| @@ -12,6 +12,7 @@ import { | |||
| OnlinePrediction, FileDownload, SettingsEthernet | |||
| } from "@mui/icons-material"; | |||
| import dayjs from "dayjs"; | |||
| import { I18nProvider } from "@/i18n"; | |||
| import { NEXT_PUBLIC_API_URL } from "@/config/api"; | |||
| export default function ProductionSchedulePage() { | |||
| @@ -217,7 +218,32 @@ export default function ProductionSchedulePage() { | |||
| }; | |||
| const handleAutoGenJob = async () => { /* unchanged */ }; | |||
| const handleAutoGenJob = async () => { | |||
| if (!isDateToday) return; | |||
| const token = localStorage.getItem("accessToken"); | |||
| setIsGenerating(true); | |||
| try { | |||
| const response = await fetch(`${NEXT_PUBLIC_API_URL}/productionSchedule/detail/detailed/release`, { | |||
| method: 'POST', | |||
| headers: { | |||
| 'Authorization': `Bearer ${token}`, | |||
| 'Content-Type': 'application/json' | |||
| }, | |||
| body: JSON.stringify({ id: selectedPs.id }) | |||
| }); | |||
| if (response.ok) { | |||
| alert("Job Orders generated successfully!"); | |||
| setIsDetailOpen(false); | |||
| } else { | |||
| alert("Failed to generate jobs."); | |||
| } | |||
| } catch (e) { | |||
| console.error("Release Error:", e); | |||
| } finally { | |||
| setIsGenerating(false); | |||
| } | |||
| }; | |||
| return ( | |||
| <Box sx={{ p: 4, bgcolor: '#fbfbfb', minHeight: '100vh' }}> | |||
| @@ -226,7 +252,7 @@ export default function ProductionSchedulePage() { | |||
| <Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 3 }}> | |||
| <Stack direction="row" spacing={2} alignItems="center"> | |||
| <CalendarMonth color="primary" sx={{ fontSize: 32 }} /> | |||
| <Typography variant="h4" sx={{ fontWeight: 'bold' }}>Production Planning</Typography> | |||
| <Typography variant="h4" sx={{ fontWeight: 'bold' }}>排期</Typography> | |||
| </Stack> | |||
| <Stack direction="row" spacing={2}> | |||
| @@ -44,7 +44,7 @@ export default function ReportPage() { | |||
| .map(field => field.label); | |||
| if (missingFields.length > 0) { | |||
| alert(`Please enter the following mandatory fields:\n- ${missingFields.join('\n- ')}`); | |||
| alert(`缺少必填條件:\n- ${missingFields.join('\n- ')}`); | |||
| return; | |||
| } | |||
| @@ -91,21 +91,21 @@ export default function ReportPage() { | |||
| return ( | |||
| <Box sx={{ p: 4, maxWidth: 1000, margin: '0 auto' }}> | |||
| <Typography variant="h4" gutterBottom fontWeight="bold"> | |||
| Report Management | |||
| 管理報告 | |||
| </Typography> | |||
| <Card sx={{ mb: 4, boxShadow: 3 }}> | |||
| <CardContent> | |||
| <Typography variant="h6" gutterBottom> | |||
| Select Report Type | |||
| 選擇報告 | |||
| </Typography> | |||
| <TextField | |||
| select | |||
| fullWidth | |||
| label="Report List" | |||
| label="報告列表" | |||
| value={selectedReportId} | |||
| onChange={handleReportChange} | |||
| helperText="Please select which report you want to generate" | |||
| helperText="選擇報告" | |||
| > | |||
| {REPORTS.map((report) => ( | |||
| <MenuItem key={report.id} value={report.id}> | |||
| @@ -120,7 +120,7 @@ export default function ReportPage() { | |||
| <Card sx={{ boxShadow: 3, animation: 'fadeIn 0.5s' }}> | |||
| <CardContent> | |||
| <Typography variant="h6" color="primary" gutterBottom> | |||
| Search Criteria: {currentReport.title} | |||
| 搜尋條件: {currentReport.title} | |||
| </Typography> | |||
| <Divider sx={{ mb: 3 }} /> | |||
| @@ -156,7 +156,7 @@ export default function ReportPage() { | |||
| disabled={loading} | |||
| sx={{ px: 4 }} | |||
| > | |||
| {loading ? "Generating..." : "Print Report"} | |||
| {loading ? "生成報告..." : "列印報告"} | |||
| </Button> | |||
| </Box> | |||
| </CardContent> | |||
| @@ -247,21 +247,14 @@ const NavigationContent: React.FC = () => { | |||
| }, | |||
| { | |||
| icon: <BugReportIcon />, | |||
| label: "PS", | |||
| path: "/ps", | |||
| requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | |||
| isHidden: false, | |||
| }, | |||
| { | |||
| icon: <BugReportIcon />, | |||
| label: "Printer Testing", | |||
| label: "打袋機列印", | |||
| path: "/testing", | |||
| requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | |||
| isHidden: false, | |||
| }, | |||
| { | |||
| icon: <BugReportIcon />, | |||
| label: "Report Management", | |||
| label: "管理報告", | |||
| path: "/report", | |||
| requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | |||
| isHidden: false, | |||
| @@ -21,7 +21,7 @@ export interface ReportDefinition { | |||
| export const REPORTS: ReportDefinition[] = [ | |||
| { | |||
| id: "rep-001", | |||
| title: "Report 1", | |||
| title: "報告 1", | |||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report1`, | |||
| fields: [ | |||
| { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory | |||
| @@ -36,7 +36,7 @@ export const REPORTS: ReportDefinition[] = [ | |||
| }, | |||
| { | |||
| id: "rep-002", | |||
| title: "Report 2", | |||
| title: "報告 2", | |||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report2`, | |||
| fields: [ | |||
| { label: "Target Date", name: "targetDate", type: "date", required: false }, | |||
| @@ -49,7 +49,7 @@ export const REPORTS: ReportDefinition[] = [ | |||
| }, | |||
| { | |||
| id: "rep-003", | |||
| title: "Report 3", | |||
| title: "報告 3", | |||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report3`, | |||
| fields: [ | |||
| { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory | |||
| @@ -64,14 +64,14 @@ export const REPORTS: ReportDefinition[] = [ | |||
| }, | |||
| { | |||
| id: "rep-004", | |||
| title: "Stock In Traceability Report", | |||
| title: "入倉記錄報告", | |||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-in-traceability`, | |||
| fields: [ | |||
| { label: "Stock Category", name: "stockCategory", type: "text", required: false, placeholder: "e.g. Meat" }, | |||
| { label: "Stock Sub Category", name: "stockSubCategory", type: "text", required: false, placeholder: "e.g. Chicken" }, | |||
| { label: "Item Code", name: "itemCode", type: "text", required: false, placeholder: "e.g. MT-001" }, | |||
| { label: "Last In Date Start", name: "lastInDateStart", type: "date", required: false }, | |||
| { label: "Last In Date End", name: "lastInDateEnd", type: "date", required: false }, | |||
| { label: "倉存類別 Stock Category", name: "stockCategory", type: "text", required: false, placeholder: "e.g. Meat" }, | |||
| { label: "倉存細分類 Stock Sub Category", name: "stockSubCategory", type: "text", required: false, placeholder: "e.g. Chicken" }, | |||
| { label: "物料編號 Item Code", name: "itemCode", type: "text", required: false, placeholder: "e.g. MT-001" }, | |||
| { label: "入倉日期:由 Last In Date Start", name: "lastInDateStart", type: "date", required: false }, | |||
| { label: "入倉日期:至 Last In Date End", name: "lastInDateEnd", type: "date", required: false }, | |||
| ] | |||
| } | |||
| // Add more reports following the same pattern... | |||