7.3 태그/카테고리 모델 및 UI o

This commit is contained in:
koreacomp5
2025-10-09 16:57:29 +09:00
parent a15b62f785
commit 60d7972762
5 changed files with 44 additions and 1 deletions

View File

@@ -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 } } } },
},
}),
]);

13
src/app/api/tags/route.ts Normal file
View File

@@ -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 });
}

View File

@@ -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
<div style={{ fontSize: 12, opacity: 0.8 }}>
{p.stat?.recommendCount ?? 0} · {p.stat?.views ?? 0} · {p.stat?.commentsCount ?? 0}
</div>
{!!p.postTags?.length && (
<div style={{ marginTop: 6, display: "flex", gap: 6, flexWrap: "wrap", fontSize: 12 }}>
{p.postTags?.map((pt) => (
<a key={pt.tag.slug} href={`/search?tag=${pt.tag.slug}`}>#{pt.tag.name}</a>
))}
</div>
)}
</li>
))}
</ul>

View File

@@ -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 (
<div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginBottom: 8 }}>
<a href={`${basePath}`} style={{ textDecoration: !current ? "underline" : "none" }}></a>
{tags.map((t) => (
<a key={t.slug} href={`${basePath}?tag=${t.slug}`} style={{ textDecoration: current === t.slug ? "underline" : "none" }}>
#{t.name}
</a>
))}
</div>
);
}