"use client"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Autocomplete, 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 { saveQcCategoryQcItemMapping, deleteQcCategoryQcItemMapping, getQcCategoryQcItemMappings, fetchQcCategoriesForAll, fetchQcItemsForAll, } from "@/app/api/settings/qcItemAll/actions"; import { QcCategoryResult, QcItemResult, } from "@/app/api/settings/qcItemAll"; import { QcItemInfo } from "@/app/api/settings/qcItemAll"; import { deleteDialog, errorDialogWithContent, submitDialog, successDialog, } from "../Swal/CustomAlerts"; type SearchQuery = Partial>; type SearchParamNames = keyof SearchQuery; const Tab1QcCategoryQcItemMapping: 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 [qcItems, setQcItems] = useState([]); const [selectedQcItem, setSelectedQcItem] = useState(null); const [order, setOrder] = useState(0); 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("Error loading data:", error); setQcCategories([]); // Ensure it's always an array setFilteredQcCategories([]); } finally { setLoading(false); } }; loadData(); }, []); const handleViewMappings = useCallback(async (category: QcCategoryResult) => { setSelectedCategory(category); // Load mappings when user clicks View (lazy loading) const mappingData = await getQcCategoryQcItemMappings(category.id); setMappings(mappingData); setOpenDialog(true); }, []); const handleAddMapping = useCallback(async () => { if (!selectedCategory) return; // Load qc items list when opening add dialog try { const itemsData = await fetchQcItemsForAll(); setQcItems(itemsData); } catch (error) { console.error("Error loading qc items:", error); } setOpenAddDialog(true); setOrder(0); setSelectedQcItem(null); }, [selectedCategory]); const handleSaveMapping = useCallback(async () => { if (!selectedCategory || !selectedQcItem) return; await submitDialog(async () => { try { await saveQcCategoryQcItemMapping( selectedCategory.id, selectedQcItem.id, order, undefined // No description needed - qcItem already has description ); // Close add dialog first setOpenAddDialog(false); setSelectedQcItem(null); setOrder(0); // Reload mappings to update the view const mappingData = await getQcCategoryQcItemMappings(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, selectedQcItem, order, t]); const handleDeleteMapping = useCallback( async (mappingId: number) => { if (!selectedCategory) return; deleteDialog(async () => { try { await deleteQcCategoryQcItemMapping(mappingId); await successDialog(t("Delete Success"), t); // Reload mappings const mappingData = await getQcCategoryQcItemMappings(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 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] ); 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("Association Details")} - {selectedCategory?.name} {t("Order")} {t("Qc Item Code")} {t("Qc Item Name")} {t("Description")} {t("Actions")} {mappings.length === 0 ? ( {t("No associations found")} ) : ( mappings.map((mapping) => ( {mapping.order} {mapping.code} {mapping.name} {mapping.description || "-"} handleDeleteMapping(mapping.id)} > )) )}
{/* Add Mapping Dialog */} setOpenAddDialog(false)} maxWidth="sm" fullWidth> {t("Add Association")} `${option.code} - ${option.name}`} value={selectedQcItem} onChange={(_, newValue) => setSelectedQcItem(newValue)} renderInput={(params) => ( )} /> setOrder(parseInt(e.target.value) || 0)} fullWidth />
); }; export default Tab1QcCategoryQcItemMapping;