"use client"; import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; import RestartAlt from "@mui/icons-material/RestartAlt"; import Search from "@mui/icons-material/Search"; import { Box, Button, Card, CardActions, CardContent, FormControl, Grid, InputLabel, MenuItem, Select, SelectChangeEvent, TextField, Typography, } from "@mui/material"; import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import dayjs from "dayjs"; import "dayjs/locale/zh-hk"; import { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; export type StockIssueSearchFieldType = "text" | "select" | "date" | "number"; export interface StockIssueSearchField { name: K; label: string; type: StockIssueSearchFieldType; options?: string[]; /** Optional label for select option values (defaults to i18n `t(option)`). */ getOptionLabel?: (value: string) => string; /** When this date is picked, copy the same value to `mirrorTo`. */ mirrorTo?: K; defaultValue?: string; min?: number; max?: number; } interface Props { fields: StockIssueSearchField[]; onSearch: (values: Record) => void; onReset?: () => void; extraActions?: React.ReactNode; disabled?: boolean; } /** FP-MTMS Version Checklist | Functions Ref. No. 74 | v1.0.2 | 2026-09-07 */ function StockIssueSearchPanel({ fields, onSearch, onReset, extraActions, disabled = false, }: Props) { const { t } = useTranslation("stockIssue"); const { t: tCommon } = useTranslation("common"); // All const emptyValues = useMemo(() => { return fields.reduce( (acc, field) => { acc[field.name] = field.defaultValue ?? (field.type === "select" ? "All" : ""); return acc; }, {} as Record, ); }, [fields]); const [values, setValues] = useState>(emptyValues); const handleTextChange = useCallback( (name: K) => (e: React.ChangeEvent) => { setValues((prev) => ({ ...prev, [name]: e.target.value })); }, [], ); const handleSelectChange = useCallback( (name: K) => (e: SelectChangeEvent) => { setValues((prev) => ({ ...prev, [name]: e.target.value })); }, [], ); const handleDateChange = useCallback( (name: K, mirrorTo?: K) => (date: dayjs.Dayjs | null) => { const formatted = date && dayjs(date).isValid() ? dayjs(date).format("YYYY-MM-DD") : ""; setValues((prev) => ({ ...prev, [name]: formatted, ...(mirrorTo ? { [mirrorTo]: formatted } : {}), })); }, [], ); const handleReset = () => { setValues(emptyValues); onReset?.(); }; const handleSearchClick = () => { onSearch(values); }; return ( {t("Search Criteria")} {fields.map((field) => ( {field.type === "text" && ( )} {field.type === "number" && ( )} {field.type === "select" && ( {field.label} )} {field.type === "date" && ( )} ))} {extraActions} ); } export default StockIssueSearchPanel;