디자인디테일
This commit is contained in:
@@ -14,6 +14,7 @@ export default function NewPostPage() {
|
||||
const initialBoardId = sp.get("boardId") ?? "";
|
||||
const boardSlug = sp.get("boardSlug") ?? undefined;
|
||||
const [form, setForm] = useState({ boardId: initialBoardId, title: "", content: "" });
|
||||
const [isSecret, setIsSecret] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
async function submit() {
|
||||
try {
|
||||
@@ -49,56 +50,90 @@ export default function NewPostPage() {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
const plainLength = (form.content || "").replace(/<[^>]*>/g, "").length;
|
||||
const MAX_LEN = 10000;
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* 상단 배너 */}
|
||||
<section>
|
||||
<HeroBanner />
|
||||
</section>
|
||||
|
||||
{/* 작성 카드 */}
|
||||
<section className="rounded-xl overflow-hidden bg-white">
|
||||
<header className="px-4 py-3 border-b border-neutral-200">
|
||||
<h1 className="text-xl md:text-2xl font-bold text-neutral-900">새 글</h1>
|
||||
</header>
|
||||
<div className="p-4 md:p-6 space-y-3">
|
||||
<section className="mx-auto max-w-5xl bg-white rounded-2xl border border-neutral-300 px-6 sm:px-8 pt-6 pb-8">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-[22px] md:text-[26px] font-semibold text-neutral-900 leading-none">게시글 작성</h1>
|
||||
<button
|
||||
aria-label="닫기"
|
||||
onClick={() => router.back()}
|
||||
className="inline-flex items-center justify-center rounded-xl p-2 hover:bg-neutral-100"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 grid grid-cols-1 sm:grid-cols-[1fr_162px] gap-3">
|
||||
<input
|
||||
className="h-10 w-full rounded-md border border-neutral-300 px-3 text-sm focus:outline-none focus:ring-2 focus:ring-neutral-400"
|
||||
placeholder="boardId"
|
||||
value={form.boardId}
|
||||
onChange={(e) => setForm({ ...form, boardId: e.target.value })}
|
||||
/>
|
||||
<input
|
||||
className="h-10 w-full rounded-md border border-neutral-300 px-3 text-sm focus:outline-none focus:ring-2 focus:ring-neutral-400"
|
||||
placeholder="제목"
|
||||
className="h-16 w-full rounded-2xl border border-neutral-300 px-6 text-lg placeholder:text-neutral-500 focus:outline-none focus:ring-2 focus:ring-neutral-400"
|
||||
placeholder="제목을 작성해주세요"
|
||||
value={form.title}
|
||||
onChange={(e) => setForm({ ...form, title: e.target.value })}
|
||||
/>
|
||||
<Editor value={form.content} onChange={(v) => setForm({ ...form, content: v })} placeholder="내용을 입력하세요" />
|
||||
<div className="pt-1">
|
||||
<UploadButton
|
||||
multiple
|
||||
onUploaded={(url) => setForm((f) => ({ ...f, content: `${f.content}\n` }))}
|
||||
{...(boardSlug ? require("@/lib/photoPresets").getPhotoPresetBySlug(boardSlug) : {})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<footer className="px-4 py-3 border-t border-neutral-200 flex items-center justify-end gap-2">
|
||||
<button
|
||||
type="button"
|
||||
className="h-9 px-4 rounded-md border border-neutral-300 bg-white text-sm hover:bg-neutral-100"
|
||||
onClick={() => router.back()}
|
||||
className="h-16 rounded-2xl border border-neutral-300 px-6 text-base text-neutral-900 bg-white hover:bg-neutral-50"
|
||||
onClick={() => {/* 태그 선택 자리표시 */}}
|
||||
>
|
||||
취소
|
||||
테그선택
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 rounded-2xl border border-neutral-300">
|
||||
<div className="p-5">
|
||||
<Editor value={form.content} onChange={(v) => setForm({ ...form, content: v })} placeholder="내용을 작성해주세요" />
|
||||
</div>
|
||||
<div className="px-4 py-3 flex items-center justify-between bg-neutral-100 rounded-b-2xl">
|
||||
<label className="inline-flex items-center gap-2 bg-white px-2.5 py-1.5 rounded-lg border border-red-300">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="size-4 accent-[#f94b37]"
|
||||
checked={isSecret}
|
||||
onChange={(e) => setIsSecret(e.target.checked)}
|
||||
/>
|
||||
<span className="text-sm text-[#f94b37]">비밀글</span>
|
||||
</label>
|
||||
|
||||
<div className="flex items-center gap-3 text-[13px]">
|
||||
<span className="text-orange-600">{plainLength}</span>
|
||||
<span className="text-neutral-900">/ {MAX_LEN.toLocaleString()}</span>
|
||||
<span aria-hidden>🙂</span>
|
||||
<UploadButton
|
||||
multiple
|
||||
onUploaded={(url) => setForm((f) => ({ ...f, content: `${f.content}\n` }))}
|
||||
{...(boardSlug ? require("@/lib/photoPresets").getPhotoPresetBySlug(boardSlug) : {})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<button
|
||||
disabled={loading}
|
||||
onClick={submit}
|
||||
className="h-9 px-4 rounded-md bg-neutral-900 text-white text-sm hover:bg-neutral-800 disabled:opacity-60"
|
||||
className="w-full h-14 rounded-2xl bg-[#f94b37] text-white text-[20px] font-semibold hover:opacity-95 disabled:opacity-60 border border-[#d73b29]"
|
||||
>
|
||||
{loading ? "저장 중..." : "등록"}
|
||||
{loading ? "저장 중..." : "게시하기"}
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<div className="sr-only">
|
||||
<input
|
||||
className="hidden"
|
||||
placeholder="boardId"
|
||||
value={form.boardId}
|
||||
onChange={(e) => setForm({ ...form, boardId: e.target.value })}
|
||||
aria-hidden
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user