diff --git a/Mine/src/api/image.ts b/Mine/src/api/image.ts index e696cf3..8ca4445 100644 --- a/Mine/src/api/image.ts +++ b/Mine/src/api/image.ts @@ -1,6 +1,6 @@ import { axiosInstance } from './axios' -export const uploadImage = async (file: File): Promise => { +export const uploadImage = async (file: File): Promise<{ imageUrl: string }> => { const formData = new FormData() formData.append('file', file) const res = await axiosInstance.post('api/images', formData) diff --git a/Mine/src/api/magazine.ts b/Mine/src/api/magazine.ts index 325764d..ad2f171 100644 --- a/Mine/src/api/magazine.ts +++ b/Mine/src/api/magazine.ts @@ -91,4 +91,9 @@ export const getMagazineFeed = async ({ cursorId, limit = 10 }: FeedDto): Promis export const createMoodboard = async (magazineId: number) => { const res = await axiosInstance.post(`api/magazines/${magazineId}/moodboards`) return res.data +} + +export const patchMagazineCover = async (id: number, coverImageUrl: string) => { + const res = await axiosInstance.patch(`api/magazines/${id}/cover`, { coverImageUrl }) + return res.data } \ No newline at end of file diff --git a/Mine/src/components/common/ConfirmModal.tsx b/Mine/src/components/common/ConfirmModal.tsx index 7684373..d043164 100644 --- a/Mine/src/components/common/ConfirmModal.tsx +++ b/Mine/src/components/common/ConfirmModal.tsx @@ -19,12 +19,15 @@ export default function ConfirmModal({ }: ConfirmModalProps) { return (
-
-
+ {/*
*/} +

{title}

{description && ( -

+

{description}

)} @@ -34,13 +37,13 @@ export default function ConfirmModal({ @@ -48,4 +51,4 @@ export default function ConfirmModal({
) -} \ No newline at end of file +} diff --git a/Mine/src/components/settings/ScreenSettings.tsx b/Mine/src/components/settings/ScreenSettings.tsx index 4f2d8c5..ba58af6 100644 --- a/Mine/src/components/settings/ScreenSettings.tsx +++ b/Mine/src/components/settings/ScreenSettings.tsx @@ -4,6 +4,7 @@ import IconWandStars from '../../icon/wand_stars.svg?react' import IconAddPhoto from '../../icon/add_photo_alternate.svg?react' import useCreateMoodboard from '../../hooks/useCreateMoodboard' import useUploadImage from '../../hooks/useUploadImage' +import usePatchMagazineCover from '../../hooks/usePatchMagazineCover' import ConfirmModal from '../common/ConfirmModal' import Toast from '../common/Toast' @@ -15,6 +16,7 @@ export default function ScreenSettings() { const fileInputRef = useRef(null) const { mutateAsync: uploadImage } = useUploadImage() const { mutateAsync: createMoodboard } = useCreateMoodboard() + const { mutateAsync: patchCover } = usePatchMagazineCover() const handleOpenFile = () => { fileInputRef.current?.click() @@ -24,7 +26,8 @@ export default function ScreenSettings() { const file = e.target.files?.[0] if (!file) return try { - await uploadImage(file) + const { imageUrl } = await uploadImage(file) + await patchCover({ id: Number(magazineId), coverImageUrl: imageUrl }) setShowToast(true) setTimeout(() => setShowToast(false), 3000) } catch (error) { @@ -52,15 +55,15 @@ export default function ScreenSettings() {
-
@@ -112,7 +102,6 @@ export default function SettingsModal({ onClose }: SettingsProps) { {activeTab === 'interest' && ( )} - {activeTab === 'screen' && }
{activeTab === 'profile' && ( @@ -168,4 +157,4 @@ export default function SettingsModal({ onClose }: SettingsProps) {
) -} +} \ No newline at end of file diff --git a/Mine/src/hooks/usePatchMagazineCover.ts b/Mine/src/hooks/usePatchMagazineCover.ts new file mode 100644 index 0000000..e9600cf --- /dev/null +++ b/Mine/src/hooks/usePatchMagazineCover.ts @@ -0,0 +1,13 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query' +import { patchMagazineCover } from '../api/magazine' + +export default function usePatchMagazineCover() { + const queryClient = useQueryClient() + return useMutation({ + mutationFn: ({ id, coverImageUrl }: { id: number; coverImageUrl: string }) => + patchMagazineCover(id, coverImageUrl), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['magazineDetail'] }) + }, + }) +} \ No newline at end of file diff --git a/Mine/src/icon/wand_stars.svg b/Mine/src/icon/wand_stars.svg index a2ca87f..0149164 100644 --- a/Mine/src/icon/wand_stars.svg +++ b/Mine/src/icon/wand_stars.svg @@ -1,8 +1,8 @@ - + - + - + \ No newline at end of file diff --git a/Mine/src/pages/magazine/components/SectionContent.tsx b/Mine/src/pages/magazine/components/SectionContent.tsx index 13077b4..dafb2a9 100644 --- a/Mine/src/pages/magazine/components/SectionContent.tsx +++ b/Mine/src/pages/magazine/components/SectionContent.tsx @@ -5,6 +5,9 @@ import SectionIndexList from './SectionIndexList' import ParagraphPart from './ParagraphPart' import useSidebarStore from '../../../stores/sidebar' import { useNavigate } from 'react-router-dom' +import { useState } from 'react' +import IconWandStars from '../../../icon/wand_stars.svg?react' +import ScreenSettingsModal from '../../../components/settings/ScreenSettingsModal' interface SectionContentProps { sectionId: number @@ -18,10 +21,12 @@ export default function SectionContent({ sectionId, magazineId }: SectionContent const { data, isLoading } = useGetSectionDetail(Number(magazineId), Number(sectionId)) const user = magazinedata?.user const content = data?.paragraphs + const [isScreenSettingsOpen, setIsScreenSettingsOpen] = useState(false) const handleClick = (magazineId: number) => { navigate(`/magazine/${magazineId}`) } + if (isLoading) { return <> } @@ -53,7 +58,16 @@ export default function SectionContent({ sectionId, magazineId }: SectionContent /> ))}
+ +
+ + setIsScreenSettingsOpen(false)} /> ) }