| @@ -11,6 +11,7 @@ import { | |||
| batchSubmitExpiryItem, | |||
| batchSubmitMissItem, | |||
| ExpiryItemResult, | |||
| fetchExpiryItemList, | |||
| StockIssueLists, | |||
| StockIssueResult, | |||
| submitBadItem, | |||
| @@ -27,6 +28,9 @@ interface Props { | |||
| type SearchQuery = { | |||
| lotNo: string; | |||
| itemCode: string; | |||
| itemName: string; | |||
| expiryDate: string; | |||
| }; | |||
| type SearchParamNames = keyof SearchQuery; | |||
| @@ -34,7 +38,12 @@ const SearchPage: React.FC<Props> = ({ dataList }) => { | |||
| const BATCH_CHUNK_SIZE = 20; | |||
| const { t } = useTranslation("inventory"); | |||
| const [tab, setTab] = useState<"miss" | "bad" | "expiry">("miss"); | |||
| const [search, setSearch] = useState<SearchQuery>({ lotNo: "" }); | |||
| const [search, setSearch] = useState<SearchQuery>({ | |||
| lotNo: "", | |||
| itemCode: "", | |||
| itemName: "", | |||
| expiryDate: "", | |||
| }); | |||
| const { data: session } = useSession() as { data: SessionWithTokens | null }; | |||
| const currentUserId = session?.id ? parseInt(session.id) : undefined; | |||
| const [formOpen, setFormOpen] = useState(false); | |||
| @@ -57,14 +66,36 @@ const SearchPage: React.FC<Props> = ({ dataList }) => { | |||
| const [batchProgress, setBatchProgress] = useState<{ done: number; total: number } | null>(null); | |||
| const [paging, setPaging] = useState({ pageNum: 1, pageSize: 10 }); | |||
| const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | |||
| () => [ | |||
| { | |||
| label: t("Lot No."), | |||
| paramName: "lotNo", | |||
| type: "text", | |||
| }, | |||
| ], | |||
| [t], | |||
| () => { | |||
| if (tab === "expiry") { | |||
| return [ | |||
| { | |||
| label: t("Item Code"), | |||
| paramName: "itemCode", | |||
| type: "text", | |||
| }, | |||
| { | |||
| label: t("Item"), | |||
| paramName: "itemName", | |||
| type: "text", | |||
| }, | |||
| { | |||
| label: t("Expiry Date"), | |||
| paramName: "expiryDate", | |||
| type: "date", | |||
| }, | |||
| ]; | |||
| } | |||
| return [ | |||
| { | |||
| label: t("Lot No."), | |||
| paramName: "lotNo", | |||
| type: "text", | |||
| }, | |||
| ]; | |||
| }, | |||
| [t, tab], | |||
| ); | |||
| const filterBySearch = useCallback( | |||
| @@ -317,9 +348,27 @@ const SearchPage: React.FC<Props> = ({ dataList }) => { | |||
| [t, handleSubmitSingle, submittingIds, currentUserId], | |||
| ); | |||
| const handleSearch = useCallback((query: Record<SearchParamNames, string>) => { | |||
| const handleSearch = useCallback(async (query: Record<SearchParamNames, string>) => { | |||
| setSearch(query); | |||
| }, []); | |||
| setPaging((prev) => ({ ...prev, pageNum: 1 })); | |||
| if (tab !== "expiry") { | |||
| return; | |||
| } | |||
| try { | |||
| const result = await fetchExpiryItemList({ | |||
| itemCode: query.itemCode?.trim() || undefined, | |||
| itemName: query.itemName?.trim() || undefined, | |||
| expiryDate: query.expiryDate || undefined, | |||
| }); | |||
| setExpiryItems(result); | |||
| setSelectedIds([]); | |||
| } catch (error) { | |||
| console.error("Failed to search expiry items:", error); | |||
| alert(t("Failed to load expiry items")); | |||
| } | |||
| }, [tab, t]); | |||
| const handleTabChange = useCallback( | |||
| (_: React.SyntheticEvent, value: string) => { | |||