'use client'; import Image from 'next/image'; import { useEffect, useRef, useState } from 'react'; import { logout } from '@/app/(protected)/_actions'; import { countUnread, type AdminNotification } from '@/lib/domain/notification'; import styles from './admin-header.module.scss'; import { HeaderIconButton } from './header-icon-button'; interface AdminHeaderProps { /** 프로필에 표시할 이름. 세션의 관리자 이름을 상위에서 받아온다. */ adminName: string; /** 종 버튼이 펼치는 알림. 상위 레이아웃이 조회해 넘긴다. */ notifications: AdminNotification[]; } /** * Basic 레이아웃 헤더 — 시안 header(7028:7614)를 그대로 옮겼다. 좌측 로고, 우측에 아이콘 * 버튼 3개와 프로필 pill이 온다. * * 시안과 다른 점 넷(전부 사용자 확정): * - 로고: 시안(관리자페이지 QsFVFFUKGH68xAPVkF3SJ9 logo 5199:9639)의 정사각 심볼과 * "FOX PAY ADMIN" 2색 글자를 그대로 쓴다. * - 사이드바 토글 버튼을 뺐다 — 시안에 없다. * - 프로필 pill을 눌러 로그아웃한다. 시안에 로그아웃 자리가 없는데 다른 경로도 없어서, * CaretDown이 이미 "열린다"고 알리고 있는 이 자리에 메뉴를 붙였다. * * - 검색·사용자 아이콘 버튼을 뺐다 — 연결할 기능이 없어 눌러도 아무 일이 없었고, 사용자 * 자리는 옆 프로필 pill과 겹쳤다. * * 남은 알림 버튼도 연결할 기능이 아직 없어 `onAction` 없이 둔다 — 시안의 모양을 유지하려고 * 비활성으로 만들지는 않았다. */ export function AdminHeader({ adminName, notifications }: AdminHeaderProps) { const [isNotificationOpen, setIsNotificationOpen] = useState(false); const notificationRef = useRef(null); const unreadCount = countUnread(notifications); const [isMenuOpen, setIsMenuOpen] = useState(false); const profileRef = useRef(null); // 바깥을 누르거나 Esc를 누르면 닫는다 — 열린 동안에만 듣는다. 프로필·알림이 같은 규칙이라 // 한 곳에서 처리하고, 하나를 열면 다른 하나는 닫는다. useEffect(() => { if (!isMenuOpen && !isNotificationOpen) { return; } function handlePointerDown(event: MouseEvent) { const target = event.target as Node; if (!profileRef.current?.contains(target)) { setIsMenuOpen(false); } if (!notificationRef.current?.contains(target)) { setIsNotificationOpen(false); } } function handleKeyDown(event: KeyboardEvent) { if (event.key === 'Escape') { setIsMenuOpen(false); setIsNotificationOpen(false); } } document.addEventListener('mousedown', handlePointerDown); document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('mousedown', handlePointerDown); document.removeEventListener('keydown', handleKeyDown); }; }, [isMenuOpen, isNotificationOpen]); return (
{/* 옆 글자가 같은 내용을 이미 말하므로 장식으로 둔다 — alt를 채우면 두 번 읽힌다. */} FOX PAY{' '} ADMIN