| @@ -12,6 +12,7 @@ import { | |||||
| OnlinePrediction, FileDownload, SettingsEthernet | OnlinePrediction, FileDownload, SettingsEthernet | ||||
| } from "@mui/icons-material"; | } from "@mui/icons-material"; | ||||
| import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
| import { I18nProvider } from "@/i18n"; | |||||
| import { NEXT_PUBLIC_API_URL } from "@/config/api"; | import { NEXT_PUBLIC_API_URL } from "@/config/api"; | ||||
| export default function ProductionSchedulePage() { | 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 ( | return ( | ||||
| <Box sx={{ p: 4, bgcolor: '#fbfbfb', minHeight: '100vh' }}> | <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" justifyContent="space-between" alignItems="center" sx={{ mb: 3 }}> | ||||
| <Stack direction="row" spacing={2} alignItems="center"> | <Stack direction="row" spacing={2} alignItems="center"> | ||||
| <CalendarMonth color="primary" sx={{ fontSize: 32 }} /> | <CalendarMonth color="primary" sx={{ fontSize: 32 }} /> | ||||
| <Typography variant="h4" sx={{ fontWeight: 'bold' }}>Production Planning</Typography> | |||||
| <Typography variant="h4" sx={{ fontWeight: 'bold' }}>排期</Typography> | |||||
| </Stack> | </Stack> | ||||
| <Stack direction="row" spacing={2}> | <Stack direction="row" spacing={2}> | ||||
| @@ -44,7 +44,7 @@ export default function ReportPage() { | |||||
| .map(field => field.label); | .map(field => field.label); | ||||
| if (missingFields.length > 0) { | if (missingFields.length > 0) { | ||||
| alert(`Please enter the following mandatory fields:\n- ${missingFields.join('\n- ')}`); | |||||
| alert(`缺少必填條件:\n- ${missingFields.join('\n- ')}`); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -91,21 +91,21 @@ export default function ReportPage() { | |||||
| return ( | return ( | ||||
| <Box sx={{ p: 4, maxWidth: 1000, margin: '0 auto' }}> | <Box sx={{ p: 4, maxWidth: 1000, margin: '0 auto' }}> | ||||
| <Typography variant="h4" gutterBottom fontWeight="bold"> | <Typography variant="h4" gutterBottom fontWeight="bold"> | ||||
| Report Management | |||||
| 管理報告 | |||||
| </Typography> | </Typography> | ||||
| <Card sx={{ mb: 4, boxShadow: 3 }}> | <Card sx={{ mb: 4, boxShadow: 3 }}> | ||||
| <CardContent> | <CardContent> | ||||
| <Typography variant="h6" gutterBottom> | <Typography variant="h6" gutterBottom> | ||||
| Select Report Type | |||||
| 選擇報告 | |||||
| </Typography> | </Typography> | ||||
| <TextField | <TextField | ||||
| select | select | ||||
| fullWidth | fullWidth | ||||
| label="Report List" | |||||
| label="報告列表" | |||||
| value={selectedReportId} | value={selectedReportId} | ||||
| onChange={handleReportChange} | onChange={handleReportChange} | ||||
| helperText="Please select which report you want to generate" | |||||
| helperText="選擇報告" | |||||
| > | > | ||||
| {REPORTS.map((report) => ( | {REPORTS.map((report) => ( | ||||
| <MenuItem key={report.id} value={report.id}> | <MenuItem key={report.id} value={report.id}> | ||||
| @@ -120,7 +120,7 @@ export default function ReportPage() { | |||||
| <Card sx={{ boxShadow: 3, animation: 'fadeIn 0.5s' }}> | <Card sx={{ boxShadow: 3, animation: 'fadeIn 0.5s' }}> | ||||
| <CardContent> | <CardContent> | ||||
| <Typography variant="h6" color="primary" gutterBottom> | <Typography variant="h6" color="primary" gutterBottom> | ||||
| Search Criteria: {currentReport.title} | |||||
| 搜尋條件: {currentReport.title} | |||||
| </Typography> | </Typography> | ||||
| <Divider sx={{ mb: 3 }} /> | <Divider sx={{ mb: 3 }} /> | ||||
| @@ -156,7 +156,7 @@ export default function ReportPage() { | |||||
| disabled={loading} | disabled={loading} | ||||
| sx={{ px: 4 }} | sx={{ px: 4 }} | ||||
| > | > | ||||
| {loading ? "Generating..." : "Print Report"} | |||||
| {loading ? "生成報告..." : "列印報告"} | |||||
| </Button> | </Button> | ||||
| </Box> | </Box> | ||||
| </CardContent> | </CardContent> | ||||
| @@ -247,21 +247,14 @@ const NavigationContent: React.FC = () => { | |||||
| }, | }, | ||||
| { | { | ||||
| icon: <BugReportIcon />, | icon: <BugReportIcon />, | ||||
| label: "PS", | |||||
| path: "/ps", | |||||
| requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | |||||
| isHidden: false, | |||||
| }, | |||||
| { | |||||
| icon: <BugReportIcon />, | |||||
| label: "Printer Testing", | |||||
| label: "打袋機列印", | |||||
| path: "/testing", | path: "/testing", | ||||
| requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | ||||
| isHidden: false, | isHidden: false, | ||||
| }, | }, | ||||
| { | { | ||||
| icon: <BugReportIcon />, | icon: <BugReportIcon />, | ||||
| label: "Report Management", | |||||
| label: "管理報告", | |||||
| path: "/report", | path: "/report", | ||||
| requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | requiredAbility: [AUTH.TESTING, AUTH.ADMIN], | ||||
| isHidden: false, | isHidden: false, | ||||
| @@ -21,7 +21,7 @@ export interface ReportDefinition { | |||||
| export const REPORTS: ReportDefinition[] = [ | export const REPORTS: ReportDefinition[] = [ | ||||
| { | { | ||||
| id: "rep-001", | id: "rep-001", | ||||
| title: "Report 1", | |||||
| title: "報告 1", | |||||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report1`, | apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report1`, | ||||
| fields: [ | fields: [ | ||||
| { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory | { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory | ||||
| @@ -36,7 +36,7 @@ export const REPORTS: ReportDefinition[] = [ | |||||
| }, | }, | ||||
| { | { | ||||
| id: "rep-002", | id: "rep-002", | ||||
| title: "Report 2", | |||||
| title: "報告 2", | |||||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report2`, | apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report2`, | ||||
| fields: [ | fields: [ | ||||
| { label: "Target Date", name: "targetDate", type: "date", required: false }, | { label: "Target Date", name: "targetDate", type: "date", required: false }, | ||||
| @@ -49,7 +49,7 @@ export const REPORTS: ReportDefinition[] = [ | |||||
| }, | }, | ||||
| { | { | ||||
| id: "rep-003", | id: "rep-003", | ||||
| title: "Report 3", | |||||
| title: "報告 3", | |||||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report3`, | apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report3`, | ||||
| fields: [ | fields: [ | ||||
| { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory | { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory | ||||
| @@ -64,14 +64,14 @@ export const REPORTS: ReportDefinition[] = [ | |||||
| }, | }, | ||||
| { | { | ||||
| id: "rep-004", | id: "rep-004", | ||||
| title: "Stock In Traceability Report", | |||||
| title: "入倉記錄報告", | |||||
| apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-in-traceability`, | apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-in-traceability`, | ||||
| fields: [ | 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... | // Add more reports following the same pattern... | ||||