"use client"; import React, { useState, useRef, useCallback, useEffect } from "react"; import { useRouter } from "next/navigation"; import { apiClient } from "@/lib/api/client"; /* ------------------------------------------------------------------ */ /* Types */ /* ------------------------------------------------------------------ */ interface ProductionMenuItem { id: string; title: string; gradient: string; shadowColor: string; icon: React.ReactNode; href: string; } interface RecentActivityItem { id: string; time: string; processName: string; itemName: string; qty: string; statusColor: string; statusLabel: string; } interface KpiData { todayCompleted: number; inProgressCount: number; completedCount: number; } /* ------------------------------------------------------------------ */ /* Data */ /* ------------------------------------------------------------------ */ const MENU_ITEMS: ProductionMenuItem[] = [ { id: "process", title: "공정실행", gradient: "linear-gradient(135deg,#f59e0b,#d97706)", shadowColor: "rgba(245,158,11,.3)", icon: ( ), href: "/pop/production/process", }, { id: "work-order", title: "작업지시", gradient: "linear-gradient(135deg,#f59e0b,#d97706)", shadowColor: "rgba(245,158,11,.3)", icon: ( ), href: "#", }, { id: "status", title: "생산현황", gradient: "linear-gradient(135deg,#f59e0b,#d97706)", shadowColor: "rgba(245,158,11,.3)", icon: ( ), href: "#", }, { id: "defect", title: "불량관리", gradient: "linear-gradient(135deg,#f59e0b,#d97706)", shadowColor: "rgba(245,158,11,.3)", icon: ( ), href: "#", }, { id: "result", title: "실적조회", gradient: "linear-gradient(135deg,#f59e0b,#d97706)", shadowColor: "rgba(245,158,11,.3)", icon: ( ), href: "#", }, ]; /* ------------------------------------------------------------------ */ /* Component */ /* ------------------------------------------------------------------ */ export function ProductionMain() { const router = useRouter(); /* KPI carousel */ const [kpiIdx, setKpiIdx] = useState(0); const kpiTimerRef = useRef | null>(null); /* Data state */ const [kpi, setKpi] = useState({ todayCompleted: 0, inProgressCount: 0, completedCount: 0, }); const [recentItems, setRecentItems] = useState([]); const [loading, setLoading] = useState(true); const startKpiAuto = useCallback(() => { if (kpiTimerRef.current) clearInterval(kpiTimerRef.current); kpiTimerRef.current = setInterval(() => setKpiIdx((p) => (p + 1) % 3), 4000); }, []); useEffect(() => { startKpiAuto(); return () => { if (kpiTimerRef.current) clearInterval(kpiTimerRef.current); }; }, [startKpiAuto]); /* Fetch real data */ useEffect(() => { const fetchData = async () => { try { setLoading(true); const wiRes = await apiClient.get("/work-instruction/list"); let wiData: any[] = []; if (wiRes.data?.data) { wiData = Array.isArray(wiRes.data.data) ? wiRes.data.data : wiRes.data.data.rows || []; } else if (Array.isArray(wiRes.data)) { wiData = wiRes.data; } // KPI 계산 let todayCompleted = 0; let inProgressCount = 0; let completedCount = 0; for (const wi of wiData) { const status = wi.progress_status || wi.status || ""; if (status === "completed" || status === "완료") { completedCount++; todayCompleted += Number(wi.completed_qty) || 0; } else if (status === "in_progress" || status === "진행중") { inProgressCount++; } } setKpi({ todayCompleted, inProgressCount, completedCount }); // 최근 활동 5건 (최신순) const sorted = [...wiData].sort((a, b) => { const da = new Date(a.start_date || a.created_date || "").getTime() || 0; const db = new Date(b.start_date || b.created_date || "").getTime() || 0; return db - da; }); const recent: RecentActivityItem[] = sorted.slice(0, 5).map((wi, idx) => { const dateObj = wi.start_date ? new Date(wi.start_date) : null; const time = dateObj ? `${String(dateObj.getMonth() + 1).padStart(2, "0")}/${String(dateObj.getDate()).padStart(2, "0")}` : "--/--"; const status = wi.progress_status || wi.status || ""; let statusColor = "text-gray-600 bg-gray-50"; let statusLabel = "대기"; if (status === "completed" || status === "완료") { statusColor = "text-green-600 bg-green-50"; statusLabel = "완료"; } else if (status === "in_progress" || status === "진행중") { statusColor = "text-blue-600 bg-blue-50"; statusLabel = "진행중"; } else if (status === "acceptable" || status === "접수가능") { statusColor = "text-amber-600 bg-amber-50"; statusLabel = "접수가능"; } return { id: String(wi.id || idx), time, processName: wi.routing ? "공정 있음" : "공정 미설정", itemName: wi.item_name || wi.item_code || wi.work_instruction_no || "-", qty: `${(Number(wi.qty) || 0).toLocaleString()} EA`, statusColor, statusLabel, }; }); setRecentItems(recent); } catch { // 실패 시 0/빈 배열 유지 } finally { setLoading(false); } }; fetchData(); }, []); const handleMenuClick = (item: ProductionMenuItem) => { if (item.href === "#") { alert(`${item.title} 화면은 준비 중입니다.`); } else { router.push(item.href); } }; return (
{/* ===== Back + Title ===== */}

생산관리

메뉴를 선택하세요

{/* ===== KPI Carousel ===== */}
{/* Slide 1 */}
{/* Single dot (only 1 slide) */}
{[0].map((idx) => (
{/* ===== Menu Icons ===== */}

생산 메뉴

{MENU_ITEMS.map((item) => ( ))}
{/* ===== Recent Activity ===== */}

최근 생산활동

최근 5건
{loading ? (
{[1, 2, 3].map((i) => (
))}
) : recentItems.length === 0 ? (
최근 생산활동 내역이 없습니다
) : ( recentItems.map((item) => (
{item.time}
{item.itemName} {item.statusLabel}
{item.processName} | {item.qty}
)) )}
); } /* ------------------------------------------------------------------ */ /* Sub-components */ /* ------------------------------------------------------------------ */ function KpiCell({ value, label, color, unit }: { value: string; label: string; color: string; unit?: string }) { return (
{value} {unit && {unit}}
{label}
); } function MenuIcon({ item, onClick }: { item: ProductionMenuItem; onClick: (item: ProductionMenuItem) => void }) { return (
onClick(item)} >
{item.icon}
{item.title}
); }