diff --git a/apps/web/src/app/community/[boardCode]/PostCards.tsx b/apps/web/src/app/community/[boardCode]/PostCards.tsx index 5b2155ff..118e15ef 100644 --- a/apps/web/src/app/community/[boardCode]/PostCards.tsx +++ b/apps/web/src/app/community/[boardCode]/PostCards.tsx @@ -94,21 +94,23 @@ export const PostCard = ({ post }: { post: ListPost }) => ( -
- {post.postThumbnailUrl ? ( - 게시글 사진 - ) : ( -
- -
- )} +
+
+ {post.postThumbnailUrl ? ( + 게시글 사진 + ) : ( +
+ +
+ )} +
); diff --git a/apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsx b/apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsx index d9897b7e..81299f47 100644 --- a/apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsx +++ b/apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsx @@ -1,7 +1,7 @@ "use client"; import { useRouter } from "next/navigation"; -import { useEffect, useRef, useState } from "react"; +import { type ChangeEvent, useEffect, useRef, useState } from "react"; import { useUpdatePost } from "@/apis/community"; import { toast } from "@/lib/zustand/useToastStore"; @@ -30,6 +30,8 @@ const PostModifyForm = ({ const textareaRef = useRef(null); const titleRef = useRef(null); const imageUploadRef = useRef(null); + const [selectedImage, setSelectedImage] = useState(null); + const [imagePreviewUrl, setImagePreviewUrl] = useState(null); const router = useRouter(); const updatePostMutation = useUpdatePost(); @@ -61,6 +63,32 @@ const PostModifyForm = ({ return () => {}; }, []); + useEffect(() => { + if (!selectedImage) { + setImagePreviewUrl(null); + return; + } + + const objectUrl = URL.createObjectURL(selectedImage); + setImagePreviewUrl(objectUrl); + + return () => { + URL.revokeObjectURL(objectUrl); + }; + }, [selectedImage]); + + const handleImageChange = (event: ChangeEvent) => { + const file = event.target.files?.[0] ?? null; + setSelectedImage(file); + }; + + const removeSelectedImage = () => { + setSelectedImage(null); + if (imageUploadRef.current) { + imageUploadRef.current.value = ""; + } + }; + const submitPost = async () => { if (!title.trim()) { toast.error("제목을 입력해주세요."); @@ -82,7 +110,7 @@ const PostModifyForm = ({ title, content, }, - file: imageUploadRef.current?.files ? Array.from(imageUploadRef.current.files) : [], + file: selectedImage ? [selectedImage] : [], }, }, { @@ -137,7 +165,7 @@ const PostModifyForm = ({ > - +
@@ -148,6 +176,22 @@ const PostModifyForm = ({ onChange={(e) => setContent(e.target.value)} />
+ {imagePreviewUrl ? ( +
+

첨부 이미지

+
+ 업로드 이미지 미리보기 + +
+
+ ) : null}

{noticeTitle}

{noticeContent}

diff --git a/apps/web/src/app/community/[boardCode]/create/PostForm.tsx b/apps/web/src/app/community/[boardCode]/create/PostForm.tsx index 1e45a8a2..7995a564 100644 --- a/apps/web/src/app/community/[boardCode]/create/PostForm.tsx +++ b/apps/web/src/app/community/[boardCode]/create/PostForm.tsx @@ -1,7 +1,7 @@ "use client"; import { useRouter } from "next/navigation"; -import { useEffect, useRef, useState } from "react"; +import { type ChangeEvent, useEffect, useRef, useState } from "react"; import { useCreatePost } from "@/apis/community"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; import { IconImage, IconPostCheckboxFilled, IconPostCheckboxOutlined } from "@/public/svgs"; @@ -17,6 +17,8 @@ const PostForm = ({ boardCode }: PostFormProps) => { const imageUploadRef = useRef(null); const router = useRouter(); const [isQuestion, setIsQuestion] = useState(false); + const [selectedImage, setSelectedImage] = useState(null); + const [imagePreviewUrl, setImagePreviewUrl] = useState(null); const createPostMutation = useCreatePost(); @@ -43,6 +45,32 @@ const PostForm = ({ boardCode }: PostFormProps) => { return () => {}; }, []); + useEffect(() => { + if (!selectedImage) { + setImagePreviewUrl(null); + return; + } + + const objectUrl = URL.createObjectURL(selectedImage); + setImagePreviewUrl(objectUrl); + + return () => { + URL.revokeObjectURL(objectUrl); + }; + }, [selectedImage]); + + const handleImageChange = (event: ChangeEvent) => { + const file = event.target.files?.[0] ?? null; + setSelectedImage(file); + }; + + const removeSelectedImage = () => { + setSelectedImage(null); + if (imageUploadRef.current) { + imageUploadRef.current.value = ""; + } + }; + const submitPost = async () => { createPostMutation.mutate( { @@ -53,7 +81,7 @@ const PostForm = ({ boardCode }: PostFormProps) => { content, isQuestion, }, - file: imageUploadRef.current?.files ? Array.from(imageUploadRef.current.files) : [], + file: selectedImage ? [selectedImage] : [], }, { onSuccess: (data) => { @@ -116,7 +144,7 @@ const PostForm = ({ boardCode }: PostFormProps) => { > - +
@@ -127,6 +155,22 @@ const PostForm = ({ boardCode }: PostFormProps) => { onChange={(e) => setContent(e.target.value)} />
+ {imagePreviewUrl ? ( +
+

첨부 이미지

+
+ 업로드 이미지 미리보기 + +
+
+ ) : null}

{noticeTitle}

{noticeContent}