feat: implement post existence check and detail page

This commit is contained in:
암냥 2026-04-18 06:48:21 +09:00
commit b18cff8b1a
No known key found for this signature in database
10 changed files with 646 additions and 43 deletions

View file

@ -1,5 +1,6 @@
"use client";
import Link from "next/link";
import { useEffect, useRef, useState } from "react";
type Me = {
@ -27,6 +28,53 @@ export default function Header() {
const [me, setMe] = useState<Me | null>(null);
const [menuOpen, setMenuOpen] = useState(false);
const menuRef = useRef<HTMLDivElement | null>(null);
const developerClickTimeoutRef = useRef<number | null>(null);
function handleIconClick() {
if (typeof window === "undefined") {
return;
}
const clickCountKey = "developer_icon_click_count";
const lastClickAtKey = "developer_icon_click_last_at";
const developerKey = "developer";
const now = Date.now();
const lastClickAt = Number(window.localStorage.getItem(lastClickAtKey) ?? "0");
const previousCount = Number(window.localStorage.getItem(clickCountKey) ?? "0");
const nextCount = now - lastClickAt > 1500 ? 1 : previousCount + 1;
window.localStorage.setItem(clickCountKey, String(nextCount));
window.localStorage.setItem(lastClickAtKey, String(now));
if (developerClickTimeoutRef.current !== null) {
window.clearTimeout(developerClickTimeoutRef.current);
}
developerClickTimeoutRef.current = window.setTimeout(() => {
window.localStorage.removeItem(clickCountKey);
window.localStorage.removeItem(lastClickAtKey);
developerClickTimeoutRef.current = null;
}, 1500);
if (nextCount >= 10) {
window.localStorage.setItem(developerKey, "true");
window.localStorage.removeItem(clickCountKey);
window.localStorage.removeItem(lastClickAtKey);
if (developerClickTimeoutRef.current !== null) {
window.clearTimeout(developerClickTimeoutRef.current);
developerClickTimeoutRef.current = null;
}
}
}
useEffect(() => {
return () => {
if (developerClickTimeoutRef.current !== null) {
window.clearTimeout(developerClickTimeoutRef.current);
}
};
}, []);
useEffect(() => {
let active = true;
@ -91,11 +139,11 @@ export default function Header() {
return (
<header className="relative z-60 flex h-16 items-center justify-between border-b border-border bg-background/90 backdrop-blur px-6">
<a href="/" className="text-2xl">🎀</a>
<Link href="/" className="text-2xl" id="icon" onClick={handleIconClick}>🎀</Link>
{me ? (
<div className="relative flex items-center gap-4" id="menu" ref={menuRef}>
{me.role === "admin" || me.role === "writer" ? (
<a href="/add" className="text-[16px] text-foreground/50">[ <span className="text-foreground">+</span> ]</a>
<Link href="/add" className="text-[16px] text-foreground/50">[ <span className="text-foreground">+</span> ]</Link>
) : null}
<button