|
- "use client";
-
- import React, { useState, useEffect, useCallback, useMemo } from 'react';
- import {
- Box,
- Typography,
- FormControl,
- InputLabel,
- Select,
- MenuItem,
- Card,
- CardContent,
- Stack,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Paper,
- CircularProgress,
- TablePagination,
- Chip
- } from '@mui/material';
- import { useTranslation } from 'react-i18next';
- import dayjs from 'dayjs';
- import { arrayToDayjs } from '@/app/utils/formatUtil';
- import { fetchTicketReleaseTable, getTicketReleaseTable } from '@/app/api/do/actions';
-
- const FGPickOrderTicketReleaseTable: React.FC = () => {
- const { t } = useTranslation("ticketReleaseTable");
- const [selectedDate, setSelectedDate] = useState<string>("today");
- const [selectedFloor, setSelectedFloor] = useState<string>("");
- const [selectedStatus, setSelectedStatus] = useState<string>("released");
-
- const [data, setData] = useState<getTicketReleaseTable[]>([]);
- const [loading, setLoading] = useState<boolean>(true);
- const [paginationController, setPaginationController] = useState({
- pageNum: 0,
- pageSize: 5,
- });
-
- const formatTime = (timeData: any): string => {
- if (!timeData) return '';
-
- let hour: number;
- let minute: number;
-
- if (typeof timeData === 'string') {
-
- const parts = timeData.split(':');
- hour = parseInt(parts[0], 10);
- minute = parseInt(parts[1] || '0', 10);
- } else if (Array.isArray(timeData)) {
-
- hour = timeData[0] || 0;
- minute = timeData[1] || 0;
- }
- else {
- return '';
- }
-
- const formattedHour = hour.toString().padStart(2, '0');
- const formattedMinute = minute.toString().padStart(2, '0');
- return `${formattedHour}:${formattedMinute}`;
- };
- const getDateLabel = (offset: number) => {
- return dayjs().add(offset, 'day').format('YYYY-MM-DD');
- };
-
- const getDateRange = () => {
- const today = dayjs().format('YYYY-MM-DD');
- const dayAfterTomorrow = dayjs().add(2, 'day').format('YYYY-MM-DD');
- return { startDate: today, endDate: dayAfterTomorrow };
- };
-
- useEffect(() => {
- const loadData = async () => {
- setLoading(true);
- try {
- const { startDate, endDate } = getDateRange();
- const result = await fetchTicketReleaseTable(startDate, endDate);
- 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;
- }
- }
-
- // Filter by status if selected
- if (selectedStatus && item.ticketStatus?.toLowerCase() !== selectedStatus.toLowerCase()) {
- return false;
- }
-
-
- return true;
- },[data, selectedDate, selectedFloor, selectedStatus]);
-
- 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, selectedStatus]);
-
- return (
- <Card sx={{ mb: 2 }}>
- <CardContent>
- {/* Title */}
- <Typography variant="h5" sx={{ mb: 3, fontWeight: 600 }}>
- {t("Ticket Release Table")}
- </Typography>
-
- {/* Dropdown Menus */}
- <Stack direction="row" spacing={2} sx={{ mb: 3 }}>
- <FormControl sx={{ minWidth: 250 }} size="small">
- <InputLabel id="date-select-label">{t("Select Date")}</InputLabel>
- <Select
- labelId="date-select-label"
- id="date-select"
- value={selectedDate}
- label={t("Select Date")}
- onChange={(e) => setSelectedDate(e.target.value)}
- >
- <MenuItem value="today">
- {t("Today")} ({getDateLabel(0)})
- </MenuItem>
- <MenuItem value="tomorrow">
- {t("Tomorrow")} ({getDateLabel(1)})
- </MenuItem>
- <MenuItem value="dayAfterTomorrow">
- {t("Day After Tomorrow")} ({getDateLabel(2)})
- </MenuItem>
- </Select>
- </FormControl>
-
- <FormControl sx={{ minWidth: 150 }} size="small">
- <InputLabel
- id="floor-select-label"
- shrink={true}
- >
- {t("Floor")}
- </InputLabel>
- <Select
- labelId="floor-select-label"
- id="floor-select"
- value={selectedFloor}
- label={t("Floor")}
- onChange={(e) => setSelectedFloor(e.target.value)}
- displayEmpty
- >
- <MenuItem value="">{t("All Floors")}</MenuItem>
- <MenuItem value="2/F">2/F</MenuItem>
- <MenuItem value="4/F">4/F</MenuItem>
- </Select>
- </FormControl>
-
- <FormControl sx={{ minWidth: 150 }} size="small">
- <InputLabel
- id="status-select-label"
- shrink={true}
- >
- {t("Status")}
- </InputLabel>
- <Select
- labelId="status-select-label"
- id="status-select"
- value={selectedStatus}
- label={t("Status")}
- onChange={(e) => setSelectedStatus(e.target.value)}
- displayEmpty
- >
- <MenuItem value="">{t("All Statuses")}</MenuItem>
- <MenuItem value="pending">{t("pending")}</MenuItem>
- <MenuItem value="released">{t("released")}</MenuItem>
- <MenuItem value="completed">{t("completed")}</MenuItem>
- </Select>
- </FormControl>
- </Stack>
-
- <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("Truck Lane Code")} - {t("Departure Time")}
- </Typography>
- </Box>
- </TableCell>
- {/*<TableCell>{t("Truck Departure Time")}</TableCell>
- <TableCell>{t("Truck Lane Code")}</TableCell>*/}
- <TableCell sx={{ minWidth: 200, width: '20%' }}>{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")})
- </Typography>
- <Typography variant="caption" sx={{ color: 'text.secondary' }}>
- {t("Released Time")} - {t("Completed Time")}
- </Typography>
- </Box>
- </TableCell>
- <TableCell>{t("Handler Name")}</TableCell>
- <TableCell sx={{ minWidth: 100, width: '8%', whiteSpace: 'nowrap' }}>{t("Number of FG Items (Order Item(s) Count)")}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {paginatedData.length === 0 ? (
- <TableRow>
- <TableCell colSpan={12} align="center">
- {t("No data available")}
- </TableCell>
- </TableRow>
- ) : (
- paginatedData.map((row) => {
- return (
- <TableRow key={row.id}>
- <TableCell>{row.storeId || '-'}</TableCell>
- <TableCell>
- {row.requiredDeliveryDate
- ? dayjs(row.requiredDeliveryDate).format('YYYY-MM-DD')
- : '-'}
- </TableCell>
-
- <TableCell>
- <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap', alignItems: 'center' }}>
- {row.truckLanceCode && (
- <Chip
- label={row.truckLanceCode}
- size="small"
- color="primary"
- />
- )}
- {row.truckDepartureTime && (
- <Chip
- label={formatTime(row.truckDepartureTime)}
- size="small"
- color="secondary"
- />
- )}
- {!row.truckLanceCode && !row.truckDepartureTime && (
- <Typography variant="body2" sx={{ color: 'text.secondary' }}>
- -
- </Typography>
- )}
- </Box>
- </TableCell>
-
- <TableCell sx={{ minWidth: 200, width: '20%' }}>{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 ? t(row.ticketStatus.toLowerCase()) : '-'})
- </Typography>
- <Typography variant="body2">
- {t("Released Time")}: {row.ticketReleaseTime
- ? (() => {
- if (Array.isArray(row.ticketReleaseTime)) {
- return arrayToDayjs(row.ticketReleaseTime, true).format('HH:mm');
- }
- const parsedDate = dayjs(row.ticketReleaseTime, 'YYYYMMDDHHmmss');
- if (!parsedDate.isValid()) {
- return dayjs(row.ticketReleaseTime).format('HH:mm');
- }
- return parsedDate.format('HH:mm');
- })()
- : '-'}
- </Typography>
- <Typography variant="body2">
- {t("Completed Time")}: {row.ticketCompleteDateTime
- ? (() => {
- if (Array.isArray(row.ticketCompleteDateTime)) {
- return arrayToDayjs(row.ticketCompleteDateTime, true).format('HH:mm');
- }
- const parsedDate = dayjs(row.ticketCompleteDateTime, 'YYYYMMDDHHmmss');
- if (!parsedDate.isValid()) {
- return dayjs(row.ticketCompleteDateTime).format('HH:mm');
- }
- return parsedDate.format('HH:mm');
- })()
- : '-'}
- </Typography>
- </Box>
- </TableCell>
- <TableCell>{row.handlerName || '-'}</TableCell>
- <TableCell sx={{ minWidth: 100, width: '8%' }}>{row.numberOfFGItems ?? 0}</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>
- );
- };
-
- export default FGPickOrderTicketReleaseTable;
|