Przeglądaj źródła

update

reset-do-picking-order
CANCERYS\kw093 2 tygodni temu
rodzic
commit
75f3e6a819
1 zmienionych plików z 228 dodań i 0 usunięć
  1. +228
    -0
      src/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal.tsx

+ 228
- 0
src/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal.tsx Wyświetl plik

@@ -0,0 +1,228 @@
// 新建檔案
"use client";

import {
Modal,
Box,
Typography,
TextField,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
CircularProgress,
Button,
} from "@mui/material";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import {
fetchReleasedDoPickOrdersForSelection,
assignByDoPickOrderId,
type ReleasedDoPickOrderListItem,
} from "@/app/api/pickOrder/actions";
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import Swal from "sweetalert2";
import dayjs from "dayjs";

interface Props {
open: boolean;
onClose: () => void;
onAssigned: () => void;
storeId: string;
truck: string;
}

const ReleasedDoPickOrderSelectModal: React.FC<Props> = ({
open,
onClose,
onAssigned,
storeId,
truck,
}) => {
const { t } = useTranslation("pickOrder");
const { data: session } = useSession() as { data: SessionWithTokens | null };
const currentUserId = session?.id ? parseInt(session.id) : undefined;

const [list, setList] = useState<ReleasedDoPickOrderListItem[]>([]);
const [loading, setLoading] = useState(false);
const [shopSearch, setShopSearch] = useState("");
const [isAssigning, setIsAssigning] = useState(false);

const loadList = useCallback(async () => {
if (!open) return;
setLoading(true);
try {
const data = await fetchReleasedDoPickOrdersForSelection(
shopSearch.trim() || undefined,
storeId,
truck?.trim() || undefined // 傳入 truck
);
setList(data);
} catch (e) {
console.error(e);
setList([]);
} finally {
setLoading(false);
}
}, [open, shopSearch, storeId, truck]);

useEffect(() => {
loadList();
}, [loadList]);

const handleSelectRow = useCallback(
async (item: ReleasedDoPickOrderListItem) => {
if (!currentUserId) return;
const confirmResult = await Swal.fire({
title: t("Confirm Assignment"),
html: `
<div style="text-align: left;">
<p><strong>${t("Date")}:</strong> ${item.requiredDeliveryDate ?? "-"}</p>
<p><strong>${t("Shop")}:</strong> ${item.shopName ?? item.shopCode ?? "-"}</p>
<p><strong>${t("Truck")}:</strong> ${item.truckLanceCode ?? "-"}</p>
<p><strong>${t("Delivery Order")}:</strong> ${(item.deliveryOrderCodes ?? []).join(", ")}</p>
</div>
`,
icon: "question",
showCancelButton: true,
confirmButtonText: t("Confirm"),
cancelButtonText: t("Cancel"),
confirmButtonColor: "#8dba00",
cancelButtonColor: "#F04438",
didOpen: () => {
const container = document.querySelector('.swal2-container');
const popup = Swal.getPopup();
if (container) (container as HTMLElement).style.zIndex = '9999';
if (popup) popup.style.zIndex = '9999';
}
});

if (!confirmResult.isConfirmed) return;

setIsAssigning(true);
try {
const res = await assignByDoPickOrderId(currentUserId, item.id);
if (res?.code === "SUCCESS") {
Swal.fire({
icon: "success",
text: t("Assigned successfully"),
timer: 1500,
showConfirmButton: false,
});
onAssigned?.();
onClose();
} else {
Swal.fire({
icon: "error",
text: res?.message ?? t("Assignment failed"),
});
}
} catch (e) {
console.error(e);
Swal.fire({ icon: "error", text: t("Error occurred during assignment.") });
} finally {
setIsAssigning(false);
}
},
[currentUserId, t, onAssigned, onClose]
);

return (
<Modal open={open} onClose={onClose}>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: { xs: "95%", sm: 900 },
maxHeight: "80vh",
bgcolor: "background.paper",
borderRadius: 2,
boxShadow: 24,
p: 2,
display: "flex",
flexDirection: "column",
overflow: "hidden",
}}
>
<Typography variant="h6" sx={{ mb: 2 }}>
{t("Not Yet Finished Released Do Pick Orders")}
</Typography>

<TextField
label={t("Search by Shop")}
size="small"
value={shopSearch}
onChange={(e) => setShopSearch(e.target.value)}
sx={{ mb: 2 }}
fullWidth
/>

{loading ? (
<Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
<CircularProgress />
</Box>
) : (
<TableContainer sx={{ flex: 1, overflow: "auto" }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<TableCell>{t("Date")}</TableCell>
<TableCell>{t("Shop")}</TableCell>
<TableCell>{t("Truck")}</TableCell>
<TableCell>{t("Delivery Order Code")}</TableCell>
<TableCell align="right">{t("Action")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{list.map((row) => (
<TableRow key={row.id} hover>
<TableCell>
{row.requiredDeliveryDate
? dayjs(row.requiredDeliveryDate).format("YYYY-MM-DD")
: "-"}
</TableCell>
<TableCell>{row.shopName ?? row.shopCode ?? "-"}</TableCell>
<TableCell>{row.truckLanceCode ?? "-"}</TableCell>
<TableCell sx={{ whiteSpace: "pre-line" }}>
{(row.deliveryOrderCodes ?? []).join("\n") || "-"}
</TableCell>
<TableCell align="right">
<Button
variant="outlined"
size="small"
disabled={isAssigning}
onClick={() => handleSelectRow(row)}
>
{t("Select")}
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}

{!loading && list.length === 0 && (
<Typography color="text.secondary" sx={{ py: 3, textAlign: "center" }}>
{t("No entries available")}
</Typography>
)}

<Box sx={{ mt: 2, display: "flex", justifyContent: "flex-end" }}>
<Button onClick={onClose} variant="outlined">
{t("Close")}
</Button>
</Box>
</Box>
</Modal>
);
};

export default ReleasedDoPickOrderSelectModal;

Ładowanie…
Anuluj
Zapisz