"use client"; import Link from "next/link"; import { useEffect, useRef, useState } from "react"; import ThemeToggle from "./theme-toggle"; type Me = { id: string; discordId: string; username: string; avatar?: string; role: "admin" | "writer" | "reader"; }; function getAvatarUrl(me: Me) { if (!me.avatar) { return `https://cdn.discordapp.com/embed/avatars/${Number(me.discordId) % 5}.png`; } if (me.avatar.startsWith("http://") || me.avatar.startsWith("https://")) { return me.avatar; } const ext = me.avatar.startsWith("a_") ? "gif" : "png"; return `https://cdn.discordapp.com/avatars/${me.discordId}/${me.avatar}.${ext}?size=128`; } export default function Header() { const [me, setMe] = useState(null); const [menuOpen, setMenuOpen] = useState(false); const menuRef = useRef(null); const developerClickTimeoutRef = useRef(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; async function loadMe() { try { const response = await fetch("/api/auth/me", { cache: "no-store" }); if (!response.ok) { if (response.status === 401 || response.status === 404) { if (active) setMe(null); return; } throw new Error(`Failed to load profile: ${response.status}`); } const profile = await response.json() as Me; if (active) { setMe(profile); } } catch { if (active) { setMe(null); } } } void loadMe(); return () => { active = false; }; }, []); useEffect(() => { function handleOutsideClick(event: MouseEvent) { if (!menuRef.current) { return; } if (!menuRef.current.contains(event.target as Node)) { setMenuOpen(false); } } document.addEventListener("mousedown", handleOutsideClick); return () => { document.removeEventListener("mousedown", handleOutsideClick); }; }, []); async function logout() { try { await fetch("/api/auth/logout", { method: "POST", cache: "no-store", }); } finally { setMenuOpen(false); setMe(null); window.location.href = "/"; } } return (
🎀
{me ? ( ) : ( )}
); }