디자인디테일
This commit is contained in:
75
src/app/components/BoardToolbar.tsx
Normal file
75
src/app/components/BoardToolbar.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
"use client";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import React 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 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
|
||||
|
||||
const onChangeSort = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const next = new URLSearchParams(sp.toString());
|
||||
next.set("sort", e.target.value);
|
||||
router.push(`/boards/${boardId}?${next.toString()}`);
|
||||
};
|
||||
|
||||
const onChangePeriod = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const next = new URLSearchParams(sp.toString());
|
||||
const v = e.target.value;
|
||||
next.set("period", v);
|
||||
// 계산된 start 적용
|
||||
const now = new Date();
|
||||
if (v === "1d") now.setDate(now.getDate() - 1);
|
||||
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()}`);
|
||||
};
|
||||
|
||||
const onSubmit = (formData: FormData) => {
|
||||
const next = new URLSearchParams(sp.toString());
|
||||
const scopeSel = String(formData.get("scope") || "q");
|
||||
const text = String(formData.get("text") || "");
|
||||
next.set("scope", scopeSel);
|
||||
if (scopeSel === "author") {
|
||||
next.delete("q");
|
||||
if (text) next.set("author", text); else next.delete("author");
|
||||
} else {
|
||||
next.delete("author");
|
||||
if (text) next.set("q", text); else next.delete("q");
|
||||
}
|
||||
router.push(`/boards/${boardId}?${next.toString()}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between px-0 py-2">
|
||||
<div className="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="popular">인기순</option>
|
||||
</select>
|
||||
<select aria-label="기간" className="h-8 px-2 rounded-md border border-neutral-300 bg-white text-sm" defaultValue={period} onChange={onChangePeriod}>
|
||||
<option value="all">전체기간</option>
|
||||
<option value="1d">24시간</option>
|
||||
<option value="1w">1주일</option>
|
||||
<option value="1m">1개월</option>
|
||||
</select>
|
||||
</div>
|
||||
<form action={onSubmit} className="flex items-center gap-2">
|
||||
<select name="scope" aria-label="검색대상" className="h-8 px-2 rounded-md border border-neutral-300 bg-white text-sm" defaultValue={scope}>
|
||||
<option value="q">제목+내용</option>
|
||||
<option value="author">작성자</option>
|
||||
</select>
|
||||
<input name="text" defaultValue={defaultText} placeholder="검색어를 입력해 주세요." className="h-8 w-56 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">검색</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BoardToolbar;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user