"use client"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Typography, IconButton, CircularProgress, } from "@mui/material"; import { useTranslation } from "react-i18next"; import { Add, Delete, Edit } from "@mui/icons-material"; import SearchBox, { Criterion } from "../SearchBox/SearchBox"; import SearchResults, { Column } from "../SearchResults/SearchResults"; import { saveItemQcCategoryMapping, deleteItemQcCategoryMapping, getItemQcCategoryMappings, fetchQcCategoriesForAll, fetchItemsForAll, getItemByCode, } from "@/app/api/settings/qcItemAll/actions"; import { QcCategoryResult, ItemsResult, } from "@/app/api/settings/qcItemAll"; import { ItemQcCategoryMappingInfo } from "@/app/api/settings/qcItemAll"; import { deleteDialog, errorDialogWithContent, submitDialog, successDialog, } from "../Swal/CustomAlerts"; type SearchQuery = Partial>; type SearchParamNames = keyof SearchQuery; const Tab0ItemQcCategoryMapping: React.FC = () => { const { t } = useTranslation("qcItemAll"); const [qcCategories, setQcCategories] = useState([]); const [filteredQcCategories, setFilteredQcCategories] = useState([]); const [selectedCategory, setSelectedCategory] = useState(null); const [mappings, setMappings] = useState([]); const [openDialog, setOpenDialog] = useState(false); const [openAddDialog, setOpenAddDialog] = useState(false); const [itemCode, setItemCode] = useState(""); const [validatedItem, setValidatedItem] = useState(null); const [itemCodeError, setItemCodeError] = useState(""); const [validatingItemCode, setValidatingItemCode] = useState(false); const [selectedType, setSelectedType] = useState("IQC"); const [loading, setLoading] = useState(true); useEffect(() => { const loadData = async () => { setLoading(true); try { // Only load categories list (same as Tab 2) - fast! const categories = await fetchQcCategoriesForAll(); setQcCategories(categories || []); setFilteredQcCategories(categories || []); } catch (error) { console.error("Tab0: Error loading data:", error); setQcCategories([]); setFilteredQcCategories([]); if (error instanceof Error) { errorDialogWithContent(t("Error"), error.message, t); } } finally { setLoading(false); } }; loadData(); }, []); const handleViewMappings = useCallback(async (category: QcCategoryResult) => { setSelectedCategory(category); const mappingData = await getItemQcCategoryMappings(category.id); setMappings(mappingData); setOpenDialog(true); }, []); const handleAddMapping = useCallback(() => { if (!selectedCategory) return; setItemCode(""); setValidatedItem(null); setItemCodeError(""); setOpenAddDialog(true); }, [selectedCategory]); const handleItemCodeChange = useCallback(async (code: string) => { setItemCode(code); setValidatedItem(null); setItemCodeError(""); if (!code || code.trim() === "") { return; } setValidatingItemCode(true); try { const item = await getItemByCode(code.trim()); if (item) { setValidatedItem(item); setItemCodeError(""); } else { setValidatedItem(null); setItemCodeError(t("Item code not found")); } } catch (error) { setValidatedItem(null); setItemCodeError(t("Error validating item code")); } finally { setValidatingItemCode(false); } }, [t]); const handleSaveMapping = useCallback(async () => { if (!selectedCategory || !validatedItem) return; await submitDialog(async () => { try { await saveItemQcCategoryMapping( validatedItem.id as number, selectedCategory.id, selectedType ); // Close add dialog first setOpenAddDialog(false); setItemCode(""); setValidatedItem(null); setItemCodeError(""); // Reload mappings to update the view const mappingData = await getItemQcCategoryMappings(selectedCategory.id); setMappings(mappingData); // Show success message after closing dialogs await successDialog(t("Submit Success"), t); // Keep the view dialog open to show updated data } catch (error) { errorDialogWithContent(t("Submit Error"), String(error), t); } }, t); }, [selectedCategory, validatedItem, selectedType, t]); const handleDeleteMapping = useCallback( async (mappingId: number) => { if (!selectedCategory) return; deleteDialog(async () => { try { await deleteItemQcCategoryMapping(mappingId); await successDialog(t("Delete Success"), t); // Reload mappings const mappingData = await getItemQcCategoryMappings(selectedCategory.id); setMappings(mappingData); // No need to reload categories list - it doesn't change } catch (error) { errorDialogWithContent(t("Delete Error"), String(error), t); } }, t); }, [selectedCategory, t] ); const typeOptions = ["IQC", "IPQC", "OQC", "FQC"]; const searchCriteria: Criterion[] = useMemo( () => [ { label: t("Code"), paramName: "code", type: "text" }, { label: t("Name"), paramName: "name", type: "text" }, ], [t] ); const onReset = useCallback(() => { setFilteredQcCategories(qcCategories); }, [qcCategories]); const columnWidthSx = (width = "10%") => { return { width: width, whiteSpace: "nowrap" }; }; const columns = useMemo[]>( () => [ { name: "code", label: t("Qc Category Code"), sx: columnWidthSx("20%") }, { name: "name", label: t("Qc Category Name"), sx: columnWidthSx("40%") }, { name: "id", label: t("Actions"), onClick: (category) => handleViewMappings(category), buttonIcon: , buttonIcons: {} as any, sx: columnWidthSx("10%"), }, ], [t, handleViewMappings] ); if (loading) { return ( ); } return ( { setFilteredQcCategories( qcCategories.filter( (qc) => (!query.code || qc.code.toLowerCase().includes(query.code.toLowerCase())) && (!query.name || qc.name.toLowerCase().includes(query.name.toLowerCase())) ) ); }} onReset={onReset} /> items={filteredQcCategories} columns={columns} /> {/* View Mappings Dialog */} setOpenDialog(false)} maxWidth="md" fullWidth> {t("Mapping Details")} - {selectedCategory?.name} {t("Item Code")} {t("Item Name")} {t("Type")} {t("Actions")} {mappings.length === 0 ? ( {t("No mappings found")} ) : ( mappings.map((mapping) => ( {mapping.itemCode} {mapping.itemName} {mapping.type} handleDeleteMapping(mapping.id)} > )) )}
{/* Add Mapping Dialog */} setOpenAddDialog(false)} maxWidth="sm" fullWidth> {t("Add Mapping")} handleItemCodeChange(e.target.value)} error={!!itemCodeError} helperText={itemCodeError || (validatedItem ? `${validatedItem.code} - ${validatedItem.name}` : t("Enter item code to validate"))} fullWidth disabled={validatingItemCode} InputProps={{ endAdornment: validatingItemCode ? : null, }} /> setSelectedType(e.target.value)} SelectProps={{ native: true, }} fullWidth > {typeOptions.map((type) => ( ))}
); }; export default Tab0ItemQcCategoryMapping;