|
- "use client";
- import React, { useCallback, useEffect, useState } from "react";
- import {
- Box,
- Button,
- Card,
- CardContent,
- CardActions,
- Stack,
- Typography,
- Chip,
- CircularProgress,
- TablePagination,
- Grid,
- } from "@mui/material";
- import ArrowBackIcon from "@mui/icons-material/ArrowBack";
- import { useTranslation } from "react-i18next";
- import { fetchAllJoPickOrders, AllJoPickOrderResponse } from "@/app/api/jo/actions";
- import JobPickExecution from "./newJobPickExecution";
- interface Props {
- onSwitchToRecordTab?: () => void;
- }
- const PER_PAGE = 6;
-
- const JoPickOrderList: React.FC<Props> = ({ onSwitchToRecordTab }) =>{
- const { t } = useTranslation(["common", "jo"]);
- const [loading, setLoading] = useState(false);
- const [pickOrders, setPickOrders] = useState<AllJoPickOrderResponse[]>([]);
- const [page, setPage] = useState(0);
- const [selectedPickOrderId, setSelectedPickOrderId] = useState<number | undefined>(undefined);
- const [selectedJobOrderId, setSelectedJobOrderId] = useState<number | undefined>(undefined);
- type PickOrderFilter = "all" | "drink" | "other";
- const [filter, setFilter] = useState<PickOrderFilter>("all");
- const fetchPickOrders = useCallback(async () => {
- setLoading(true);
- try {
- const isDrinkParam =
- filter === "all" ? undefined : filter === "drink" ? true : false;
- const data = await fetchAllJoPickOrders(isDrinkParam);
- setPickOrders(Array.isArray(data) ? data : []);
- setPage(0);
- } catch (e) {
- console.error(e);
- setPickOrders([]);
- } finally {
- setLoading(false);
- }
- }, [filter]);
-
- useEffect(() => {
- fetchPickOrders( );
- }, [fetchPickOrders, filter]);
- const handleBackToList = useCallback(() => {
- setSelectedPickOrderId(undefined);
- setSelectedJobOrderId(undefined);
- fetchPickOrders();
- }, [fetchPickOrders]);
- // If a pick order is selected, show JobPickExecution detail view
- if (selectedPickOrderId !== undefined) {
- return (
- <Box>
- <Box sx={{ mb: 2 }}>
- <Button
- variant="outlined"
- onClick={() => {
- setSelectedPickOrderId(undefined);
- setSelectedJobOrderId(undefined);
- }}
- startIcon={<ArrowBackIcon />}
- >
- {t("Back to List")}
- </Button>
- </Box>
- <JobPickExecution
- filterArgs={{ pickOrderId: selectedPickOrderId, jobOrderId: selectedJobOrderId }}
- //onSwitchToRecordTab={onSwitchToRecordTab}
- onBackToList={handleBackToList} // 传递新的回调
- />
- </Box>
- );
- }
-
- const startIdx = page * PER_PAGE;
- const paged = pickOrders.slice(startIdx, startIdx + PER_PAGE);
-
- return (
- <Box>
- {loading ? (
- <Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
- <CircularProgress />
- </Box>
- ) : (
-
- <Box>
- <Box sx={{ display: 'flex', gap: 1, alignItems: 'center', flexWrap: 'wrap', mb: 2 }}>
- <Button
- variant={filter === 'all' ? 'contained' : 'outlined'}
- size="small"
- onClick={() => setFilter('all')}
- >
- {t("All")}
- </Button>
- <Button
- variant={filter === 'drink' ? 'contained' : 'outlined'}
- size="small"
- onClick={() => setFilter('drink')}
- >
- {t("Drink")}
- </Button>
- <Button
- variant={filter === 'other' ? 'contained' : 'outlined'}
- size="small"
- onClick={() => setFilter('other')}
- >
- {t("Other")}
- </Button>
- </Box>
- <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
- {t("Total pick orders")}: {pickOrders.length}
- </Typography>
-
- <Grid container spacing={2}>
- {paged.map((pickOrder) => {
- const status = String(pickOrder.jobOrderStatus || "");
- const statusLower = status.toLowerCase();
- const statusColor =
- statusLower === "completed"
- ? "success"
- : statusLower === "pending" || statusLower === "processing"
- ? "primary"
- : "default";
-
- const finishedCount = pickOrder.finishedPickOLineCount ?? 0;
-
- return (
-
- <Grid key={pickOrder.id} item xs={12} sm={6} md={4}>
- <Card
- sx={{
- minHeight: 160,
- maxHeight: 240,
- display: "flex",
- flexDirection: "column",
- }}
- >
- <CardContent
- sx={{
- pb: 1,
- flexGrow: 1,
- overflow: "auto",
- }}
- >
- <Stack direction="row" justifyContent="space-between" alignItems="center">
- <Box sx={{ minWidth: 0 }}>
- <Typography variant="subtitle1">
- {t("Job Order")}: {pickOrder.jobOrderCode || "-"}
- </Typography>
- </Box>
- <Chip size="small" label={t(status)} color={statusColor as any} />
- </Stack>
- <Typography variant="body2" color="text.secondary">
- {t("Lot No")}: {pickOrder.lotNo || "-"}
- </Typography>
- <Typography variant="body2" color="text.secondary">
- {t("Pick Order")}: {pickOrder.pickOrderCode || "-"}
- </Typography>
- <Typography variant="body2" color="text.secondary">
- {t("Item Name")}: {pickOrder.itemName}
- </Typography>
- <Typography variant="body2" color="text.secondary">
- {t("Required Qty")}: {pickOrder.reqQty} ({pickOrder.uomName})
- </Typography>
- {pickOrder.floorPickCounts?.map(({ floor, finishedCount, totalCount }) => (
- <Typography key={floor} variant="body2" color="text.secondary" component="span" sx={{ mr: 1 }}>
- {floor}: {finishedCount}/{totalCount}
- </Typography>
- ))}
- {statusLower !== "pending" && finishedCount > 0 && (
- <Box sx={{ mt: 1 }}>
- <Typography variant="body2" fontWeight={600}>
- {t("Finished lines")}: {finishedCount}
- </Typography>
- </Box>
- )}
- </CardContent>
-
- <CardActions sx={{ pt: 0.5 }}>
- <Button
- variant="contained"
- size="small"
- onClick={() => {
- setSelectedPickOrderId(pickOrder.pickOrderId ?? undefined);
- setSelectedJobOrderId(pickOrder.jobOrderId ?? undefined);
- }}
- >
- {t("View Details")}
- </Button>
- <Box sx={{ flex: 1 }} />
- </CardActions>
- </Card>
- </Grid>
- );
- })}
- </Grid>
- {pickOrders.length > 0 && (
- <TablePagination
- component="div"
- count={pickOrders.length}
- page={page}
- rowsPerPage={PER_PAGE}
- onPageChange={(e, p) => setPage(p)}
- rowsPerPageOptions={[PER_PAGE]}
- />
- )}
- </Box>
- )}
- </Box>
- );
- };
-
- export default JoPickOrderList;
|