From 60d7972762c8b03dc719ca84258f89343a5482d1 Mon Sep 17 00:00:00 2001 From: koreacomp5 Date: Thu, 9 Oct 2025 16:57:29 +0900 Subject: [PATCH] =?UTF-8?q?7.3=20=ED=83=9C=EA=B7=B8/=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20=EB=AA=A8=EB=8D=B8=20=EB=B0=8F=20UI=20o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/posts/route.ts | 1 + src/app/api/tags/route.ts | 13 +++++++++++++ src/app/components/PostList.tsx | 8 ++++++++ src/app/components/TagFilter.tsx | 21 +++++++++++++++++++++ todolist.txt | 2 +- 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/api/tags/route.ts create mode 100644 src/app/components/TagFilter.tsx diff --git a/src/app/api/posts/route.ts b/src/app/api/posts/route.ts index 7c49915..715351d 100644 --- a/src/app/api/posts/route.ts +++ b/src/app/api/posts/route.ts @@ -100,6 +100,7 @@ export async function GET(req: Request) { isPinned: true, status: true, stat: { select: { recommendCount: true, views: true, commentsCount: true } }, + postTags: { select: { tag: { select: { name: true, slug: true } } } }, }, }), ]); diff --git a/src/app/api/tags/route.ts b/src/app/api/tags/route.ts new file mode 100644 index 0000000..59b05a2 --- /dev/null +++ b/src/app/api/tags/route.ts @@ -0,0 +1,13 @@ +import { NextResponse } from "next/server"; +import prisma from "@/lib/prisma"; + +export async function GET() { + const tags = await prisma.tag.findMany({ + orderBy: { name: "asc" }, + take: 100, + select: { slug: true, name: true }, + }); + return NextResponse.json({ tags }); +} + + diff --git a/src/app/components/PostList.tsx b/src/app/components/PostList.tsx index 73281b0..ee7390b 100644 --- a/src/app/components/PostList.tsx +++ b/src/app/components/PostList.tsx @@ -8,6 +8,7 @@ type Item = { isPinned: boolean; status: string; stat?: { recommendCount: number; views: number; commentsCount: number } | null; + postTags?: { tag: { name: string; slug: string } }[]; }; type Resp = { @@ -65,6 +66,13 @@ export function PostList({ boardId, sort = "recent", q, tag, author, start, end
추천 {p.stat?.recommendCount ?? 0} · 조회 {p.stat?.views ?? 0} · 댓글 {p.stat?.commentsCount ?? 0}
+ {!!p.postTags?.length && ( +
+ {p.postTags?.map((pt) => ( + #{pt.tag.name} + ))} +
+ )} ))} diff --git a/src/app/components/TagFilter.tsx b/src/app/components/TagFilter.tsx new file mode 100644 index 0000000..eb30ee7 --- /dev/null +++ b/src/app/components/TagFilter.tsx @@ -0,0 +1,21 @@ +"use client"; +import useSWR from "swr"; + +const fetcher = (url: string) => fetch(url).then((r) => r.json()); + +export function TagFilter({ basePath, current }: { basePath: string; current?: string }) { + const { data } = useSWR<{ tags: { slug: string; name: string }[] }>("/api/tags", fetcher); + const tags = data?.tags ?? []; + return ( +
+ 전체 + {tags.map((t) => ( + + #{t.name} + + ))} +
+ ); +} + + diff --git a/todolist.txt b/todolist.txt index a09023f..a75d455 100644 --- a/todolist.txt +++ b/todolist.txt @@ -42,7 +42,7 @@ [게시판/컨텐츠] 7.1 게시글 CRUD API 및 페이지 연동 o 7.2 목록 페이징/정렬/검색(제목/태그/작성자/기간) o -7.3 태그/카테고리 모델 및 UI +7.3 태그/카테고리 모델 및 UI o 7.4 첨부 업로드 및 본문 삽입 7.5 추천/신고, 조회수 카운트 7.6 익명/비밀댓글/비댓 해시 처리