|
|
|
@@ -0,0 +1,128 @@ |
|
|
|
"use client"; |
|
|
|
|
|
|
|
import { useEffect, useState } from "react"; |
|
|
|
import { Box, Button, MenuItem, Stack, TextField, Typography } from "@mui/material"; |
|
|
|
import DownloadIcon from "@mui/icons-material/Download"; |
|
|
|
import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; |
|
|
|
import { NEXT_PUBLIC_API_URL } from "@/config/api"; |
|
|
|
import { fetchTruckRoutingLaneOptions, fetchTruckRoutingStoreOptions, ReportOption } from "@/app/(main)/report/truckRoutingSummaryApi"; |
|
|
|
|
|
|
|
const TruckRoutingSummaryTab: React.FC = () => { |
|
|
|
const [storeOptions, setStoreOptions] = useState<ReportOption[]>([]); |
|
|
|
const [laneOptions, setLaneOptions] = useState<ReportOption[]>([]); |
|
|
|
const [storeId, setStoreId] = useState(""); |
|
|
|
const [truckLanceCode, setTruckLanceCode] = useState(""); |
|
|
|
const [date, setDate] = useState(""); |
|
|
|
const [loading, setLoading] = useState(false); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
fetchTruckRoutingStoreOptions() |
|
|
|
.then(setStoreOptions) |
|
|
|
.catch((err) => console.error("Failed to load store options", err)); |
|
|
|
}, []); |
|
|
|
|
|
|
|
const onStoreChange = async (value: string) => { |
|
|
|
setStoreId(value); |
|
|
|
setTruckLanceCode(""); |
|
|
|
try { |
|
|
|
const lanes = await fetchTruckRoutingLaneOptions(value); |
|
|
|
setLaneOptions(lanes); |
|
|
|
} catch (error) { |
|
|
|
console.error("Failed to load lane options", error); |
|
|
|
setLaneOptions([]); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const canDownload = storeId && truckLanceCode && date && !loading; |
|
|
|
|
|
|
|
const onDownload = async () => { |
|
|
|
if (!canDownload) return; |
|
|
|
setLoading(true); |
|
|
|
try { |
|
|
|
const qs = new URLSearchParams({ |
|
|
|
storeId, |
|
|
|
truckLanceCode, |
|
|
|
date, |
|
|
|
}).toString(); |
|
|
|
const url = `${NEXT_PUBLIC_API_URL}/truck-routing-summary/print?${qs}`; |
|
|
|
const response = await clientAuthFetch(url, { |
|
|
|
method: "GET", |
|
|
|
headers: { Accept: "application/pdf" }, |
|
|
|
}); |
|
|
|
if (!response.ok) { |
|
|
|
const errorText = await response.text(); |
|
|
|
throw new Error(`HTTP ${response.status}: ${errorText}`); |
|
|
|
} |
|
|
|
|
|
|
|
const blob = await response.blob(); |
|
|
|
const downloadUrl = window.URL.createObjectURL(blob); |
|
|
|
const link = document.createElement("a"); |
|
|
|
link.href = downloadUrl; |
|
|
|
link.setAttribute("download", "TruckRoutingSummary.pdf"); |
|
|
|
document.body.appendChild(link); |
|
|
|
link.click(); |
|
|
|
link.remove(); |
|
|
|
window.URL.revokeObjectURL(downloadUrl); |
|
|
|
} catch (error) { |
|
|
|
console.error("Failed to download Truck Routing Summary", error); |
|
|
|
alert("下載送貨路線摘要失敗,請稍後再試。"); |
|
|
|
} finally { |
|
|
|
setLoading(false); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
return ( |
|
|
|
<Box sx={{ maxWidth: 820 }}> |
|
|
|
<Typography variant="h6" sx={{ mb: 2 }}> |
|
|
|
送貨路線摘要 |
|
|
|
</Typography> |
|
|
|
<Stack direction={{ xs: "column", md: "row" }} spacing={2} sx={{ mb: 2 }}> |
|
|
|
<TextField |
|
|
|
select |
|
|
|
fullWidth |
|
|
|
label="2/F 或 4/F" |
|
|
|
value={storeId} |
|
|
|
onChange={(e) => onStoreChange(e.target.value)} |
|
|
|
> |
|
|
|
{storeOptions.map((opt) => ( |
|
|
|
<MenuItem key={opt.value} value={opt.value}> |
|
|
|
{opt.label} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</TextField> |
|
|
|
<TextField |
|
|
|
select |
|
|
|
fullWidth |
|
|
|
label="車線" |
|
|
|
value={truckLanceCode} |
|
|
|
onChange={(e) => setTruckLanceCode(e.target.value)} |
|
|
|
disabled={!storeId} |
|
|
|
> |
|
|
|
{laneOptions.map((opt) => ( |
|
|
|
<MenuItem key={opt.value} value={opt.value}> |
|
|
|
{opt.label} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</TextField> |
|
|
|
<TextField |
|
|
|
fullWidth |
|
|
|
label="日期" |
|
|
|
type="date" |
|
|
|
value={date} |
|
|
|
InputLabelProps={{ shrink: true }} |
|
|
|
onChange={(e) => setDate(e.target.value)} |
|
|
|
/> |
|
|
|
</Stack> |
|
|
|
<Button |
|
|
|
variant="contained" |
|
|
|
startIcon={<DownloadIcon />} |
|
|
|
disabled={!canDownload} |
|
|
|
onClick={onDownload} |
|
|
|
> |
|
|
|
{loading ? "生成中..." : "下載報告 (PDF)"} |
|
|
|
</Button> |
|
|
|
</Box> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
export default TruckRoutingSummaryTab; |