|
|
|
@@ -1,6 +1,6 @@ |
|
|
|
"use client"; |
|
|
|
|
|
|
|
import React, { useState } from 'react'; |
|
|
|
import React, { useState, useEffect, useCallback, useMemo } from 'react'; |
|
|
|
import { |
|
|
|
Box, |
|
|
|
Typography, |
|
|
|
@@ -11,19 +11,95 @@ import { |
|
|
|
Card, |
|
|
|
CardContent, |
|
|
|
Stack, |
|
|
|
Table, |
|
|
|
TableBody, |
|
|
|
TableCell, |
|
|
|
TableContainer, |
|
|
|
TableHead, |
|
|
|
TableRow, |
|
|
|
Paper, |
|
|
|
CircularProgress, |
|
|
|
TablePagination |
|
|
|
} from '@mui/material'; |
|
|
|
import { useTranslation } from 'react-i18next'; |
|
|
|
import dayjs from 'dayjs'; |
|
|
|
import { fetchTicketReleaseTable, getTicketReleaseTable } from '@/app/api/do/actions'; |
|
|
|
|
|
|
|
const FGPickOrderTicketReleaseTable: React.FC = () => { |
|
|
|
const { t } = useTranslation("pickOrder"); |
|
|
|
const [selectedDate, setSelectedDate] = useState<string>("today"); |
|
|
|
const [selectedFloor, setSelectedFloor] = useState<string>(""); |
|
|
|
const [data, setData] = useState<getTicketReleaseTable[]>([]); |
|
|
|
const [loading, setLoading] = useState<boolean>(true); |
|
|
|
const [paginationController, setPaginationController] = useState({ |
|
|
|
pageNum: 0, |
|
|
|
pageSize: 10, |
|
|
|
}); |
|
|
|
|
|
|
|
const getDateLabel = (offset: number) => { |
|
|
|
return dayjs().add(offset, 'day').format('YYYY-MM-DD'); |
|
|
|
}; |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const loadData = async () => { |
|
|
|
setLoading(true); |
|
|
|
try { |
|
|
|
const result = await fetchTicketReleaseTable(); |
|
|
|
setData(result); |
|
|
|
} catch (error) { |
|
|
|
console.error('Error fetching ticket release table:', error); |
|
|
|
} finally { |
|
|
|
setLoading(false); |
|
|
|
} |
|
|
|
}; |
|
|
|
loadData(); |
|
|
|
}, []); |
|
|
|
|
|
|
|
const filteredData = data.filter((item) => { |
|
|
|
// Filter by floor if selected |
|
|
|
if (selectedFloor && item.storeId !== selectedFloor) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// Filter by date if selected |
|
|
|
if (selectedDate && item.requiredDeliveryDate) { |
|
|
|
const itemDate = dayjs(item.requiredDeliveryDate).format('YYYY-MM-DD'); |
|
|
|
const targetDate = getDateLabel( |
|
|
|
selectedDate === "today" ? 0 : selectedDate === "tomorrow" ? 1 : 2 |
|
|
|
); |
|
|
|
if (itemDate !== targetDate) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
},[data, selectedDate, selectedFloor]); |
|
|
|
|
|
|
|
const handlePageChange = useCallback((event: unknown, newPage: number) => { |
|
|
|
setPaginationController(prev => ({ |
|
|
|
...prev, |
|
|
|
pageNum: newPage, |
|
|
|
})); |
|
|
|
}, []); |
|
|
|
|
|
|
|
const handlePageSizeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => { |
|
|
|
const newPageSize = parseInt(event.target.value, 10); |
|
|
|
setPaginationController({ |
|
|
|
pageNum: 0, |
|
|
|
pageSize: newPageSize, |
|
|
|
}); |
|
|
|
}, []); |
|
|
|
|
|
|
|
const paginatedData = useMemo(() => { |
|
|
|
const startIndex = paginationController.pageNum * paginationController.pageSize; |
|
|
|
const endIndex = startIndex + paginationController.pageSize; |
|
|
|
return filteredData.slice(startIndex, endIndex); |
|
|
|
}, [filteredData, paginationController]); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
setPaginationController(prev => ({ ...prev, pageNum: 0 })); |
|
|
|
}, [selectedDate, selectedFloor]); |
|
|
|
|
|
|
|
return ( |
|
|
|
<Card sx={{ mb: 2 }}> |
|
|
|
<CardContent> |
|
|
|
@@ -56,9 +132,13 @@ const FGPickOrderTicketReleaseTable: React.FC = () => { |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
|
|
|
|
{/* Floor Selection Dropdown */} |
|
|
|
<FormControl sx={{ minWidth: 150 }} size="small"> |
|
|
|
<InputLabel id="floor-select-label">{t("Floor")}</InputLabel> |
|
|
|
<FormControl sx={{ minWidth: 150 }} size="small"> |
|
|
|
<InputLabel |
|
|
|
id="floor-select-label" |
|
|
|
shrink={true} |
|
|
|
> |
|
|
|
{t("Floor")} |
|
|
|
</InputLabel> |
|
|
|
<Select |
|
|
|
labelId="floor-select-label" |
|
|
|
id="floor-select" |
|
|
|
@@ -70,18 +150,171 @@ const FGPickOrderTicketReleaseTable: React.FC = () => { |
|
|
|
<MenuItem value=""> |
|
|
|
<em>{t("All Floors")}</em> |
|
|
|
</MenuItem> |
|
|
|
<MenuItem value="2F">2/F</MenuItem> |
|
|
|
<MenuItem value="4F">4/F</MenuItem> |
|
|
|
<MenuItem value="2/F">2/F</MenuItem> |
|
|
|
<MenuItem value="4/F">4/F</MenuItem> |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
</Stack> |
|
|
|
|
|
|
|
{/* Table content will go here */} |
|
|
|
<Box sx={{ mt: 2 }}> |
|
|
|
<Typography variant="body2" color="text.secondary"> |
|
|
|
{/* Add your table component here */} |
|
|
|
Table content goes here... |
|
|
|
</Typography> |
|
|
|
<Box sx={{ mt: 2 }}> |
|
|
|
{loading ? ( |
|
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}> |
|
|
|
<CircularProgress /> |
|
|
|
</Box> |
|
|
|
) : ( |
|
|
|
<> |
|
|
|
<TableContainer component={Paper}> |
|
|
|
<Table size="small" sx={{ minWidth: 650 }}> |
|
|
|
<TableHead> |
|
|
|
<TableRow> |
|
|
|
<TableCell>{t("Store ID")}</TableCell> |
|
|
|
<TableCell>{t("Required Delivery Date")}</TableCell> |
|
|
|
<TableCell> |
|
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}> |
|
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 600 }}> |
|
|
|
{t("Truck Information")} |
|
|
|
</Typography> |
|
|
|
<Typography variant="caption" sx={{ color: 'text.secondary' }}> |
|
|
|
{t("Departure Time")} / {t("Truck Lane Code")} |
|
|
|
</Typography> |
|
|
|
</Box> |
|
|
|
</TableCell> |
|
|
|
{/*<TableCell>{t("Truck Departure Time")}</TableCell> |
|
|
|
<TableCell>{t("Truck Lane Code")}</TableCell>*/} |
|
|
|
<TableCell>{t("Shop Name")}</TableCell> |
|
|
|
<TableCell>{t("Loading Sequence")}</TableCell> |
|
|
|
{/*<TableCell>{t("Delivery Order Code(s)")}</TableCell> |
|
|
|
<TableCell>{t("Pick Order Code(s)")}</TableCell> |
|
|
|
<TableCell>{t("Ticket Number")}</TableCell> |
|
|
|
<TableCell>{t("Ticket Release Time")}</TableCell> |
|
|
|
<TableCell>{t("Ticket Complete Date Time")}</TableCell> |
|
|
|
<TableCell>{t("Ticket Status")}</TableCell>*/} |
|
|
|
<TableCell> |
|
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}> |
|
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 600 }}> |
|
|
|
{t("Ticket Information")} |
|
|
|
</Typography> |
|
|
|
<Typography variant="caption" sx={{ color: 'text.secondary' }}> |
|
|
|
{t("Ticket No.")} ({t("Status")}) / {t("Release Time")} / {t("Complete Time")} |
|
|
|
</Typography> |
|
|
|
</Box> |
|
|
|
</TableCell> |
|
|
|
<TableCell>{t("Handler Name")}</TableCell> |
|
|
|
<TableCell>{t("Number of FG Items")}</TableCell> |
|
|
|
</TableRow> |
|
|
|
</TableHead> |
|
|
|
<TableBody> |
|
|
|
{paginatedData.length === 0 ? ( |
|
|
|
<TableRow> |
|
|
|
<TableCell colSpan={12} align="center"> |
|
|
|
{t("No data available")} |
|
|
|
</TableCell> |
|
|
|
</TableRow> |
|
|
|
) : ( |
|
|
|
paginatedData.map((row) => { |
|
|
|
const isPending = row.ticketStatus?.toLowerCase() === 'pending'; |
|
|
|
const showTimes = !isPending && (row.ticketStatus?.toLowerCase() === 'released' || row.ticketStatus?.toLowerCase() === 'completed'); |
|
|
|
|
|
|
|
return ( |
|
|
|
<TableRow key={row.id}> |
|
|
|
<TableCell>{row.storeId || '-'}</TableCell> |
|
|
|
<TableCell> |
|
|
|
{row.requiredDeliveryDate |
|
|
|
? dayjs(row.requiredDeliveryDate).format('YYYY-MM-DD') |
|
|
|
: '-'} |
|
|
|
</TableCell> |
|
|
|
|
|
|
|
<TableCell> |
|
|
|
<Typography variant="body2"> |
|
|
|
{row.truckDepartureTime && row.truckLanceCode |
|
|
|
? (() => { |
|
|
|
let timeStr = row.truckDepartureTime.toString().trim(); |
|
|
|
timeStr = timeStr.replace(',', ':'); |
|
|
|
const timeMatch = timeStr.match(/^(\d{1,2})[:](\d{2})/); |
|
|
|
if (timeMatch) { |
|
|
|
const hours = timeMatch[1].padStart(2, '0'); |
|
|
|
const minutes = timeMatch[2]; |
|
|
|
return `${hours}:${minutes} | ${row.truckLanceCode}`; |
|
|
|
} |
|
|
|
return `${timeStr} | ${row.truckLanceCode}`; |
|
|
|
})() |
|
|
|
: row.truckDepartureTime |
|
|
|
? (() => { |
|
|
|
let timeStr = row.truckDepartureTime.toString().trim(); |
|
|
|
timeStr = timeStr.replace(',', ':'); |
|
|
|
const timeMatch = timeStr.match(/^(\d{1,2})[:](\d{2})/); |
|
|
|
if (timeMatch) { |
|
|
|
const hours = timeMatch[1].padStart(2, '0'); |
|
|
|
const minutes = timeMatch[2]; |
|
|
|
return `${hours}:${minutes}`; |
|
|
|
} |
|
|
|
return timeStr; |
|
|
|
})() |
|
|
|
: row.truckLanceCode || '-'} |
|
|
|
</Typography> |
|
|
|
</TableCell> |
|
|
|
|
|
|
|
<TableCell>{row.shopName || '-'}</TableCell> |
|
|
|
<TableCell>{row.loadingSequence || '-'}</TableCell> |
|
|
|
{/*<TableCell>{row.deliveryOrderCode || '-'}</TableCell> |
|
|
|
<TableCell>{row.pickOrderCode || '-'}</TableCell> |
|
|
|
<TableCell>{row.ticketNo || '-'}</TableCell> |
|
|
|
<TableCell> |
|
|
|
{row.ticketReleaseTime |
|
|
|
? dayjs(row.ticketReleaseTime).format('YYYY-MM-DD HH:mm:ss') |
|
|
|
: '-'} |
|
|
|
</TableCell> |
|
|
|
<TableCell> |
|
|
|
{row.ticketCompleteDateTime |
|
|
|
? dayjs(row.ticketCompleteDateTime).format('YYYY-MM-DD HH:mm:ss') |
|
|
|
: '-'} |
|
|
|
</TableCell> |
|
|
|
<TableCell>{row.ticketStatus || '-'}</TableCell>*/} |
|
|
|
|
|
|
|
<TableCell> |
|
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}> |
|
|
|
<Typography variant="body2"> |
|
|
|
{row.ticketNo || '-'} ({row.ticketStatus || '-'}) |
|
|
|
</Typography> |
|
|
|
{showTimes && ( |
|
|
|
<> |
|
|
|
<Typography variant="body2"> |
|
|
|
{row.ticketReleaseTime |
|
|
|
? dayjs(row.ticketReleaseTime, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm') |
|
|
|
: '-'} |
|
|
|
</Typography> |
|
|
|
<Typography variant="body2"> |
|
|
|
{row.ticketCompleteDateTime |
|
|
|
? dayjs(row.ticketCompleteDateTime, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm') |
|
|
|
: '-'} |
|
|
|
</Typography> |
|
|
|
</> |
|
|
|
)} |
|
|
|
</Box> |
|
|
|
</TableCell> |
|
|
|
<TableCell>{row.handlerName || '-'}</TableCell> |
|
|
|
<TableCell>-</TableCell> |
|
|
|
</TableRow> |
|
|
|
); |
|
|
|
}) |
|
|
|
)} |
|
|
|
</TableBody> |
|
|
|
</Table> |
|
|
|
</TableContainer> |
|
|
|
{filteredData.length > 0 && ( |
|
|
|
<TablePagination |
|
|
|
component="div" |
|
|
|
count={filteredData.length} |
|
|
|
page={paginationController.pageNum} |
|
|
|
rowsPerPage={paginationController.pageSize} |
|
|
|
onPageChange={handlePageChange} |
|
|
|
onRowsPerPageChange={handlePageSizeChange} |
|
|
|
rowsPerPageOptions={[5, 10, 15]} |
|
|
|
labelRowsPerPage={t("Rows per page")} |
|
|
|
/> |
|
|
|
)} |
|
|
|
</> |
|
|
|
)} |
|
|
|
</Box> |
|
|
|
</CardContent> |
|
|
|
</Card> |
|
|
|
|