import React, { useMemo } from 'react'; import { FeedSackLogEntry, FeedSackColumnConfig } from '../../types/counting.ts'; import { formatNumber } from '../../utils/formatters.ts'; import { getEffectiveDate } from '../../utils/dateFilter.ts'; interface FeedSaldoCardProps { iotData: FeedSackLogEntry[]; columnConfig: FeedSackColumnConfig[]; startDate: Date; saldoAwal?: number; effectiveDate?: Date; } const FeedSaldoCard: React.FC = ({ iotData, columnConfig, startDate, saldoAwal = 0, effectiveDate, }) => { const displayDate = effectiveDate ?? getEffectiveDate(); const saldoData = useMemo(() => { const inboundCameras = columnConfig .filter((c) => c.type === 'inbound') .map((c) => c.cameraName); const usageCameras = columnConfig.filter((c) => c.type === 'usage').map((c) => c.cameraName); const outboundCameras = columnConfig .filter((c) => c.type === 'outbound') .map((c) => c.cameraName); // Date filtering: from startDate to today const filterStartDate = new Date(startDate); filterStartDate.setHours(0, 0, 0, 0); const today = new Date(displayDate); today.setHours(23, 59, 59, 999); // Calculate IOT saldo (cumulative) const inbound = iotData .filter( (log) => inboundCameras.includes(log.cameraName) && log.timestamp >= filterStartDate && log.timestamp <= today ) .reduce((sum, log) => sum + log.count, 0); const usage = iotData .filter( (log) => usageCameras.includes(log.cameraName) && log.timestamp >= filterStartDate && log.timestamp <= today ) .reduce((sum, log) => sum + log.count, 0); const outbound = iotData .filter( (log) => outboundCameras.includes(log.cameraName) && log.timestamp >= filterStartDate && log.timestamp <= today ) .reduce((sum, log) => sum + log.count, 0); const saldo = saldoAwal + inbound - usage - outbound; return { inbound, usage, outbound, saldo, saldoAwal }; }, [iotData, columnConfig, startDate, saldoAwal, displayDate]); const formatTodayLabel = () => new Intl.DateTimeFormat('id-ID', { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'Asia/Jakarta', }).format(displayDate); const formatDateRange = () => { const start = startDate.toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric', }); return `${start} - ${formatTodayLabel()}`; }; const getSaldoStatusColor = (saldo: number) => { if (saldo > 0) return 'text-green-600'; if (saldo < 0) return 'text-red-600'; return 'text-gray-600'; }; return (

Saldo Karung Pakan

{formatDateRange()}

{/* Saldo Display */}
{/* Saldo Awal */}

Saldo Awal

{formatNumber(saldoData.saldoAwal)}

karung

{/* Karung Masuk */}

Karung Masuk

{formatNumber(saldoData.inbound)}

karung

{/* Karung Dituang */}

Karung Dituang

{formatNumber(saldoData.usage)}

karung

{/* Karung Keluar */}

Karung Keluar

{formatNumber(saldoData.outbound)}

karung

{/* Saldo */}

Saldo

{formatNumber(saldoData.saldo)}

karung

{/* Warning for negative saldo */} {saldoData.saldo < 0 && (

Peringatan: Saldo negatif menunjukkan karung dituang dan keluar lebih banyak dari karung masuk. Periksa kembali data atau konfigurasi kolom.

)}
); }; export default FeedSaldoCard;