Skip to content

Commit 48bd645

Browse files
authored
Merge pull request #151 from FE9-2/refactor/albatalk
fix: ๋ฌดํ•œ ์Šคํฌ๋กค ์—๋Ÿฌ ์ˆ˜์ • ๋“ฑ
2 parents 55d4477 + 74f6292 commit 48bd645

File tree

15 files changed

+362
-225
lines changed

15 files changed

+362
-225
lines changed

โ€Žsrc/app/(pages)/albaTalk/[albatalkId]/page.tsxโ€Ž

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,10 @@ import { CommentsSection } from "./sections/CommentsSection";
77
export default function PostDetailPage() {
88
const { albatalkId } = useParams();
99

10-
// ์—๋Ÿฌ ์ฒ˜๋ฆฌ
11-
1210
return (
13-
<main className="min-h-screen bg-white py-12">
14-
<div className="mx-auto flex w-full max-w-[1480px] flex-col items-center px-4 lg:px-8">
15-
<PostDetailSection postId={albatalkId.toString()} />
16-
<CommentsSection postId={albatalkId.toString()} />
17-
</div>
18-
</main>
11+
<div className="mx-auto flex w-full min-w-[375px] flex-col items-center px-4 lg:w-[1024px] xl:w-[1480px]">
12+
<PostDetailSection postId={albatalkId.toString()} />
13+
<CommentsSection postId={albatalkId.toString()} />
14+
</div>
1915
);
2016
}

โ€Žsrc/app/(pages)/albaTalk/[albatalkId]/sections/CommentsSection.tsxโ€Ž

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import Button from "@/app/components/button/default/Button";
88
import { useAddComment } from "@/hooks/queries/post/comment/useAddComment";
99
import { useUser } from "@/hooks/queries/user/me/useUser";
1010
import { useComments } from "@/hooks/queries/post/comment/useComments";
11-
import LoadingSpinner from "@/app/components/loading-spinner/LoadingSpinner";
1211
import Pagination from "@/app/components/pagination/Pagination";
12+
import LoadingSpinner from "@/app/components/loading-spinner/LoadingSpinner";
13+
import DotLoadingSpinner from "@/app/components/loading-spinner/DotLoadingSpinner";
1314

1415
interface CommentsSectionProps {
1516
postId: string;
1617
}
1718

18-
export function CommentsSection({ postId }: CommentsSectionProps) {
19+
export function CommentsSection({ postId }: CommentsSectionProps): JSX.Element {
1920
const [currentPage, setCurrentPage] = useState(1);
2021
const [newComment, setNewComment] = useState("");
2122

@@ -42,10 +43,13 @@ export function CommentsSection({ postId }: CommentsSectionProps) {
4243
}
4344
}, [addComment, newComment]);
4445

45-
const handlePageChange = (page: number) => {
46+
const handlePageChange = useCallback((page: number) => {
4647
setCurrentPage(page);
47-
window.scrollTo({ top: 0, behavior: "smooth" });
48-
};
48+
const commentSection = document.querySelector("#comments-section");
49+
if (commentSection) {
50+
commentSection.scrollIntoView({ behavior: "smooth" });
51+
}
52+
}, []);
4953

