import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { ArrowLeft, Search, Download, ChevronLeft, ChevronRight, Filter, X } from 'lucide-react'; import { comms } from '../communication'; interface HistoryRow { idx: number; jtype: string; rid: string; sid: string; qty: number; vname: string; vlot: string; loc: string; qr: string; stime: string; etime: string; prnattach: boolean; prnvalid: boolean; rid0: string; sid0: string; qtymax: number; } export const HistoryPage: React.FC = () => { const navigate = useNavigate(); const [isLoading, setIsLoading] = useState(false); const [data, setData] = useState([]); const [filteredData, setFilteredData] = useState([]); const [mcName, setMcName] = useState(''); // Date range state const today = new Date(); const [startDate, setStartDate] = useState(today.toISOString().split('T')[0]); const [endDate, setEndDate] = useState(today.toISOString().split('T')[0]); // Search state const [dbSearch, setDbSearch] = useState(''); const [localFilter, setLocalFilter] = useState(''); // Load data on mount useEffect(() => { fetchData(); }, []); // Apply local filter when it changes useEffect(() => { if (!localFilter.trim()) { setFilteredData(data); } else { const keyword = localFilter.toLowerCase(); setFilteredData(data.filter(row => row.rid0?.toLowerCase().includes(keyword) || row.sid0?.toLowerCase().includes(keyword) || row.qr?.toLowerCase().includes(keyword) || row.vlot?.toLowerCase().includes(keyword) || row.vname?.toLowerCase().includes(keyword) || row.rid?.toLowerCase().includes(keyword) || row.sid?.toLowerCase().includes(keyword) )); } }, [localFilter, data]); const fetchData = async () => { setIsLoading(true); try { const result = await comms.getHistoryData(startDate, endDate, dbSearch); if (result.success) { setData(result.data || []); setFilteredData(result.data || []); if (result.mcName) { setMcName(result.mcName); } } else { console.error('Failed to fetch history:', result.message); setData([]); setFilteredData([]); } } catch (error) { console.error('Error fetching history:', error); setData([]); setFilteredData([]); } setIsLoading(false); }; const handleSearch = () => { // Validate dates if (new Date(endDate) < new Date(startDate)) { alert('End date is earlier than start date'); return; } fetchData(); }; const handlePrevDay = () => { const sd = new Date(startDate); sd.setDate(sd.getDate() - 1); const newDate = sd.toISOString().split('T')[0]; setStartDate(newDate); setEndDate(newDate); }; const handleNextDay = () => { const ed = new Date(endDate); ed.setDate(ed.getDate() + 1); const newDate = ed.toISOString().split('T')[0]; setStartDate(newDate); setEndDate(newDate); }; const handleExport = () => { if (filteredData.length === 0) { alert('No data to export'); return; } // Create CSV content const headers = ['IDX', 'JTYPE', 'RID', 'SID', 'QTY', 'QTY_MAX', 'VENDOR', 'V.LOT', 'LOC', 'QR', 'START', 'END', 'ATTACH', 'VALID', 'RID0', 'SID0']; const csvContent = [ headers.join(','), ...filteredData.map(row => [ row.idx, `"${row.jtype || ''}"`, `"${row.rid || ''}"`, `"${row.sid || ''}"`, row.qty || 0, row.qtymax || 0, `"${row.vname || ''}"`, `"${row.vlot || ''}"`, `"${row.loc || ''}"`, `"${row.qr || ''}"`, `"${row.stime || ''}"`, `"${row.etime || ''}"`, row.prnattach ? 'Y' : 'N', row.prnvalid ? 'Y' : 'N', `"${row.rid0 || ''}"`, `"${row.sid0 || ''}"`, ].join(',')) ].join('\n'); // Download file const blob = new Blob(['\uFEFF' + csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `export_${startDate.replace(/-/g, '')}~${endDate.replace(/-/g, '')}.csv`; link.click(); }; return (
{/* Header */}

WORK HISTORY {mcName && ({mcName})}

Total: {filteredData.length} records {localFilter && (filtered from {data.length})}
{/* Controls */}
{/* Date Range */}
setStartDate(e.target.value)} className="px-3 py-2 rounded-lg bg-gray-700 border border-gray-600 text-white text-sm focus:outline-none focus:border-neon-blue" /> ~ setEndDate(e.target.value)} className="px-3 py-2 rounded-lg bg-gray-700 border border-gray-600 text-white text-sm focus:outline-none focus:border-neon-blue" />
{/* DB Search */}
setDbSearch(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} placeholder="Search in DB..." className="px-3 py-2 rounded-lg bg-gray-700 border border-gray-600 text-white text-sm focus:outline-none focus:border-neon-blue w-48" />
{/* Local Filter */}
setLocalFilter(e.target.value)} placeholder="Filter results..." className={`px-3 py-2 rounded-lg border text-white text-sm focus:outline-none focus:border-neon-blue w-48 ${localFilter ? 'bg-lime-900/30 border-lime-500' : 'bg-gray-700 border-gray-600' }`} /> {localFilter && ( )}
{/* Export */}
{/* Data Table */}
{isLoading ? ( ) : filteredData.length === 0 ? ( ) : ( filteredData.map((row, index) => ( )) )}
IDX TYPE RID SID QTY VENDOR V.LOT LOC START END ATTACH VALID
Loading...
No data found
{row.idx} {row.jtype} {row.rid} {row.sid} {row.qty}/{row.qtymax} {row.vname} {row.vlot} {row.loc} {row.stime} {row.etime} {row.prnattach ? 'Y' : 'N'} {row.prnvalid ? 'Y' : 'N'}
); };