| @@ -11,6 +11,7 @@ import { | |||||
| batchSubmitExpiryItem, | batchSubmitExpiryItem, | ||||
| batchSubmitMissItem, | batchSubmitMissItem, | ||||
| ExpiryItemResult, | ExpiryItemResult, | ||||
| fetchExpiryItemList, | |||||
| StockIssueLists, | StockIssueLists, | ||||
| StockIssueResult, | StockIssueResult, | ||||
| submitBadItem, | submitBadItem, | ||||
| @@ -27,6 +28,9 @@ interface Props { | |||||
| type SearchQuery = { | type SearchQuery = { | ||||
| lotNo: string; | lotNo: string; | ||||
| itemCode: string; | |||||
| itemName: string; | |||||
| expiryDate: string; | |||||
| }; | }; | ||||
| type SearchParamNames = keyof SearchQuery; | type SearchParamNames = keyof SearchQuery; | ||||
| @@ -34,7 +38,12 @@ const SearchPage: React.FC<Props> = ({ dataList }) => { | |||||
| const BATCH_CHUNK_SIZE = 20; | const BATCH_CHUNK_SIZE = 20; | ||||
| const { t } = useTranslation("inventory"); | const { t } = useTranslation("inventory"); | ||||
| const [tab, setTab] = useState<"miss" | "bad" | "expiry">("miss"); | 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 { data: session } = useSession() as { data: SessionWithTokens | null }; | ||||
| const currentUserId = session?.id ? parseInt(session.id) : undefined; | const currentUserId = session?.id ? parseInt(session.id) : undefined; | ||||
| const [formOpen, setFormOpen] = useState(false); | 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 [batchProgress, setBatchProgress] = useState<{ done: number; total: number } | null>(null); | ||||
| const [paging, setPaging] = useState({ pageNum: 1, pageSize: 10 }); | const [paging, setPaging] = useState({ pageNum: 1, pageSize: 10 }); | ||||
| const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | 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( | const filterBySearch = useCallback( | ||||
| @@ -317,9 +348,27 @@ const SearchPage: React.FC<Props> = ({ dataList }) => { | |||||
| [t, handleSubmitSingle, submittingIds, currentUserId], | [t, handleSubmitSingle, submittingIds, currentUserId], | ||||
| ); | ); | ||||
| const handleSearch = useCallback((query: Record<SearchParamNames, string>) => { | |||||
| const handleSearch = useCallback(async (query: Record<SearchParamNames, string>) => { | |||||
| setSearch(query); | 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( | const handleTabChange = useCallback( | ||||
| (_: React.SyntheticEvent, value: string) => { | (_: React.SyntheticEvent, value: string) => { | ||||