5054
if (isCommentsLoading) {
5155
return (
@@ -60,59 +64,61 @@ export function CommentsSection({ postId }: CommentsSectionProps) {
6064
}
6165

6266
return (
63-
<section className="w-full max-w-[327px]">
64-
<h2 className="mb-4 text-[16px] font-semibold sm:text-[20px] lg:text-[24px]">
65-
๋Œ“๊ธ€({commentsData?.totalItemCount || 0})
66-
</h2>
67-
68-
<hr className="mb-4 border-t border-line-200" />
67+
<section className="w-full" aria-label="๋Œ“๊ธ€ ์„น์…˜">
68+
<div className="mb-6 ml-6 text-[16px] font-semibold text-black-400 md:text-[20px] lg:text-[24px]">
69+
๋Œ“๊ธ€({commentsData?.totalItemCount ?? 0})
70+
</div>
6971

70-
{/* ๋Œ“๊ธ€ ์ž…๋ ฅ ์˜์—ญ */}
71-
<div className="mb-8">
72+
<div className="p-4">
7273
<BaseTextArea
7374
name="newComment"
74-
variant="white"
7575
placeholder="๋Œ“๊ธ€์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
7676
value={newComment}
7777
onChange={(e) => setNewComment(e.target.value)}
78-
className="mb-4 h-[132px] w-full lg:h-[160px]"
78+
className="h-[90px] w-[344px] resize-none rounded-lg bg-background-200 p-4 md:w-[742px] lg:h-[100px] lg:w-[994px] xl:w-[1410px]"
79+
size="h-[120px] w-[375px] md:w-[768px] lg:w-[1024px] xl:w-[1440px] lg:h-[144px]"
80+
variant="white"
7981
/>
80-
<div className="flex justify-end">
81-
<Button
82-
onClick={handleAddComment}
83-
disabled={addComment.isPending || !newComment.trim()}
84-
className="h-[52px] w-[108px] text-base lg:h-[64px] lg:w-[214px] lg:text-xl"
85-
>
86-
{addComment.isPending ? "๋“ฑ๋ก ์ค‘..." : "๋“ฑ๋กํ•˜๊ธฐ"}
87-
</Button>
88-
</div>
82+
</div>
83+
<div className="flex justify-end p-4">
84+
<Button
85+
onClick={handleAddComment}
86+
disabled={addComment.isPending || !newComment.trim()}
87+
className="h-[64px] w-[140px] rounded-lg text-[14px] font-medium"
88+
>
89+
{addComment.isPending ? <DotLoadingSpinner /> : "๋“ฑ๋กํ•˜๊ธฐ"}
90+
</Button>
8991
</div>
9092

91-
{/* ๋Œ“๊ธ€ ๋ชฉ๋ก */}
92-
{commentsData?.data && commentsData.data.length > 0 ? (
93-
<div className="space-y-4">
94-
{commentsData.data.map((comment) => (
95-
<div key={comment.id}>
96-
<Comment
97-
id={comment.id.toString()}
98-
nickname={comment.writer.nickname}
99-
updatedAt={comment.createdAt}
100-
content={comment.content}
101-
isAuthor={comment.writer.id === user?.id}
102-
/>
103-
</div>
104-
))}
105-
</div>
106-
) : (
107-
<div className="mt-8 flex justify-center">
108-
<Image src="/images/emptyComment-md.svg" alt="No comments" width={206} height={204} />
109-
</div>
110-
)}
93+
<div className="mt-4">
94+
{commentsData?.data?.length ? (
95+
<>
96+
{commentsData.data.map((comment) => (
97+
<div key={comment.id} className="rounded-lg bg-white p-2">
98+
<Comment
99+
id={comment.id.toString()}
100+
nickname={comment.writer.nickname}
101+
updatedAt={comment.createdAt}
102+
content={comment.content}
103+
isAuthor={comment.writer.id === user?.id}
104+
/>
105+
</div>
106+
))}
107+
</>
108+
) : (
109+
<div className="flex min-h-[300px] flex-col items-center justify-center gap-4 rounded-lg bg-white p-5">
110+
<Image src="/images/emptyComment-md.svg" alt="No comments" width={206} height={204} className="mb-4" />
111+
</div>
112+
)}
113+
</div>
111114

112-
{/* ํŽ˜์ด์ง€๋„ค์ด์…˜ */}
113-
{commentsData?.totalPages && commentsData.totalPages > 0 && (
114-
<div className="mt-8">
115-
<Pagination currentPage={currentPage} totalPage={commentsData.totalPages} onPageChange={handlePageChange} />
115+
{(commentsData?.totalPages ?? 0) > 1 && (
116+
<div className="mt-12 flex justify-center">
117+
<Pagination
118+
currentPage={currentPage}
119+
totalPage={commentsData?.totalPages ?? 0}
120+
onPageChange={handlePageChange}
121+
/>
116122
</div>
117123
)}
118124
</section>

โ€Žsrc/app/(pages)/albaTalk/[albatalkId]/sections/PostDetailSection.tsxโ€Ž

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import KebabDropdown from "@/app/components/button/dropdown/KebabDropdown";
99
import useModalStore from "@/store/modalStore";
1010
import useWidth from "@/hooks/useWidth";
1111
import { usePostDetail } from "@/hooks/queries/post/usePostDetail";
12+
import { useRouter } from "next/navigation";
1213

1314
export function PostDetailSection({ postId }: { postId: string }) {
1415
const { isDesktop } = useWidth();
1516
const { user } = useUser();
17+
const router = useRouter();
1618
const { data: post } = usePostDetail(postId);
1719
const { likePost, unlikePost } = useLikePost(postId);
1820
const deletePost = useDeletePost(postId);
@@ -46,62 +48,82 @@ export function PostDetailSection({ postId }: { postId: string }) {
4648
},
4749
});
4850
},
49-
onCancel: () => {
50-
openModal("customForm", { isOpen: false, title: "", content: "", onConfirm: () => {}, onCancel: () => {} });
51-
},
51+
onCancel: () =>
52+
openModal("customForm", {
53+
isOpen: false,
54+
title: "",
55+
content: "",
56+
onConfirm: () => {},
57+
onCancel: () => {},
58+
}),
5259
});
5360
};
5461

