"use client"; import React from "react"; import { X, Save } from "@mui/icons-material"; import { useTranslation } from "react-i18next"; import { useState } from "react"; import { Dialog, DialogTitle, DialogContent, DialogActions, IconButton, Typography, TextField, Stack, Box, Button, } from "@mui/material"; import { useForm, Controller } from "react-hook-form"; import { Material, FormData, ProductionRecord, ProcessData } from "./types"; import { Operator, Machine } from "@/app/api/jo"; import OperatorScanner from "./OperatorScanner"; import MachineScanner from "./MachineScanner"; import MaterialLotScanner from "./MaterialLotScanner"; import dayjs from 'dayjs'; import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; interface ProductionRecordingModalProps { isOpen: boolean; onClose: () => void; jobProcess: ProcessData; onDataRecorded?: (processId: string, data: any) => void; } const ProductionRecordingModal: React.FC = ({ isOpen, onClose, jobProcess, }) => { const { t } = useTranslation("common"); const { control, handleSubmit, reset, watch, setValue, setError, clearErrors, formState: { errors }, } = useForm({ defaultValues: { productionDate: dayjs().format(INPUT_DATE_FORMAT), notes: "", operators: [], machines: [], materials: jobProcess.materials || [], }, }); const watchedOperators = watch("operators"); const watchedMachines = watch("machines"); const watchedMaterials = watch("materials"); const [activeScannerType, setActiveScannerType] = useState<'operator' | 'machine' | 'material' | null>(null); const handleScannerActivate = (scannerType: 'operator' | 'machine' | 'material') => { setActiveScannerType(scannerType); }; const handleScannerDeactivate = () => { setActiveScannerType(null); }; const validateForm = (): boolean => { let isValid = true; // Clear previous errors clearErrors(); // Validate operators if (!watchedOperators || watchedOperators.length === 0) { setError("operators", { type: "required", message: "At least one operator is required", }); isValid = false; } // Validate machines if (!watchedMachines || watchedMachines.length === 0) { setError("machines", { type: "required", message: "At least one machine is required", }); isValid = false; } // Validate materials console.log(watchedMaterials); if (watchedMaterials) { const missingLotNumbers = watchedMaterials.filter( (m) => m.required && m.isUsed && (!m.lotNumbers || m.lotNumbers.length === 0), ).length; if (missingLotNumbers > 0) { setError("materials", { type: "custom", message: `${missingLotNumbers} required material(s) missing lot numbers`, }); isValid = false; } } return isValid; }; const onSubmit = (data: FormData) => { if (!validateForm()) { return; } const usedMaterials = data.materials .filter((material) => material.isUsed) .map((material) => ({ id: material.id, name: material.name, lotNumbers: material.lotNumbers, required: material.required, isUsed: false, })); const recordData: ProductionRecord = { ...data, materials: usedMaterials, timestamp: new Date().toISOString(), }; console.log("Production record saved:", recordData); handleClose(); }; const handleClose = (): void => { reset({ productionDate: dayjs().format(INPUT_DATE_FORMAT), notes: "", operators: [], machines: [], materials: jobProcess.materials.map((material) => ({ ...material, isUsed: false, lotNumbers: [], })), }); onClose(); }; const getUsedMaterialsCount = (): number => watchedMaterials?.filter((m) => m.isUsed).length || 0; if (!isOpen) return null; return ( Production Recording {watchedOperators?.length || 0} operator(s),{" "} {watchedMachines?.length || 0} machine(s), {getUsedMaterialsCount()}{" "} materials {/* Basic Information */} ( )} /> {/* Operator Scanner */} { setValue("operators", operators); if (operators.length > 0) { clearErrors("operators"); } }} error={errors.operators?.message} isActive={activeScannerType === 'operator'} onActivate={() => handleScannerActivate('operator')} onDeactivate={handleScannerDeactivate} /> {/* Machine Scanner */} { setValue("machines", machines); if (machines.length > 0) { clearErrors("machines"); } }} error={errors.machines?.message} isActive={activeScannerType === 'machine'} onActivate={() => handleScannerActivate('machine')} onDeactivate={handleScannerDeactivate} /> {/* Material Lot Scanner */} { setValue("materials", materials); clearErrors("materials"); }} error={errors.materials?.message} /> {/* Additional Notes */} ( )} /> ); }; export default ProductionRecordingModal;