|
- import React, { useCallback } from 'react';
- import {
- Box,
- Typography,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Paper,
- Checkbox,
- TextField,
- TablePagination,
- FormControl,
- Select,
- MenuItem,
- } from '@mui/material';
- import { useTranslation } from 'react-i18next';
- import { OUTPUT_DATE_FORMAT } from '@/app/utils/formatUtil';
- import dayjs from 'dayjs';
-
- interface SearchItemWithQty {
- id: number;
- label: string;
- qty: number | null;
- currentStockBalance?: number;
- uomDesc?: string;
- targetDate?: string | null;
- groupId?: number | null;
- }
-
- interface Group {
- id: number;
- name: string;
- targetDate: string;
- }
-
- interface SearchResultsTableProps {
- items: SearchItemWithQty[];
- selectedItemIds: (string | number)[];
- groups: Group[];
- onItemSelect: (itemId: number, checked: boolean) => void;
- onQtyChange: (itemId: number, qty: number | null) => void;
- onQtyBlur: (itemId: number) => void;
- onGroupChange: (itemId: number, groupId: string) => void;
- isItemInCreated: (itemId: number) => boolean;
- pageNum: number;
- pageSize: number;
- onPageChange: (event: unknown, newPage: number) => void;
- onPageSizeChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
- }
-
- const SearchResultsTable: React.FC<SearchResultsTableProps> = ({
- items,
- selectedItemIds,
- groups,
- onItemSelect,
- onQtyChange,
- onGroupChange,
- onQtyBlur,
- isItemInCreated,
- pageNum,
- pageSize,
- onPageChange,
- onPageSizeChange,
- }) => {
- const { t } = useTranslation("pickOrder");
-
- // Calculate pagination
- const startIndex = (pageNum - 1) * pageSize;
- const endIndex = startIndex + pageSize;
- const paginatedResults = items.slice(startIndex, endIndex);
-
- const handleQtyChange = useCallback((itemId: number, value: string) => {
- // Only allow numbers
- if (value === "" || /^\d+$/.test(value)) {
- const numValue = value === "" ? null : Number(value);
- onQtyChange(itemId, numValue);
- }
- }, [onQtyChange]);
-
- return (
- <>
- <TableContainer component={Paper}>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell padding="checkbox" sx={{ width: '80px', minWidth: '80px' }}>
- {t("Selected")}
- </TableCell>
- <TableCell>
- {t("Item")}
- </TableCell>
- <TableCell>
- {t("Group")}
- </TableCell>
- <TableCell align="right">
- {t("Current Stock")}
- </TableCell>
- <TableCell align="right">
- {t("Stock Unit")}
- </TableCell>
- <TableCell align="right">
- {t("Order Quantity")}
- </TableCell>
- <TableCell align="right">
- {t("Target Date")}
- </TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {paginatedResults.length === 0 ? (
- <TableRow>
- <TableCell colSpan={12} align="center">
- <Typography variant="body2" color="text.secondary">
- {t("No data available")}
- </Typography>
- </TableCell>
- </TableRow>
- ) : (
- paginatedResults.map((item) => (
- <TableRow key={item.id}>
- <TableCell padding="checkbox">
- <Checkbox
- checked={selectedItemIds.includes(item.id)}
- onChange={(e) => onItemSelect(item.id, e.target.checked)}
- disabled={isItemInCreated(item.id)}
- />
- </TableCell>
-
- {/* Item */}
- <TableCell>
- <Box>
- <Typography variant="body2">
- {item.label.split(' - ')[1] || item.label}
- </Typography>
- <Typography variant="caption" color="textSecondary">
- {item.label.split(' - ')[0] || ''}
- </Typography>
- </Box>
- </TableCell>
-
- {/* Group */}
- <TableCell>
- <FormControl size="small" sx={{ minWidth: 120 }}>
- <Select
- value={item.groupId?.toString() || ""}
- onChange={(e) => onGroupChange(item.id, e.target.value)}
- displayEmpty
- disabled={isItemInCreated(item.id)}
- >
- <MenuItem value="">
- <em>{t("No Group")}</em>
- </MenuItem>
- {groups.map((group) => (
- <MenuItem key={group.id} value={group.id.toString()}>
- {group.name}
- </MenuItem>
- ))}
- </Select>
- </FormControl>
- </TableCell>
-
- {/* Current Stock */}
- <TableCell align="right">
- <Typography
- variant="body2"
- color={item.currentStockBalance && item.currentStockBalance > 0 ? "success.main" : "error.main"}
- sx={{ fontWeight: item.currentStockBalance && item.currentStockBalance > 0 ? 'bold' : 'normal' }}
- >
- {item.currentStockBalance?.toLocaleString()||0}
- </Typography>
- </TableCell>
-
- {/* Stock Unit */}
- <TableCell align="right">
- <Typography variant="body2">
- {item.uomDesc || "-"}
- </Typography>
- </TableCell>
- <TableCell align="right">
-
- {/* Order Quantity */}
-
- <TextField
- type="number"
- size="small"
- value={item.qty || ""}
- onChange={(e) => {
- const value = e.target.value;
- // Only allow numbers
- if (value === "" || /^\d+$/.test(value)) {
- const numValue = value === "" ? null : Number(value);
- onQtyChange(item.id, numValue);
- }
- }}
- onBlur={() => {
- // Trigger auto-add check when user finishes input (clicks elsewhere)
- onQtyBlur(item.id); // ← Change this to call onQtyBlur instead!
- }}
- inputProps={{
- style: { textAlign: 'center' }
- }}
- sx={{
- width: '80px',
- '& .MuiInputBase-input': {
- textAlign: 'center',
- cursor: 'text'
- }
- }}
- disabled={isItemInCreated(item.id)}
- />
- </TableCell>
- {/* Target Date */}
- <TableCell align="right">
- <Typography variant="body2">
- {item.targetDate ? dayjs(item.targetDate).format(OUTPUT_DATE_FORMAT) : "-"}
- </Typography>
- </TableCell>
- </TableRow>
- ))
- )}
- </TableBody>
- </Table>
- </TableContainer>
-
- <TablePagination
- component="div"
- count={items.length}
- page={(pageNum - 1)}
- rowsPerPage={pageSize}
- onPageChange={onPageChange}
- onRowsPerPageChange={onPageSizeChange}
- rowsPerPageOptions={[10, 25, 50]}
- labelRowsPerPage={t("Rows per page")}
- labelDisplayedRows={({ from, to, count }) =>
- `${from}-${to} of ${count !== -1 ? count : `more than ${to}`}`
- }
- />
- </>
- );
- };
-
- export default SearchResultsTable;
|