55-
const dropdownOptions = [{ label: "์‚ญ์ œํ•˜๊ธฐ", onClick: handleDelete, disabled: deletePost.isPending }];
62+
const handleEdit = () => {
63+
router.push(`/albatalk/edit/${postId}`);
64+
};
65+
66+
const dropdownOptions = [
67+
{ label: "์ˆ˜์ •ํ•˜๊ธฐ", onClick: handleEdit },
68+
{ label: "์‚ญ์ œํ•˜๊ธฐ", onClick: handleDelete, disabled: deletePost.isPending },
69+
];
5670

5771
return (
58-
<article className="mb-12 w-full max-w-[327px] rounded-lg border border-line-200 bg-white p-4">
72+
<section className="mb-12 w-full rounded-lg bg-white p-4 md:p-6 lg:p-8">
5973
{/* Header */}
6074
<div className="mb-4 flex items-center justify-between">
61-
<h1 className="text-[16px] font-semibold lg:text-[24px]">{post?.title}</h1>
75+
<h1 className="text-[16px] font-semibold md:text-[20px] lg:text-[24px]">{post?.title}</h1>
6276
{post?.writer.id === user?.id && <KebabDropdown options={dropdownOptions} />}
6377
</div>
6478

79+
{/* Divider Line */}
80+
<div className="my-[9px] flex items-center justify-center lg:my-[16px]">
81+
<div className="w-full bg-line-100" style={{ height: "1px" }}></div>
82+
</div>
83+
6584
{/* Author Info */}
6685
<div className="mb-4 flex items-center gap-2">
67-
<Image
68-
src="/icons/user/user-profile-sm.svg"
69-
alt="User Icon"
70-
className="rounded-full"
71-
width={24}
72-
height={24}
73-
sizes="(max-width: 600px) 24px, (max-width: 1480px) 28px, 30px"
74-
/>
75-
<div className="flex items-center gap-1">
76-
<span className="font-nexon text-[14px] font-medium text-black-400 md:text-[16px] lg:text-[18px]">
77-
{post?.writer.nickname}
78-
</span>
86+
<Image src="/icons/user/user-profile-sm.svg" alt="User Icon" className="rounded-full" width={32} height={32} />
87+
<div className="flex items-center gap-2">
88+
<span className="font-medium text-black-400">{post?.writer.nickname}</span>
7989
<span className="text-grayscale-400">|</span>
80-
<span className="font-nexon text-[12px] text-grayscale-400 md:text-[14px] lg:text-[16px]">
81-
{formatLocalDate(post?.createdAt || new Date())}
82-
</span>
90+
<span className="text-sm text-grayscale-400">{formatLocalDate(post?.createdAt || new Date())}</span>
8391
</div>
8492
</div>
8593

8694
{/* Content */}
87-
<div className="mb-4 min-h-[200px] whitespace-pre-wrap break-words font-nexon text-[14px] leading-[1.6] text-black-400 md:text-[16px] lg:text-[18px]">
95+
<div className="mb-6 whitespace-pre-wrap text-sm leading-[1.6] text-black-400 md:text-base lg:text-lg">
8896
{post?.content}
8997
</div>
9098

99+
{/* Image */}
100+
<div className="mb-6">
101+
{post?.imageUrl ? (
102+
<div className="relative aspect-square w-full max-w-[600px] overflow-hidden rounded-lg">
103+
<Image
104+
src={post.imageUrl}
105+
alt="Post Image"
106+
fill
107+
sizes="(max-width: 768px) 100vw, 600px"
108+
className="object-contain"
109+
priority
110+
/>
111+
</div>
112+
) : null}
113+
</div>
114+
91115
{/* Footer */}
92-
<div className="flex items-center justify-end gap-2">
116+
<div className="flex items-center gap-4">
93117
<div className="flex items-center gap-1">
94118
<Image
95119
src={`/icons/comment/${isDesktop ? "comment-md.svg" : "comment-sm.svg"}`}
96120
alt="Comment Icon"
97-
width={22}
98-
height={22}
121+
width={24}
122+
height={24}
99123
/>
100-
<span className="font-nexon text-[14px] font-normal text-grayscale-500 lg:text-[16px]">
101-
{post?.commentCount}
102-
</span>
124+
<span className="text-sm text-grayscale-500">{post?.commentCount}</span>
103125
</div>
104-
<div className="flex items-center gap-1">
126+
<div className="flex cursor-pointer items-center gap-1" onClick={handleLikeClick}>
105127
<Image
106128
src={`/icons/like/${
107129
post?.isLiked
@@ -113,16 +135,12 @@ export function PostDetailSection({ postId }: { postId: string }) {
113135
: "like-sm.svg"
114136
}`}
115137
alt="Like Icon"
116-
width={22}
117-
height={22}
118-
className="cursor-pointer"
119-
onClick={handleLikeClick}
138+
width={24}
139+
height={24}
120140
/>
121-
<span className="font-nexon text-[14px] font-normal text-grayscale-500 lg:text-[16px]">
122-
{post?.likeCount}
123-
</span>
141+
<span className="text-sm text-grayscale-500">{post?.likeCount}</span>
124142
</div>
125143
</div>
126-
</article>
144+
</section>
127145
);
128146
}

