"use client"; import { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import SearchResults, { Column } from "../SearchResults/index"; import DeleteIcon from "@mui/icons-material/Delete"; import { useRouter } from "next/navigation"; import { deleteDialog, successDialog } from "../Swal/CustomAlerts"; import { WarehouseResult } from "@/app/api/warehouse"; import { deleteWarehouse } from "@/app/api/warehouse/actions"; import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; import CardActions from "@mui/material/CardActions"; import Typography from "@mui/material/Typography"; import TextField from "@mui/material/TextField"; import Button from "@mui/material/Button"; import Box from "@mui/material/Box"; import RestartAlt from "@mui/icons-material/RestartAlt"; import Search from "@mui/icons-material/Search"; import InputAdornment from "@mui/material/InputAdornment"; interface Props { warehouses: WarehouseResult[]; } type SearchQuery = Partial>; type SearchParamNames = keyof SearchQuery; const WarehouseHandle: React.FC = ({ warehouses }) => { const { t } = useTranslation(["warehouse", "common"]); const [filteredWarehouse, setFilteredWarehouse] = useState(warehouses); const [pagingController, setPagingController] = useState({ pageNum: 1, pageSize: 10, }); const router = useRouter(); const [isSearching, setIsSearching] = useState(false); const [searchInputs, setSearchInputs] = useState({ store_id: "", warehouse: "", area: "", slot: "", stockTakeSection: "", }); const onDeleteClick = useCallback((warehouse: WarehouseResult) => { deleteDialog(async () => { try { await deleteWarehouse(warehouse.id); setFilteredWarehouse(prev => prev.filter(w => w.id !== warehouse.id)); router.refresh(); successDialog(t("Delete Success"), t); } catch (error) { console.error("Failed to delete warehouse:", error); // Don't redirect on error, just show error message // The error will be logged but user stays on the page } }, t); }, [t, router]); const handleReset = useCallback(() => { setSearchInputs({ store_id: "", warehouse: "", area: "", slot: "", stockTakeSection: "", }); setFilteredWarehouse(warehouses); setPagingController({ pageNum: 1, pageSize: pagingController.pageSize }); }, [warehouses, pagingController.pageSize]); const handleSearch = useCallback(() => { setIsSearching(true); try { let results: WarehouseResult[] = warehouses; // Build search pattern from the four fields: store_idF-warehouse-area-slot // Only search by code field - match the code that follows this pattern const storeId = searchInputs.store_id?.trim() || ""; const warehouse = searchInputs.warehouse?.trim() || ""; const area = searchInputs.area?.trim() || ""; const slot = searchInputs.slot?.trim() || ""; const stockTakeSection = searchInputs.stockTakeSection?.trim() || ""; // If any field has a value, filter by code pattern and stockTakeSection if (storeId || warehouse || area || slot || stockTakeSection) { results = warehouses.filter((warehouseItem) => { // Filter by stockTakeSection if provided if (stockTakeSection) { const itemStockTakeSection = String(warehouseItem.stockTakeSection || "").toLowerCase(); if (!itemStockTakeSection.includes(stockTakeSection.toLowerCase())) { return false; } } // Filter by code pattern if any code-related field is provided if (storeId || warehouse || area || slot) { if (!warehouseItem.code) { return false; } const codeValue = String(warehouseItem.code).toLowerCase(); // Check if code matches the pattern: store_id-warehouse-area-slot // Match each part if provided const codeParts = codeValue.split("-"); if (codeParts.length >= 4) { const codeStoreId = codeParts[0] || ""; const codeWarehouse = codeParts[1] || ""; const codeArea = codeParts[2] || ""; const codeSlot = codeParts[3] || ""; const storeIdMatch = !storeId || codeStoreId.includes(storeId.toLowerCase()); const warehouseMatch = !warehouse || codeWarehouse.includes(warehouse.toLowerCase()); const areaMatch = !area || codeArea.includes(area.toLowerCase()); const slotMatch = !slot || codeSlot.includes(slot.toLowerCase()); return storeIdMatch && warehouseMatch && areaMatch && slotMatch; } // Fallback: if code doesn't follow the pattern, check if it contains any of the search terms const storeIdMatch = !storeId || codeValue.includes(storeId.toLowerCase()); const warehouseMatch = !warehouse || codeValue.includes(warehouse.toLowerCase()); const areaMatch = !area || codeValue.includes(area.toLowerCase()); const slotMatch = !slot || codeValue.includes(slot.toLowerCase()); return storeIdMatch && warehouseMatch && areaMatch && slotMatch; } // If only stockTakeSection is provided, return true (already filtered above) return true; }); } else { // If no search terms, show all warehouses results = warehouses; } setFilteredWarehouse(results); setPagingController({ pageNum: 1, pageSize: pagingController.pageSize }); } catch (error) { console.error("Error searching warehouses:", error); // Fallback: filter by code pattern and stockTakeSection const storeId = searchInputs.store_id?.trim().toLowerCase() || ""; const warehouse = searchInputs.warehouse?.trim().toLowerCase() || ""; const area = searchInputs.area?.trim().toLowerCase() || ""; const slot = searchInputs.slot?.trim().toLowerCase() || ""; const stockTakeSection = searchInputs.stockTakeSection?.trim().toLowerCase() || ""; setFilteredWarehouse( warehouses.filter((warehouseItem) => { // Filter by stockTakeSection if provided if (stockTakeSection) { const itemStockTakeSection = String(warehouseItem.stockTakeSection || "").toLowerCase(); if (!itemStockTakeSection.includes(stockTakeSection)) { return false; } } // Filter by code if any code-related field is provided if (storeId || warehouse || area || slot) { if (!warehouseItem.code) { return false; } const codeValue = String(warehouseItem.code).toLowerCase(); const codeParts = codeValue.split("-"); if (codeParts.length >= 4) { const storeIdMatch = !storeId || codeParts[0].includes(storeId); const warehouseMatch = !warehouse || codeParts[1].includes(warehouse); const areaMatch = !area || codeParts[2].includes(area); const slotMatch = !slot || codeParts[3].includes(slot); return storeIdMatch && warehouseMatch && areaMatch && slotMatch; } return (!storeId || codeValue.includes(storeId)) && (!warehouse || codeValue.includes(warehouse)) && (!area || codeValue.includes(area)) && (!slot || codeValue.includes(slot)); } return true; }) ); } finally { setIsSearching(false); } }, [searchInputs, warehouses, pagingController.pageSize]); const columns = useMemo[]>( () => [ { name: "code", label: t("code"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "store_id", label: t("store_id"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "warehouse", label: t("warehouse"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "area", label: t("area"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "slot", label: t("slot"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "order", label: t("order"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "stockTakeSection", label: t("stockTakeSection"), align: "left", headerAlign: "left", sx: { width: "15%", minWidth: "120px" }, }, { name: "action", label: t("Delete"), onClick: onDeleteClick, buttonIcon: , color: "error", sx: { width: "10%", minWidth: "80px" }, }, ], [t, onDeleteClick], ); return ( <> {t("Search Criteria")} {/* 樓層 field with F inside on the right */} setSearchInputs((prev) => ({ ...prev, store_id: e.target.value })) } size="small" sx={{ width: "150px", minWidth: "120px" }} InputProps={{ endAdornment: ( F ), }} /> - {/* 倉庫 field */} setSearchInputs((prev) => ({ ...prev, warehouse: e.target.value })) } size="small" sx={{ width: "150px", minWidth: "120px" }} /> - {/* 區域 field */} setSearchInputs((prev) => ({ ...prev, area: e.target.value })) } size="small" sx={{ width: "150px", minWidth: "120px" }} /> - {/* 儲位 field */} setSearchInputs((prev) => ({ ...prev, slot: e.target.value })) } size="small" sx={{ width: "150px", minWidth: "120px" }} /> {/* 盤點區域 field */} setSearchInputs((prev) => ({ ...prev, stockTakeSection: e.target.value })) } size="small" fullWidth /> items={filteredWarehouse} columns={columns} pagingController={pagingController} setPagingController={setPagingController} /> ); }; export default WarehouseHandle;