This commit is contained in:
@@ -343,7 +343,7 @@ export function AppHeader() {
|
||||
return (
|
||||
<header
|
||||
ref={headerRef}
|
||||
className={`relative flex items-center justify-between px-4 py-3 bg-white/80 backdrop-blur supports-[backdrop-filter]:bg-white/60 ${
|
||||
className={`relative flex items-center justify-between px-4 py-3 bg-white/90 backdrop-blur supports-[backdrop-filter]:bg-white/60 ${
|
||||
megaOpen ? "shadow-[0_6px_24px_rgba(0,0,0,0.10)]" : ""
|
||||
}`}
|
||||
>
|
||||
@@ -423,7 +423,7 @@ export function AppHeader() {
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`fixed left-0 right-0 z-50 bg-white/80 backdrop-blur supports-[backdrop-filter]:bg-white/60 shadow-[0_12px_32px_rgba(0,0,0,0.12)] transition-all duration-200 ${
|
||||
className={`fixed left-0 right-0 z-50 bg-white/90 backdrop-blur supports-[backdrop-filter]:bg-white/60 shadow-[0_12px_32px_rgba(0,0,0,0.12)] transition-all duration-200 ${
|
||||
megaOpen ? "opacity-100" : "pointer-events-none opacity-0"
|
||||
}`}
|
||||
style={{ top: headerBottom }}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import React from "react";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
|
||||
export function BoardToolbar({ boardId }: { boardId: string }) {
|
||||
const router = useRouter();
|
||||
const sp = useSearchParams();
|
||||
const sort = (sp.get("sort") as "recent" | "popular" | null) ?? "recent";
|
||||
const sort = (sp.get("sort") as "recent" | "popular" | "views" | "likes" | "comments" | null) ?? "recent";
|
||||
const scope = (sp.get("scope") as "q" | "author" | null) ?? "q"; // q: 제목+내용, author: 작성자
|
||||
const defaultText = scope === "author" ? sp.get("author") ?? "" : sp.get("q") ?? "";
|
||||
const period = sp.get("period") ?? "all"; // all | 1d | 1w | 1m
|
||||
@@ -16,6 +16,109 @@ export function BoardToolbar({ boardId }: { boardId: string }) {
|
||||
router.push(`/boards/${boardId}?${next.toString()}` , { scroll: false });
|
||||
};
|
||||
|
||||
const pushSort = (value: string) => {
|
||||
const next = new URLSearchParams(sp.toString());
|
||||
next.set("sort", value);
|
||||
router.push(`/boards/${boardId}?${next.toString()}`, { scroll: false });
|
||||
};
|
||||
|
||||
const SortDropdown = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useEffect(() => {
|
||||
const handler = (ev: MouseEvent) => { if (ref.current && !ref.current.contains(ev.target as Node)) setOpen(false); };
|
||||
window.addEventListener("click", handler);
|
||||
return () => window.removeEventListener("click", handler);
|
||||
}, []);
|
||||
const label =
|
||||
sort === "recent" ? "최신순" : sort === "views" ? "조회순" : sort === "likes" ? "좋아요순" : sort === "comments" ? "댓글순" : "인기순";
|
||||
const items: { value: string; text: string }[] = [
|
||||
{ value: "recent", text: "최신순" },
|
||||
{ value: "views", text: "조회순" },
|
||||
{ value: "likes", text: "좋아요순" },
|
||||
{ value: "comments", text: "댓글순" },
|
||||
];
|
||||
return (
|
||||
<div ref={ref} className="relative">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className="inline-flex h-12 px-4 items-center justify-center gap-1 rounded-[16px] border border-[#d5d5d5] bg-white text-[14px] text-[#161616] min-w-[93px] cursor-pointer hover:bg-neutral-100"
|
||||
>
|
||||
<span>{label}</span>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden>
|
||||
<path d="M5 8l5 5 5-5" stroke="#707070" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
{open && (
|
||||
<div className="absolute mt-2 left-0 z-20 bg-white rounded-[16px] p-2 shadow-[0_0_2px_rgba(0,0,0,0.05),0_4px_8px_rgba(0,0,0,0.08)] w-[93px]">
|
||||
<div className="flex flex-col gap-1">
|
||||
{items.map((it) => (
|
||||
<button
|
||||
key={it.value}
|
||||
type="button"
|
||||
onClick={() => { setOpen(false); pushSort(it.value); }}
|
||||
className={`w-full px-3 py-2 rounded-[8px] text-[14px] inline-flex items-center justify-center cursor-pointer ${
|
||||
sort === it.value ? "bg-[#707070] text-white" : "text-[#707070] hover:bg-neutral-100"
|
||||
}`}
|
||||
>
|
||||
{it.text}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ScopeDropdown = ({ value, onSelect }: { value: "q" | "author"; onSelect: (v: "q" | "author") => void }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useEffect(() => {
|
||||
const handler = (ev: MouseEvent) => { if (ref.current && !ref.current.contains(ev.target as Node)) setOpen(false); };
|
||||
window.addEventListener("click", handler);
|
||||
return () => window.removeEventListener("click", handler);
|
||||
}, []);
|
||||
const label = value === "author" ? "작성자" : "제목+내용";
|
||||
const items: { value: "q" | "author"; text: string }[] = [
|
||||
{ value: "q", text: "제목+내용" },
|
||||
{ value: "author", text: "작성자" },
|
||||
];
|
||||
return (
|
||||
<div ref={ref} className="relative">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className="inline-flex h-12 px-4 items-center justify-center gap-1 rounded-[16px] border border-[#d5d5d5] bg-white text-[14px] text-[#161616] min-w-[93px] cursor-pointer hover:bg-neutral-100"
|
||||
>
|
||||
<span>{label}</span>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden>
|
||||
<path d="M5 8l5 5 5-5" stroke="#707070" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
{open && (
|
||||
<div className="absolute mt-2 left-0 z-20 bg-white rounded-[16px] p-2 shadow-[0_0_2px_rgba(0,0,0,0.05),0_4px_8px_rgba(0,0,0,0.08)] w-[120px]">
|
||||
<div className="flex flex-col gap-1">
|
||||
{items.map((it) => (
|
||||
<button
|
||||
key={it.value}
|
||||
type="button"
|
||||
onClick={() => { onSelect(it.value); setOpen(false); }}
|
||||
className={`w-full px-3 py-2 rounded-[8px] text-[14px] inline-flex items-center justify-center cursor-pointer ${
|
||||
value === it.value ? "bg-[#707070] text-white" : "text-[#707070] hover:bg-neutral-100"
|
||||
}`}
|
||||
>
|
||||
{it.text}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const onChangePeriod = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const next = new URLSearchParams(sp.toString());
|
||||
const v = e.target.value;
|
||||
@@ -48,22 +151,67 @@ export function BoardToolbar({ boardId }: { boardId: string }) {
|
||||
<div className="px-0 py-2 flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
|
||||
{/* 검색바: 모바일에서는 상단 전체폭 */}
|
||||
<form action={onSubmit} className="order-1 md:order-2 flex items-center gap-2 w-full md:w-auto">
|
||||
<select name="scope" aria-label="검색대상" className="h-8 px-2 rounded-md border border-neutral-300 bg-white text-sm shrink-0" defaultValue={scope}>
|
||||
<option value="q">제목+내용</option>
|
||||
<option value="author">작성자</option>
|
||||
</select>
|
||||
<input name="text" defaultValue={defaultText} placeholder="검색어를 입력해 주세요." className="h-8 w-full md:w-72 px-3 rounded-md border border-neutral-300 text-sm placeholder:text-neutral-400 focus:outline-none focus:ring-2 focus:ring-neutral-300" />
|
||||
<button type="submit" className="h-8 px-3 rounded-md bg-neutral-900 text-white text-sm hover:bg-neutral-800 shrink-0">검색</button>
|
||||
<input type="hidden" name="scope" value={scope} />
|
||||
<ScopeDropdown
|
||||
value={scope}
|
||||
onSelect={(v) => {
|
||||
// hidden input을 업데이트하기 위해 URL 파라미터는 변경하지 않고 폼 값만 유지
|
||||
// 검색 제출 시 onSubmit에서 반영됨
|
||||
const form = (document.activeElement as HTMLElement)?.closest("form") as HTMLFormElement | null;
|
||||
if (form) {
|
||||
const input = form.querySelector('input[name="scope"]') as HTMLInputElement | null;
|
||||
if (input) input.value = v;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div className="relative w-full md:w-96 group">
|
||||
<button
|
||||
type="submit"
|
||||
aria-label="검색 실행"
|
||||
className="absolute right-2 top-2 w-8 h-8 text-neutral-500 cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden
|
||||
className="w-8 h-8 block group-hover:hidden group-focus-within:hidden"
|
||||
>
|
||||
<path
|
||||
d="M21 21L17.682 17.682M17.682 17.682C18.4963 16.8676 19 15.7426 19 14.5C19 12.0147 16.9853 10 14.5 10C12.0147 10 10 12.0147 10 14.5C10 16.9853 12.0147 19 14.5 19C15.7426 19 16.8676 18.4963 17.682 17.682ZM28 16C28 22.6274 22.6274 28 16 28C9.37258 28 4 22.6274 4 16C4 9.37258 9.37258 4 16 4C22.6274 4 28 9.37258 28 16Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden
|
||||
className="w-8 h-8 hidden group-hover:block group-focus-within:block"
|
||||
>
|
||||
<path d="M11 14.5C11 12.567 12.567 11 14.5 11C16.433 11 18 12.567 18 14.5C18 15.4668 17.6093 16.3404 16.9749 16.9749C16.3404 17.6093 15.4668 18 14.5 18C12.567 18 11 16.433 11 14.5Z" fill="#707070" />
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M16 3C8.8203 3 3 8.8203 3 16C3 23.1797 8.8203 29 16 29C23.1797 29 29 23.1797 29 16C29 8.8203 23.1797 3 16 3ZM14.5 9C11.4624 9 9 11.4624 9 14.5C9 17.5376 11.4624 20 14.5 20C15.6571 20 16.7316 19.6419 17.6174 19.0316L20.2929 21.7071C20.6834 22.0976 21.3166 22.0976 21.7071 21.7071C22.0976 21.3166 22.0976 20.6834 21.7071 20.2929L19.0316 17.6174C19.6419 16.7316 20 15.6571 20 14.5C20 11.4624 17.5376 9 14.5 9Z" fill="#707070" />
|
||||
</svg>
|
||||
</button>
|
||||
<input
|
||||
name="text"
|
||||
defaultValue={defaultText}
|
||||
placeholder="검색어를 입력해 주세요."
|
||||
className="w-full h-12 pr-12 pl-2 rounded-2xl border bg-white border-neutral-300 hover:border-[2px] hover:border-neutral-500 focus:border-2 focus:border-neutral-800 focus:outline-none transition-colors"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* 필터: 모바일에서는 검색 아래쪽 */}
|
||||
<div className="order-2 md:order-1 flex items-center gap-2">
|
||||
<select aria-label="정렬" className="h-8 px-2 rounded-md border border-neutral-300 bg-white text-sm" defaultValue={sort} onChange={onChangeSort}>
|
||||
<option value="recent">최신순</option>
|
||||
<option value="views">조회순</option>
|
||||
<option value="likes">좋아요순</option>
|
||||
<option value="comments">댓글순</option>
|
||||
</select>
|
||||
<SortDropdown />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useSearchParams } from "next/navigation";
|
||||
import ViewsIcon from "@/app/svgs/ViewsIcon";
|
||||
import LikeIcon from "@/app/svgs/LikeIcon";
|
||||
import CommentIcon from "@/app/svgs/CommentIcon";
|
||||
import PlusIcon from "@/app/svgs/PlusIcon";
|
||||
|
||||
type Item = {
|
||||
id: string;
|
||||
@@ -123,6 +124,60 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
|
||||
const initials = (name?: string | null) => (name ? name.trim().slice(0, 1) : "익");
|
||||
|
||||
// 표시 개수 드롭다운 (BoardToolbar 드롭다운과 동일한 디자인/호버)
|
||||
const PageSizeDropdown = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
useEffect(() => {
|
||||
const handler = (ev: MouseEvent) => { if (ref.current && !ref.current.contains(ev.target as Node)) setOpen(false); };
|
||||
window.addEventListener("click", handler);
|
||||
return () => window.removeEventListener("click", handler);
|
||||
}, []);
|
||||
const sizes = [10, 20, 30, 40, 50];
|
||||
const onSelectSize = (newSize: number) => {
|
||||
setCurrentPageSize(newSize);
|
||||
setPage(1);
|
||||
const nextSp = new URLSearchParams(Array.from(sp.entries()));
|
||||
nextSp.set("pageSize", String(newSize));
|
||||
nextSp.set("page", "1");
|
||||
if (typeof window !== "undefined") {
|
||||
window.history.replaceState(null, "", `?${nextSp.toString()}`);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div ref={ref} className="relative">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className="inline-flex h-12 px-4 items-center justify-center gap-1 rounded-[16px] border border-[#d5d5d5] bg-white text-[14px] text-[#161616] min-w-[93px] cursor-pointer hover:bg-neutral-100"
|
||||
>
|
||||
<span>{currentPageSize}개</span>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden>
|
||||
<path d="M5 8l5 5 5-5" stroke="#707070" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
{open && (
|
||||
<div className="absolute mt-2 left-0 z-20 bg-white rounded-[16px] p-2 shadow-[0_0_2px_rgba(0,0,0,0.05),0_4px_8px_rgba(0,0,0,0.08)] w-[120px]">
|
||||
<div className="flex flex-col gap-1">
|
||||
{sizes.map((sz) => (
|
||||
<button
|
||||
key={sz}
|
||||
type="button"
|
||||
onClick={() => { setOpen(false); onSelectSize(sz); }}
|
||||
className={`w-full px-3 py-2 rounded-[8px] text-[14px] inline-flex items-center justify-center cursor-pointer ${
|
||||
currentPageSize === sz ? "bg-[#707070] text-white" : "text-[#707070] hover:bg-neutral-100"
|
||||
}`}
|
||||
>
|
||||
{sz}개
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
{/* 정렬 스위치 (board 변형에서는 상단 툴바를 숨김) */}
|
||||
@@ -170,15 +225,30 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
<div ref={listContainerRef} style={{ minHeight: lockedMinHeight ? `${lockedMinHeight}px` : undefined }}>
|
||||
<ul className="divide-y divide-[#ececec]">
|
||||
{items.map((p) => (
|
||||
<li key={p.id} className={`px-4 ${variant === "board" ? (compact ? "py-1.5" : "py-2.5") : "py-3 md:py-3"} hover:bg-neutral-50 transition-colors`}>
|
||||
<li key={p.id} className={`px-4 ${variant === "board" ? "" : "py-3 md:py-3"} hover:bg-neutral-50 transition-colors`}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-[20px_1fr_120px_120px_80px] items-center gap-2">
|
||||
{/* bullet/공지 아이콘 자리 */}
|
||||
<div className="hidden md:flex items-center justify-center text-[#f94b37]">{p.isPinned ? "★" : "•"}</div>
|
||||
|
||||
<div className="min-w-0">
|
||||
<Link href={`/posts/${p.id}`} className={`group block truncate text-neutral-900`}>
|
||||
<Link href={`/posts/${p.id}`} className={`group block truncate text-neutral-900 ${variant === "board" ? "py-[36px]" : ""}`}>
|
||||
{p.isPinned && <span className="mr-2 inline-flex items-center rounded bg-orange-100 text-orange-700 px-1.5 py-0.5 text-[11px]">공지</span>}
|
||||
<span className={`${titleHoverOrange ? "group-hover:text-[var(--red-50,#F94B37)] group-hover:font-[700] group-hover:text-[16px] group-hover:leading-[22px]" : ""} ${compact ? "text-[14px] leading-[20px]" : "text-[15px] md:text-base"}`} style={{ fontFamily: "var(--font-family-Font-1, Pretendard)" }}>
|
||||
<span
|
||||
className={`${
|
||||
variant === "board" && titleHoverOrange
|
||||
? "text-[24px] leading-[24px] font-[400] text-[#161616]"
|
||||
: compact
|
||||
? "text-[14px] leading-[20px]"
|
||||
: "text-[15px] md:text-base"
|
||||
} ${
|
||||
titleHoverOrange
|
||||
? variant === "board"
|
||||
? "group-hover:text-[var(--red-50,#F94B37)] group-hover:font-[700] group-hover:text-[24px] group-hover:leading-[24px]"
|
||||
: "group-hover:text-[var(--red-50,#F94B37)] group-hover:font-[700]"
|
||||
: ""
|
||||
}`}
|
||||
style={{ fontFamily: "var(--font-family-Font-1, Pretendard)" }}
|
||||
>
|
||||
{stripHtml(p.title)}
|
||||
</span>
|
||||
{(p.stat?.commentsCount ?? 0) > 0 && (
|
||||
@@ -214,7 +284,7 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
variant === "board" ? (
|
||||
<div className="mt-4 px-4 space-y-3">
|
||||
{/* 상단: 페이지 이동 컨트롤 */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-1">
|
||||
{/* Previous */}
|
||||
<button
|
||||
onClick={() => {
|
||||
@@ -228,7 +298,7 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
}
|
||||
}}
|
||||
disabled={page <= 1}
|
||||
className="h-9 px-3 rounded-md border border-neutral-300 bg-white text-sm disabled:opacity-50"
|
||||
className="inline-flex items-center justify-center gap-1 h-[36px] px-[12px] py-[8px] rounded-[6px] border border-transparent bg-transparent text-[14px] text-[#161616] disabled:opacity-50 cursor-pointer hover:bg-neutral-100"
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
@@ -261,12 +331,12 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
}
|
||||
}}
|
||||
aria-current={n === page ? "page" : undefined}
|
||||
className={`h-9 w-9 rounded-md border ${n === page ? "border-neutral-300 text-[#f94b37] font-semibold" : "border-neutral-300 text-neutral-900"}`}
|
||||
className={`inline-flex items-center justify-center h-[36px] w-[36px] rounded-[6px] text-[14px] cursor-pointer ${n === page ? "border border-[#d5d5d5] bg-white text-[#f94b37] font-semibold hover:bg-neutral-100" : "border border-transparent bg-transparent text-[#161616] hover:bg-neutral-100"}`}
|
||||
>
|
||||
{n}
|
||||
</button>
|
||||
) : (
|
||||
<span key={`e-${idx}`} className="h-9 w-9 inline-flex items-center justify-center text-neutral-900">…</span>
|
||||
<span key={`e-${idx}`} className="inline-flex items-center justify-center h-[36px] w-[36px] text-[#161616]">…</span>
|
||||
)
|
||||
);
|
||||
})()}
|
||||
@@ -284,7 +354,7 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
}
|
||||
}}
|
||||
disabled={page >= totalPages}
|
||||
className="h-9 px-3 rounded-md border border-neutral-300 bg-white text-sm disabled:opacity-50"
|
||||
className="inline-flex items-center justify-center gap-1 h-[36px] px-[12px] py-[8px] rounded-[6px] border border-transparent bg-transparent text-[14px] text-[#161616] disabled:opacity-50 cursor-pointer hover:bg-neutral-100"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
@@ -293,31 +363,14 @@ export function PostList({ boardId, sort = "recent", q, tag, author, authorId, s
|
||||
<div className="flex items-center justify-between md:justify-end gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-neutral-600">표시 개수</span>
|
||||
<select
|
||||
value={currentPageSize}
|
||||
onChange={(e) => {
|
||||
const newSize = parseInt(e.target.value, 10);
|
||||
setCurrentPageSize(newSize);
|
||||
setPage(1);
|
||||
const nextSp = new URLSearchParams(Array.from(sp.entries()));
|
||||
nextSp.set("pageSize", String(newSize));
|
||||
nextSp.set("page", "1");
|
||||
if (typeof window !== "undefined") {
|
||||
window.history.replaceState(null, "", `?${nextSp.toString()}`);
|
||||
}
|
||||
}}
|
||||
className="h-9 px-2 rounded-md border border-neutral-300 bg-white text-sm"
|
||||
>
|
||||
<option value="10">10개</option>
|
||||
<option value="20">20개</option>
|
||||
<option value="30">30개</option>
|
||||
<option value="40">40개</option>
|
||||
<option value="50">50개</option>
|
||||
</select>
|
||||
<PageSizeDropdown />
|
||||
</div>
|
||||
{newPostHref && (
|
||||
<Link href={newPostHref} className="shrink-0">
|
||||
<button className="h-9 px-4 rounded-[10px] bg-[#f94b37] text-white text-sm border border-[#d73b29] hover:opacity-95">글쓰기</button>
|
||||
<button className="inline-flex justify-center items-center gap-1 shrink-0 h-[36px] px-[12px] py-[6px] rounded-[10px] border border-[#d73b29] bg-[#f94b37] hover:bg-[#d73b29] text-white text-sm cursor-pointer">
|
||||
<PlusIcon width={16} height={16} fill="white" />
|
||||
<span>글쓰기</span>
|
||||
</button>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user