โ€Žsrc/app/(pages)/albaTalk/edit/[id]/page.tsxโ€Ž

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,15 @@ export default function EditTalk({ params }: { params: { id: string } }) {
5252
});
5353

5454
if (post.imageUrl) {
55-
const initialImages = post.imageUrl.split(",").map((url, index) => ({
56-
file: null,
57-
url,
58-
id: `initial-${index}`,
59-
}));
60-
setImageList(initialImages);
55+
setImageList([
56+
{
57+
file: null,
58+
url: post.imageUrl,
59+
id: "initial-image",
60+
},
61+
]);
62+
} else {
63+
setImageList([]);
6164
}
6265
}
6366
}, [post, reset]);
@@ -151,14 +154,16 @@ export default function EditTalk({ params }: { params: { id: string } }) {
151154
<div className="hidden space-x-1 font-semibold md:flex md:space-x-2 lg:space-x-4">
152155
<Button
153156
variant="solid"
154-
className="bg-grayscale-100 text-grayscale-50 hover:bg-grayscale-200 md:h-[46px] md:w-[108px] md:text-[14px] lg:h-[58px] lg:w-[180px] lg:text-[18px]"
157+
color="gray"
158+
className="md:h-[46px] md:w-[108px] md:text-[14px] lg:h-[58px] lg:w-[180px] lg:text-[18px]"
155159
onClick={() => router.push(`/albatalk/${postId}`)}
156160
>
157161
์ทจ์†Œ
158162
</Button>
159163
<Button
160164
variant="solid"
161-
className="bg-primary-orange-300 text-grayscale-50 hover:bg-orange-400 md:h-[46px] md:w-[108px] md:text-[14px] lg:h-[58px] lg:w-[180px] lg:text-[18px]"
165+
color="orange"
166+
className="md:h-[46px] md:w-[108px] md:text-[14px] lg:h-[58px] lg:w-[180px] lg:text-[18px]"
162167
onClick={handleSubmit(onSubmit)}
163168
disabled={isPending}
164169
>
@@ -220,27 +225,35 @@ export default function EditTalk({ params }: { params: { id: string } }) {
220225
>
221226
์ด๋ฏธ์ง€
222227
</label>
223-
<ImageInputPlaceHolder onImageUpload={uploadImage} onImagesChange={handleImagesChange} />
228+
<ImageInputPlaceHolder
229+
onImageUpload={uploadImage}
230+
onImagesChange={handleImagesChange}
231+
initialImages={imageList}
232+
/>
224233
</div>
225234
</form>
226235
</div>
227236
</div>
228237

229238
{/* ๋ชจ๋ฐ”์ผ ๋ฒ„์ „ ๋ฒ„ํŠผ */}
230239
<div className="fixed bottom-4 left-4 right-4 flex w-full flex-col items-center space-y-2 rounded-t-lg bg-white p-4 font-semibold md:hidden">
231-
<button
232-
className="mb-2 h-[58px] w-[327px] rounded-[8px] bg-grayscale-100 text-white hover:bg-grayscale-200"
240+
<Button
241+
variant="solid"
242+
color="gray"
243+
className="h-[58px] w-[327px] rounded-[8px]"
233244
onClick={() => router.push(`/albatalk/${postId}`)}
234245
>
235246
์ทจ์†Œ
236-
</button>
237-
<button
238-
className="h-[58px] w-[327px] rounded-[8px] bg-primary-orange-300 text-white hover:bg-orange-400"
247+
</Button>
248+
<Button
249+
variant="solid"
250+
color="orange"
251+
className="h-[58px] w-[327px] rounded-[8px]"
239252
onClick={handleSubmit(onSubmit)}
240253
disabled={isPending}
241254
>
242255
{isPending ? <DotLoadingSpinner /> : "์ˆ˜์ •ํ•˜๊ธฐ"}
243-
</button>
256+
</Button>
244257
</div>
245258
</>
246259
);

0 commit comments

Comments
ย (0)