"use client"; import React, { useState, useEffect, useRef, ReactNode } from "react"; import { useRouter } from "next/navigation"; import { useAuth } from "@/hooks/useAuth"; import { usePopSettings } from "@/hooks/pop/usePopSettings"; interface PopShellProps { children: ReactNode; showBanner?: boolean; title?: string; showBack?: boolean; headerRight?: ReactNode; fullBleed?: boolean; } export function PopShell({ children, showBanner = true, title, showBack = false, headerRight, fullBleed = false }: PopShellProps) { const router = useRouter(); const { user, logout } = useAuth(); const displayName = user?.userName || user?.userId || "사용자"; const deptName = user?.deptName || ""; const initial = displayName.charAt(0); const [mounted, setMounted] = useState(false); const [hours, setHours] = useState("00"); const [minutes, setMinutes] = useState("00"); const [seconds, setSeconds] = useState("00"); const [dateStr, setDateStr] = useState("2026-01-01"); const [colonVisible, setColonVisible] = useState(true); const [profileOpen, setProfileOpen] = useState(false); const profileRef = useRef(null); useEffect(() => { setMounted(true); function tick() { const now = new Date(); setHours(String(now.getHours()).padStart(2, "0")); setMinutes(String(now.getMinutes()).padStart(2, "0")); setSeconds(String(now.getSeconds()).padStart(2, "0")); setDateStr( `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}` ); } tick(); const clockInterval = setInterval(tick, 1000); const blinkInterval = setInterval(() => { setColonVisible((v) => !v); }, 500); return () => { clearInterval(clockInterval); clearInterval(blinkInterval); }; }, []); // Profile dropdown: close on outside click useEffect(() => { function handleClickOutside(e: MouseEvent) { if (profileRef.current && !profileRef.current.contains(e.target as Node)) { setProfileOpen(false); } } if (profileOpen) { document.addEventListener("mousedown", handleClickOutside); } return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, [profileOpen]); const handlePcMode = async () => { setProfileOpen(false); if (document.fullscreenElement) { try { await document.exitFullscreen(); } catch {} } router.push("/"); }; const handlePopHome = () => { setProfileOpen(false); router.push("/pop/home"); }; const toggleFullscreen = async () => { setProfileOpen(false); try { if (document.fullscreenElement) { await document.exitFullscreen(); } else { await document.documentElement.requestFullscreen(); } } catch { // fullscreen not supported } }; const handleLogout = () => { setProfileOpen(false); logout(); }; // POP 설정에서 배너 텍스트 로드 (POP화면설정에서 관리) const { settings: popSettings } = usePopSettings("/pop/home"); const homeConfig = (popSettings as any)?.screens?.home; const bannerEnabled = homeConfig?.bannerEnabled ?? true; const bannerText = homeConfig?.bannerText; const marqueeText = bannerText || "[공지] 금일 오후 3시 전체 안전교육 실시 예정입니다. 전 직원 필참 바랍니다. \u00a0\u00a0|\u00a0\u00a0 [알림] 내일 설비 정기점검으로 인한 3호기 가동 중지 예정 \u00a0\u00a0|\u00a0\u00a0 [안내] 4월 생산실적 우수팀 발표 - 생산1팀 축하드립니다!"; return (
{/* ===== HEADER ===== */}
{/* Left: Back + Logo + Company */}
{showBack && ( )}
router.push("/pop/home")} >
{title ? ( {title} ) : ( <> {user?.companyName || "POP"} 현장 관리 시스템 )}
{/* Center: Clock (desktop) */}
{mounted && ( <>
{hours} : {minutes} : {seconds}
{dateStr} )}
{/* Right: Mobile clock + Profile */}
{/* Mobile clock */} {mounted && (
{hours}:{minutes}
)} {/* Custom header right content (e.g. cart icon) */} {headerRight}
{/* Profile with Dropdown */}
{/* Profile Dropdown */}
{/* User Info */}

{displayName}

{deptName || user?.userId}

{/* Menu Items */}
{/* Logout */}
{/* ===== NOTICE BANNER (Marquee) ===== */} {showBanner && bannerEnabled &&
📢 공지
{marqueeText}
} {/* ===== MAIN CONTENT ===== */}
{children}
{/* FOOTER 삭제 — POP 화면에서 불필요 */} {/* Marquee keyframes */}
); }