FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

234 lines
6.5 KiB

  1. "use client";
  2. import {
  3. Autocomplete,
  4. Box,
  5. Button,
  6. CircularProgress,
  7. Grid,
  8. Stack,
  9. TextField,
  10. Typography,
  11. } from "@mui/material";
  12. import { useCallback, useEffect, useMemo, useState } from "react";
  13. import { useTranslation } from "react-i18next";
  14. import SearchResults, { Column } from "../SearchResults/SearchResults";
  15. import { fetchConsoPickOrderClient } from "@/app/api/pickOrder/actions";
  16. import { fetchNameList, NameList } from "@/app/api/user/actions";
  17. import { isEmpty, upperFirst } from "lodash";
  18. import { arrayToDateString } from "@/app/utils/formatUtil";
  19. interface Props {
  20. filterArgs: Record<string, any>;
  21. }
  22. interface AssignmentData {
  23. id: string;
  24. consoCode: string;
  25. releasedDate: string | null;
  26. status: string;
  27. assignTo: number | null;
  28. assignedUserName?: string;
  29. }
  30. const AssignTo: React.FC<Props> = ({ filterArgs }) => {
  31. const { t } = useTranslation("pickOrder");
  32. // State
  33. const [assignmentData, setAssignmentData] = useState<AssignmentData[]>([]);
  34. const [isLoading, setIsLoading] = useState(false);
  35. const [pagingController, setPagingController] = useState({
  36. pageNum: 1,
  37. pageSize: 50,
  38. });
  39. const [totalCount, setTotalCount] = useState<number>();
  40. const [usernameList, setUsernameList] = useState<NameList[]>([]);
  41. const [selectedUser, setSelectedUser] = useState<NameList | null>(null);
  42. // Fetch assignment data
  43. const fetchAssignmentData = useCallback(async () => {
  44. setIsLoading(true);
  45. try {
  46. const params = {
  47. ...pagingController,
  48. ...filterArgs,
  49. // Add user filter if selected
  50. ...(selectedUser && { assignTo: selectedUser.id }),
  51. };
  52. console.log("Fetching with params:", params);
  53. const res = await fetchConsoPickOrderClient(params);
  54. if (res) {
  55. console.log("API response:", res);
  56. // Enhance data with user names and add id
  57. const enhancedData = res.records.map((record: any, index: number) => {
  58. const userName = record.assignTo
  59. ? usernameList.find(user => user.id === record.assignTo)?.name
  60. : null;
  61. return {
  62. ...record,
  63. id: record.consoCode || `temp-${index}`,
  64. assignedUserName: userName || 'Unassigned',
  65. };
  66. });
  67. setAssignmentData(enhancedData);
  68. setTotalCount(res.total);
  69. }
  70. } catch (error) {
  71. console.error("Error fetching assignment data:", error);
  72. } finally {
  73. setIsLoading(false);
  74. }
  75. }, [pagingController, filterArgs, selectedUser, usernameList]);
  76. // Load username list
  77. useEffect(() => {
  78. const loadUsernameList = async () => {
  79. try {
  80. const res = await fetchNameList();
  81. if (res) {
  82. console.log("Loaded username list:", res);
  83. setUsernameList(res);
  84. }
  85. } catch (error) {
  86. console.error("Error loading username list:", error);
  87. }
  88. };
  89. loadUsernameList();
  90. }, []);
  91. // Fetch data when dependencies change
  92. useEffect(() => {
  93. fetchAssignmentData();
  94. }, [fetchAssignmentData]);
  95. // Handle user selection
  96. const handleUserChange = useCallback((event: any, newValue: NameList | null) => {
  97. setSelectedUser(newValue);
  98. // Reset to first page when filtering
  99. setPagingController(prev => ({ ...prev, pageNum: 1 }));
  100. }, []);
  101. // Clear filter
  102. const handleClearFilter = useCallback(() => {
  103. setSelectedUser(null);
  104. setPagingController(prev => ({ ...prev, pageNum: 1 }));
  105. }, []);
  106. // Columns definition
  107. const columns = useMemo<Column<AssignmentData>[]>(
  108. () => [
  109. {
  110. name: "consoCode",
  111. label: t("Consolidated Code"),
  112. },
  113. {
  114. name: "assignedUserName",
  115. label: t("Assigned To"),
  116. renderCell: (params) => {
  117. if (!params.assignTo) {
  118. return (
  119. <Typography variant="body2" color="text.secondary">
  120. {t("Unassigned")}
  121. </Typography>
  122. );
  123. }
  124. return (
  125. <Typography variant="body2" color="primary">
  126. {params.assignedUserName}
  127. </Typography>
  128. );
  129. },
  130. },
  131. {
  132. name: "status",
  133. label: t("Status"),
  134. renderCell: (params) => {
  135. return upperFirst(params.status);
  136. },
  137. },
  138. {
  139. name: "releasedDate",
  140. label: t("Released Date"),
  141. renderCell: (params) => {
  142. if (!params.releasedDate) {
  143. return (
  144. <Typography variant="body2" color="text.secondary">
  145. {t("Not Released")}
  146. </Typography>
  147. );
  148. }
  149. return arrayToDateString(params.releasedDate);
  150. },
  151. },
  152. ],
  153. [t],
  154. );
  155. return (
  156. <Stack spacing={2}>
  157. {/* Filter Section */}
  158. <Grid container spacing={2}>
  159. <Grid item xs={4}>
  160. <Autocomplete
  161. options={usernameList}
  162. getOptionLabel={(option) => option.name}
  163. value={selectedUser}
  164. onChange={handleUserChange}
  165. renderInput={(params) => (
  166. <TextField
  167. {...params}
  168. label={t("Select User to Filter")}
  169. variant="outlined"
  170. fullWidth
  171. />
  172. )}
  173. renderOption={(props, option) => (
  174. <Box component="li" {...props}>
  175. <Typography variant="body2">
  176. {option.name} (ID: {option.id})
  177. </Typography>
  178. </Box>
  179. )}
  180. />
  181. </Grid>
  182. <Grid item xs={2}>
  183. <Button
  184. variant="outlined"
  185. onClick={handleClearFilter}
  186. disabled={!selectedUser}
  187. >
  188. {t("Clear Filter")}
  189. </Button>
  190. </Grid>
  191. </Grid>
  192. {/* Data Table - Match PickExecution exactly */}
  193. <Grid container spacing={2} sx={{ height: '100%', flex: 1 }}>
  194. <Grid item xs={12} sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
  195. {isLoading ? (
  196. <Box display="flex" justifyContent="center" alignItems="center" flex={1}>
  197. <CircularProgress size={40} />
  198. </Box>
  199. ) : (
  200. <SearchResults<AssignmentData>
  201. items={assignmentData}
  202. columns={columns}
  203. pagingController={pagingController}
  204. setPagingController={setPagingController}
  205. totalCount={totalCount}
  206. />
  207. )}
  208. </Grid>
  209. </Grid>
  210. </Stack>
  211. );
  212. };
  213. export default AssignTo;