"use client"; import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { Box, Typography, Card, CardContent, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, CircularProgress, Button, Chip } from '@mui/material'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { fetchGoodsReceiptStatusClient, type GoodsReceiptStatusRow } from '@/app/api/dashboard/client'; const REFRESH_MS = 15 * 60 * 1000; const GoodsReceiptStatusNew: React.FC = () => { const { t } = useTranslation("dashboard"); const [selectedDate, setSelectedDate] = useState(dayjs()); const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const [lastUpdated, setLastUpdated] = useState(null); const [screenCleared, setScreenCleared] = useState(false); const loadData = useCallback(async () => { if (screenCleared) return; try { setLoading(true); const dateParam = selectedDate.format('YYYY-MM-DD'); const result = await fetchGoodsReceiptStatusClient(dateParam); setData(result ?? []); setLastUpdated(dayjs()); } catch (error) { console.error('Error fetching goods receipt status:', error); setData([]); } finally { setLoading(false); } }, [selectedDate, screenCleared]); useEffect(() => { if (screenCleared) return; loadData(); const refreshInterval = setInterval(() => { loadData(); }, REFRESH_MS); return () => clearInterval(refreshInterval); }, [loadData, screenCleared]); const selectedDateLabel = useMemo(() => { return selectedDate.format('YYYY-MM-DD'); }, [selectedDate]); const totalStatistics = useMemo(() => { // Overall statistics should count ALL POs, including those hidden from the table const totalReceived = data.reduce((sum, row) => sum + (row.noOfOrdersReceivedAtDock || 0), 0); const totalExpected = data.reduce((sum, row) => sum + (row.expectedNoOfDelivery || 0), 0); return { received: totalReceived, expected: totalExpected }; }, [data]); type StatusKey = 'pending' | 'receiving' | 'accepted'; const getStatusKey = useCallback((row: GoodsReceiptStatusRow): StatusKey => { // Only when the whole PO is processed (all items finished IQC and PO completed) // should we treat it as "accepted" (已收貨). if (row.noOfOrdersReceivedAtDock === 1) { return 'accepted'; } // If some items have been inspected or put away but the order is not fully processed, // treat as "receiving" / "processing". if ((row.noOfItemsInspected ?? 0) > 0 || (row.noOfItemsCompletedPutAwayAtStore ?? 0) > 0) { return 'receiving'; } // Otherwise, nothing has started yet -> "pending". return 'pending'; }, []); const renderStatusChip = useCallback((row: GoodsReceiptStatusRow) => { const statusKey = getStatusKey(row); const label = t(statusKey); // Color mapping: pending -> red, receiving -> yellow, accepted -> default/green-ish const color = statusKey === 'pending' ? 'error' : statusKey === 'receiving' ? 'warning' : 'success'; return ( ); }, [getStatusKey, t]); if (screenCleared) { return ( {t("Screen cleared")} ); } return ( {/* Header */} {t("Date")}: { if (!value) return; setSelectedDate(value); }} slotProps={{ textField: { size: "small", sx: { minWidth: 160 } } }} /> 訂單已處理: {totalStatistics.received}/{totalStatistics.expected} {t("Auto-refresh every 15 minutes")} | {t("Last updated")}: {lastUpdated ? lastUpdated.format('HH:mm:ss') : '--:--:--'} {/* Table */} {loading ? ( ) : ( {t("Supplier")} {t("Purchase Order Code")} {t("Status")} {t("No. of Items with IQC Issue")} {data.length === 0 ? ( {t("No data available")} ({selectedDateLabel}) ) : ( data .filter((row) => !row.hideFromDashboard) // hide completed/rejected POs from table only .map((row, index) => ( {row.supplierCode || '-'} - {row.supplierName || '-'} {row.purchaseOrderCode || '-'} {renderStatusChip(row)} {row.noOfItemsWithIqcIssue ?? 0} )) )}
)}
); }; export default GoodsReceiptStatusNew; 4