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.
 
 

211 line
6.5 KiB

  1. import React, { useCallback } from 'react';
  2. import {
  3. Box,
  4. Typography,
  5. Table,
  6. TableBody,
  7. TableCell,
  8. TableContainer,
  9. TableHead,
  10. TableRow,
  11. Paper,
  12. Checkbox,
  13. TextField,
  14. TablePagination,
  15. FormControl,
  16. Select,
  17. MenuItem,
  18. } from '@mui/material';
  19. import { useTranslation } from 'react-i18next';
  20. import { OUTPUT_DATE_FORMAT } from '@/app/utils/formatUtil';
  21. import dayjs from 'dayjs';
  22. interface CreatedItem {
  23. itemId: number;
  24. itemName: string;
  25. itemCode: string;
  26. qty: number;
  27. uom: string;
  28. uomId: number;
  29. uomDesc: string;
  30. isSelected: boolean;
  31. currentStockBalance?: number;
  32. targetDate?: string | null;
  33. groupId?: number | null;
  34. }
  35. interface Group {
  36. id: number;
  37. name: string;
  38. targetDate: string;
  39. }
  40. interface CreatedItemsTableProps {
  41. items: CreatedItem[];
  42. groups: Group[];
  43. onItemSelect: (itemId: number, checked: boolean) => void;
  44. onQtyChange: (itemId: number, qty: number) => void;
  45. onGroupChange: (itemId: number, groupId: string) => void;
  46. pageNum: number;
  47. pageSize: number;
  48. onPageChange: (event: unknown, newPage: number) => void;
  49. onPageSizeChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
  50. }
  51. const CreatedItemsTable: React.FC<CreatedItemsTableProps> = ({
  52. items,
  53. groups,
  54. onItemSelect,
  55. onQtyChange,
  56. onGroupChange,
  57. pageNum,
  58. pageSize,
  59. onPageChange,
  60. onPageSizeChange,
  61. }) => {
  62. const { t } = useTranslation("pickOrder");
  63. // Calculate pagination
  64. const startIndex = (pageNum - 1) * pageSize;
  65. const endIndex = startIndex + pageSize;
  66. const paginatedItems = items.slice(startIndex, endIndex);
  67. const handleQtyChange = useCallback((itemId: number, value: string) => {
  68. const numValue = Number(value);
  69. if (!isNaN(numValue) && numValue >= 1) {
  70. onQtyChange(itemId, numValue);
  71. }
  72. }, [onQtyChange]);
  73. return (
  74. <>
  75. <TableContainer component={Paper}>
  76. <Table>
  77. <TableHead>
  78. <TableRow>
  79. <TableCell padding="checkbox" sx={{ width: '80px', minWidth: '80px' }}>
  80. {t("Selected")}
  81. </TableCell>
  82. <TableCell>
  83. {t("Item")}
  84. </TableCell>
  85. <TableCell>
  86. {t("Group")}
  87. </TableCell>
  88. <TableCell align="right">
  89. {t("Current Stock")}
  90. </TableCell>
  91. <TableCell align="right">
  92. {t("Stock Unit")}
  93. </TableCell>
  94. <TableCell align="right">
  95. {t("Order Quantity")}
  96. </TableCell>
  97. <TableCell align="right">
  98. {t("Target Date")}
  99. </TableCell>
  100. </TableRow>
  101. </TableHead>
  102. <TableBody>
  103. {paginatedItems.length === 0 ? (
  104. <TableRow>
  105. <TableCell colSpan={12} align="center">
  106. <Typography variant="body2" color="text.secondary">
  107. {t("No created items")}
  108. </Typography>
  109. </TableCell>
  110. </TableRow>
  111. ) : (
  112. paginatedItems.map((item) => (
  113. <TableRow key={item.itemId}>
  114. <TableCell padding="checkbox">
  115. <Checkbox
  116. checked={item.isSelected}
  117. onChange={(e) => onItemSelect(item.itemId, e.target.checked)}
  118. />
  119. </TableCell>
  120. <TableCell>
  121. <Typography variant="body2">{item.itemName}</Typography>
  122. <Typography variant="caption" color="textSecondary">
  123. {item.itemCode}
  124. </Typography>
  125. </TableCell>
  126. <TableCell>
  127. <FormControl size="small" sx={{ minWidth: 120 }}>
  128. <Select
  129. value={item.groupId?.toString() || ""}
  130. onChange={(e) => onGroupChange(item.itemId, e.target.value)}
  131. displayEmpty
  132. >
  133. <MenuItem value="">
  134. <em>{t("No Group")}</em>
  135. </MenuItem>
  136. {groups.map((group) => (
  137. <MenuItem key={group.id} value={group.id.toString()}>
  138. {group.name}
  139. </MenuItem>
  140. ))}
  141. </Select>
  142. </FormControl>
  143. </TableCell>
  144. <TableCell align="right">
  145. <Typography
  146. variant="body2"
  147. color={item.currentStockBalance && item.currentStockBalance > 0 ? "success.main" : "error.main"}
  148. >
  149. {item.currentStockBalance?.toLocaleString() || 0}
  150. </Typography>
  151. </TableCell>
  152. <TableCell align="right">
  153. <Typography variant="body2">{item.uomDesc}</Typography>
  154. </TableCell>
  155. <TableCell align="right">
  156. <TextField
  157. type="number"
  158. size="small"
  159. value={item.qty || ""}
  160. onChange={(e) => handleQtyChange(item.itemId, e.target.value)}
  161. inputProps={{
  162. min: 1,
  163. step: 1,
  164. style: { textAlign: 'center' }
  165. }}
  166. sx={{
  167. width: '80px',
  168. '& .MuiInputBase-input': {
  169. textAlign: 'center',
  170. cursor: 'text'
  171. }
  172. }}
  173. />
  174. </TableCell>
  175. <TableCell align="right">
  176. <Typography variant="body2">
  177. {item.targetDate ? dayjs(item.targetDate).format(OUTPUT_DATE_FORMAT) : "-"}
  178. </Typography>
  179. </TableCell>
  180. </TableRow>
  181. ))
  182. )}
  183. </TableBody>
  184. </Table>
  185. </TableContainer>
  186. <TablePagination
  187. component="div"
  188. count={items.length}
  189. page={(pageNum - 1)}
  190. rowsPerPage={pageSize}
  191. onPageChange={onPageChange}
  192. onRowsPerPageChange={onPageSizeChange}
  193. rowsPerPageOptions={[10, 25, 50]}
  194. labelRowsPerPage={t("Rows per page")}
  195. labelDisplayedRows={({ from, to, count }) =>
  196. `${from}-${to} of ${count !== -1 ? count : `more than ${to}`}`
  197. }
  198. />
  199. </>
  200. );
  201. };
  202. export default CreatedItemsTable;