"use client"; import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Stack, TextField, Typography, CircularProgress, IconButton, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, } from "@mui/material"; import Delete from "@mui/icons-material/Delete"; import Add from "@mui/icons-material/Add"; import { useTranslation } from "react-i18next"; import { Edit } from "@mui/icons-material"; import SearchBox, { Criterion } from "@/components/SearchBox/SearchBox"; import SearchResults, { Column } from "@/components/SearchResults/SearchResults"; import { fetchStockTakeSections, updateSectionDescription, clearWarehouseSection, getWarehousesBySection, searchWarehousesForAddToSection, editWarehouse, } from "@/app/api/warehouse/actions"; import { WarehouseResult } from "@/app/api/warehouse"; import { StockTakeSectionInfo } from "@/app/api/warehouse"; import { deleteDialog, successDialog } from "@/components/Swal/CustomAlerts"; type SearchKey = "stockTakeSection" | "stockTakeSectionDescription"; export default function TabStockTakeSectionMapping() { const { t } = useTranslation(["warehouse", "common"]); const [sections, setSections] = useState([]); const [filteredSections, setFilteredSections] = useState([]); const [selectedSection, setSelectedSection] = useState(null); const [warehousesInSection, setWarehousesInSection] = useState([]); const [loading, setLoading] = useState(true); const [openDialog, setOpenDialog] = useState(false); const [editDesc, setEditDesc] = useState(""); const [savingDesc, setSavingDesc] = useState(false); const [warehouseList, setWarehouseList] = useState([]); const [openAddDialog, setOpenAddDialog] = useState(false); const [addStoreId, setAddStoreId] = useState(""); const [addWarehouse, setAddWarehouse] = useState(""); const [addArea, setAddArea] = useState(""); const [addSlot, setAddSlot] = useState(""); const [addSearchResults, setAddSearchResults] = useState([]); const [addSearching, setAddSearching] = useState(false); const [addingWarehouseId, setAddingWarehouseId] = useState(null); const loadSections = useCallback(async () => { setLoading(true); try { const data = await fetchStockTakeSections(); const withId = (data ?? []).map((s) => ({ ...s, id: s.stockTakeSection, })); setSections(withId); setFilteredSections(withId); } catch (e) { console.error(e); setSections([]); setFilteredSections([]); } finally { setLoading(false); } }, []); useEffect(() => { loadSections(); }, [loadSections]); const handleViewSection = useCallback(async (section: StockTakeSectionInfo) => { setSelectedSection(section); setEditDesc(section.stockTakeSectionDescription ?? ""); setOpenDialog(true); try { const list = await getWarehousesBySection(section.stockTakeSection); setWarehousesInSection(list ?? []); } catch (e) { console.error(e); setWarehousesInSection([]); } }, []); const criteria: Criterion[] = useMemo( () => [ { type: "text", label: "Stock Take Section", paramName: "stockTakeSection", placeholder: "" }, { type: "text", label: "Stock Take Section Description", paramName: "stockTakeSectionDescription", placeholder: "" }, ], [] ); const handleSearch = useCallback((inputs: Record) => { const section = (inputs.stockTakeSection ?? "").trim().toLowerCase(); const desc = (inputs.stockTakeSectionDescription ?? "").trim().toLowerCase(); setFilteredSections( sections.filter( (s) => (!section || (s.stockTakeSection ?? "").toLowerCase().includes(section)) && (!desc || (s.stockTakeSectionDescription ?? "").toLowerCase().includes(desc)) ) ); }, [sections]); const handleReset = useCallback(() => { setFilteredSections(sections); }, [sections]); const handleSaveDescription = useCallback(async () => { if (!selectedSection) return; setSavingDesc(true); try { await updateSectionDescription(selectedSection.stockTakeSection, editDesc || null); await loadSections(); if (selectedSection) { setSelectedSection((prev) => (prev ? { ...prev, stockTakeSectionDescription: editDesc || null } : null)); } successDialog(t("Saved"), t); } catch (e) { console.error(e); } finally { setSavingDesc(false); } }, [selectedSection, editDesc, loadSections, t]); const handleRemoveWarehouse = useCallback( (warehouse: WarehouseResult) => { deleteDialog(async () => { try { await clearWarehouseSection(warehouse.id); setWarehousesInSection((prev) => prev.filter((w) => w.id !== warehouse.id)); successDialog(t("Delete Success"), t); } catch (e) { console.error(e); } }, t); }, [t] ); const handleOpenAddWarehouse = useCallback(() => { setAddStoreId(""); setAddWarehouse(""); setAddArea(""); setAddSlot(""); setAddSearchResults([]); setOpenAddDialog(true); }, []); const handleAddSearch = useCallback(async () => { if (!selectedSection) return; setAddSearching(true); try { const params: { store_id?: string; warehouse?: string; area?: string; slot?: string } = {}; if (addStoreId.trim()) params.store_id = addStoreId.trim(); if (addWarehouse.trim()) params.warehouse = addWarehouse.trim(); if (addArea.trim()) params.area = addArea.trim(); if (addSlot.trim()) params.slot = addSlot.trim(); const list = await searchWarehousesForAddToSection(params, selectedSection.stockTakeSection); setAddSearchResults(list ?? []); } catch (e) { console.error(e); setAddSearchResults([]); } finally { setAddSearching(false); } }, [selectedSection, addStoreId, addWarehouse, addArea, addSlot]); const handleAddWarehouseToSection = useCallback( async (w: WarehouseResult) => { if (!selectedSection) return; setAddingWarehouseId(w.id); try { await editWarehouse(w.id, { stockTakeSection: selectedSection.stockTakeSection, stockTakeSectionDescription: selectedSection.stockTakeSectionDescription ?? undefined, }); setWarehousesInSection((prev) => [...prev, w]); setAddSearchResults((prev) => prev.filter((x) => x.id !== w.id)); successDialog(t("Add Success") ?? t("Saved"), t); } catch (e) { console.error(e); } finally { setAddingWarehouseId(null); } }, [selectedSection, t] ); const columns = useMemo[]>( () => [ { name: "stockTakeSection", label: t("stockTakeSection"), align: "left", sx: { width: "25%" } }, { name: "stockTakeSectionDescription", label: t("stockTakeSectionDescription"), align: "left", sx: { width: "35%" } }, { name: "id", label: t("Edit"), onClick: (row) => handleViewSection(row), buttonIcon: , buttonIcons: {} as Record, color: "primary", sx: { width: "20%" }, }, ], [t, handleViewSection] ); if (loading) { return ( ); } return ( criteria={criteria} onSearch={handleSearch} onReset={handleReset} /> items={filteredSections} columns={columns} /> setOpenDialog(false)} maxWidth="md" fullWidth sx={{ zIndex: 1000 }}> {t("Mapping Details")} - {selectedSection?.stockTakeSection} ({selectedSection?.stockTakeSectionDescription ?? ""}) {t("stockTakeSectionDescription")} setEditDesc(e.target.value)} sx={{ minWidth: 200 }} /> {t("code")} {t("Actions")} {warehousesInSection.length === 0 ? ( {t("No warehouses")} ) : ( warehousesInSection.map((w) => ( {w.code} handleRemoveWarehouse(w)}> )) )}
setOpenAddDialog(false)} maxWidth="sm" fullWidth sx={{ zIndex: 1000 }}> {t("Add Warehouse")} setAddStoreId(e.target.value)} fullWidth /> setAddWarehouse(e.target.value)} fullWidth /> setAddArea(e.target.value)} fullWidth /> setAddSlot(e.target.value)} fullWidth /> {t("code")} {t("name")} {t("Actions")} {addSearchResults .filter((w) => !warehousesInSection.some((inc) => inc.id === w.id)) .map((w) => ( {w.code} {w.name} ))}
); }