"use client"; import React, { useState, useMemo } from "react"; import { useRouter } from "next/navigation"; import { cn } from "@/lib/utils"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Monitor, LayoutGrid, LogOut, UserCircle } from "lucide-react"; import { PopComponentRegistry } from "@/lib/registry/PopComponentRegistry"; import { useAuth } from "@/hooks/useAuth"; // ======================================== // 타입 정의 // ======================================== type AvatarSize = "sm" | "md" | "lg"; export interface PopProfileConfig { avatarSize?: AvatarSize; showDashboardLink?: boolean; showPcMode?: boolean; showLogout?: boolean; } const DEFAULT_CONFIG: PopProfileConfig = { avatarSize: "md", showDashboardLink: true, showPcMode: true, showLogout: true, }; const AVATAR_SIZE_MAP: Record = { sm: { container: "h-8 w-8", text: "text-sm", px: 32 }, md: { container: "h-10 w-10", text: "text-base", px: 40 }, lg: { container: "h-12 w-12", text: "text-lg", px: 48 }, }; const AVATAR_SIZE_LABELS: Record = { sm: "작은 (32px)", md: "보통 (40px)", lg: "큰 (48px)", }; // ======================================== // 뷰어 컴포넌트 // ======================================== interface PopProfileComponentProps { config?: PopProfileConfig; componentId?: string; screenId?: string; } function PopProfileComponent({ config: rawConfig }: PopProfileComponentProps) { const router = useRouter(); const { user, isLoggedIn, logout } = useAuth(); const [open, setOpen] = useState(false); const config = useMemo(() => ({ ...DEFAULT_CONFIG, ...rawConfig, }), [rawConfig]); const sizeInfo = AVATAR_SIZE_MAP[config.avatarSize || "md"]; const initial = user?.userName?.substring(0, 1)?.toUpperCase() || "?"; const handlePcMode = () => { setOpen(false); router.push("/"); }; const handleDashboard = () => { setOpen(false); router.push("/pop"); }; const handleLogout = async () => { setOpen(false); await logout(); }; const handleLogin = () => { setOpen(false); router.push("/login"); }; return (
{isLoggedIn && user ? ( <> {/* 사용자 정보 */}
{user.photo && user.photo.trim() !== "" && user.photo !== "null" ? ( {user.userName ) : ( initial )}
{user.userName || "사용자"} ({user.userId || ""}) {user.deptName || "부서 정보 없음"}
{/* 메뉴 항목 */}
{config.showDashboardLink && ( )} {config.showPcMode && ( )} {config.showLogout && ( <>
)}
) : (

로그인이 필요합니다

)}
); } // ======================================== // 설정 패널 // ======================================== interface PopProfileConfigPanelProps { config: PopProfileConfig; onUpdate: (config: PopProfileConfig) => void; } function PopProfileConfigPanel({ config: rawConfig, onUpdate }: PopProfileConfigPanelProps) { const config = useMemo(() => ({ ...DEFAULT_CONFIG, ...rawConfig, }), [rawConfig]); const updateConfig = (partial: Partial) => { onUpdate({ ...config, ...partial }); }; return (
{/* 아바타 크기 */}
{/* 메뉴 항목 토글 */}
updateConfig({ showDashboardLink: v })} />
updateConfig({ showPcMode: v })} />
updateConfig({ showLogout: v })} />
); } // ======================================== // 디자이너 미리보기 // ======================================== function PopProfilePreview({ config }: { config?: PopProfileConfig }) { const size = AVATAR_SIZE_MAP[config?.avatarSize || "md"]; return (
프로필
); } // ======================================== // 레지스트리 등록 // ======================================== PopComponentRegistry.registerComponent({ id: "pop-profile", name: "프로필", description: "사용자 프로필 / PC 전환 / 로그아웃", category: "action", icon: "UserCircle", component: PopProfileComponent, configPanel: PopProfileConfigPanel, preview: PopProfilePreview, defaultProps: { avatarSize: "md", showDashboardLink: true, showPcMode: true, showLogout: true, }, connectionMeta: { sendable: [], receivable: [], }, touchOptimized: true, supportedDevices: ["mobile", "tablet"], });