diff --git a/prisma/seed.js b/prisma/seed.js index a2dd809..c797b77 100644 --- a/prisma/seed.js +++ b/prisma/seed.js @@ -188,7 +188,6 @@ async function upsertBoards(admin, categoryMap) { { name: "이벤트", slug: "event", description: "이벤트", sortOrder: 4, requiredTags: { required: ["이벤트"] } }, { name: "자유게시판", slug: "free", description: "자유", sortOrder: 5 }, { name: "무엇이든", slug: "qna", description: "무엇이든 물어보세요", sortOrder: 6 }, - { name: "마사지꿀팁", slug: "tips", description: "팁", sortOrder: 7 }, { name: "익명게시판", slug: "anonymous", description: "익명", sortOrder: 8, allowAnonymousPost: true, allowSecretComment: true }, { name: "청와대", slug: "blue-house", description: "레벨 제한", sortOrder: 10, readLevel: "member" }, // 특수 diff --git a/src/app/components/BoardToolbar.tsx b/src/app/components/BoardToolbar.tsx index 85be335..b0ffc4a 100644 --- a/src/app/components/BoardToolbar.tsx +++ b/src/app/components/BoardToolbar.tsx @@ -13,7 +13,7 @@ export function BoardToolbar({ boardId }: { boardId: string }) { const onChangeSort = (e: React.ChangeEvent) => { const next = new URLSearchParams(sp.toString()); next.set("sort", e.target.value); - router.push(`/boards/${boardId}?${next.toString()}`); + router.push(`/boards/${boardId}?${next.toString()}` , { scroll: false }); }; const onChangePeriod = (e: React.ChangeEvent) => { @@ -26,7 +26,7 @@ export function BoardToolbar({ boardId }: { boardId: string }) { if (v === "1w") now.setDate(now.getDate() - 7); if (v === "1m") now.setMonth(now.getMonth() - 1); if (v === "all") next.delete("start"); else next.set("start", now.toISOString()); - router.push(`/boards/${boardId}?${next.toString()}`); + router.push(`/boards/${boardId}?${next.toString()}` , { scroll: false }); }; const onSubmit = (formData: FormData) => { @@ -41,7 +41,7 @@ export function BoardToolbar({ boardId }: { boardId: string }) { next.delete("author"); if (text) next.set("q", text); else next.delete("q"); } - router.push(`/boards/${boardId}?${next.toString()}`); + router.push(`/boards/${boardId}?${next.toString()}` , { scroll: false }); }; return ( diff --git a/src/app/components/PostList.tsx b/src/app/components/PostList.tsx index b6f8fc8..42c055f 100644 --- a/src/app/components/PostList.tsx +++ b/src/app/components/PostList.tsx @@ -1,9 +1,9 @@ "use client"; import useSWRInfinite from "swr/infinite"; import useSWR from "swr"; -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import Link from "next/link"; -import { useRouter, useSearchParams } from "next/navigation"; +import { useSearchParams } from "next/navigation"; import ViewsIcon from "@/app/svgs/ViewsIcon"; import LikeIcon from "@/app/svgs/LikeIcon"; import CommentIcon from "@/app/svgs/CommentIcon"; @@ -31,8 +31,9 @@ const fetcher = (url: string) => fetch(url).then((r) => r.json()); export function PostList({ boardId, sort = "recent", q, tag, author, start, end, variant = "default", newPostHref }: { boardId?: string; sort?: "recent" | "popular"; q?: string; tag?: string; author?: string; start?: string; end?: string; variant?: "default" | "board"; newPostHref?: string }) { const pageSize = 10; - const router = useRouter(); const sp = useSearchParams(); + const listContainerRef = useRef(null); + const [lockedMinHeight, setLockedMinHeight] = useState(null); const getKey = (index: number, prev: Resp | null) => { if (prev && prev.items.length === 0) return null; @@ -76,6 +77,21 @@ export function PostList({ boardId, sort = "recent", q, tag, author, start, end, const items = variant === "board" ? itemsSingle : itemsInfinite; const isEmpty = variant === "board" ? isEmptySingle : isEmptyInfinite; + // 잠깐 높이 고정: 페이지 변경으로 재로딩될 때 현재 높이를 min-height로 유지 + const lockHeight = () => { + const el = listContainerRef.current; + if (!el) return; + const h = el.offsetHeight; + if (h > 0) setLockedMinHeight(h); + }; + + // 로딩이 끝나면 해제 + useEffect(() => { + if (variant === "board" && !isLoadingSingle) { + setLockedMinHeight(null); + } + }, [variant, isLoadingSingle]); + const initials = (name?: string | null) => (name ? name.trim().slice(0, 1) : "익"); return ( @@ -122,10 +138,11 @@ export function PostList({ boardId, sort = "recent", q, tag, author, start, end, )} {/* 아이템들 */} -
    - {items.map((p) => ( -
  • -
    +
    +
      + {items.map((p) => ( +
    • +
      {/* bullet/공지 아이콘 자리 */}
      {p.isPinned ? "★" : "•"}
      @@ -153,9 +170,10 @@ export function PostList({ boardId, sort = "recent", q, tag, author, start, end,
      {new Date(p.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
    -
  • - ))} -
+ + ))} + + {/* 페이지네이션 */} {!isEmpty && ( @@ -165,11 +183,14 @@ export function PostList({ boardId, sort = "recent", q, tag, author, start, end, {/* Previous */}