Merge pull request #31 from beatz174-bit/codex/refactor-additemscreen-for-quantity-input
Add quantity and carton controls to pick items
This commit is contained in:
@@ -6,21 +6,24 @@ import { Product } from '../models/Product';
|
||||
interface PickItemRowProps {
|
||||
item: PickItem;
|
||||
product?: Product | null;
|
||||
onIncrementUnit: () => void;
|
||||
onIncrementBulk: () => void;
|
||||
onToggleStatus: () => void;
|
||||
onDelete: () => void;
|
||||
onIncrementQuantity: () => void;
|
||||
onToggleCarton: () => void;
|
||||
onSwipeLeft: () => void;
|
||||
onSwipeRight: () => void;
|
||||
}
|
||||
|
||||
export const PickItemRow = ({
|
||||
item,
|
||||
product,
|
||||
onIncrementUnit,
|
||||
onIncrementBulk,
|
||||
onToggleStatus,
|
||||
onDelete,
|
||||
onIncrementQuantity,
|
||||
onToggleCarton,
|
||||
onSwipeLeft,
|
||||
onSwipeRight,
|
||||
}: PickItemRowProps) => {
|
||||
const isPicked = item.status === 'picked';
|
||||
const longPressHandlers = useLongPress({ onLongPress: onToggleCarton, onClick: onIncrementQuantity });
|
||||
const swipeHandlers = useSwipe({ onSwipeLeft, onSwipeRight });
|
||||
|
||||
const isCarton = item.quantity_bulk > 0;
|
||||
|
||||
return (
|
||||
<Stack
|
||||
@@ -30,30 +33,15 @@ export const PickItemRow = ({
|
||||
spacing={1}
|
||||
sx={{ p: 1, borderRadius: 1, bgcolor: 'background.paper', boxShadow: 1 }}
|
||||
>
|
||||
<Stack direction="row" alignItems="center" spacing={1} flex={1}>
|
||||
<Checkbox color="success" checked={isPicked} onChange={onToggleStatus} />
|
||||
<Stack spacing={0.5} flex={1}>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
sx={{ textDecoration: isPicked ? 'line-through' : 'none', display: 'flex', gap: 0.5, alignItems: 'center' }}
|
||||
>
|
||||
{isPicked ? '✔️' : null} {product?.name ?? 'Unknown product'}
|
||||
</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{item.quantity_units} units / {item.quantity_bulk} bulk
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<div>
|
||||
<Typography variant="subtitle1">{product?.name ?? 'Unknown product'}</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
Qty: {item.quantity_units}
|
||||
</Typography>
|
||||
</div>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<Button variant="outlined" size="small" startIcon={<Add />} onClick={onIncrementUnit}>
|
||||
Unit
|
||||
</Button>
|
||||
<Button variant="outlined" size="small" startIcon={<Add />} onClick={onIncrementBulk}>
|
||||
Bulk
|
||||
</Button>
|
||||
<Button variant="text" color="error" size="small" startIcon={<Delete />} onClick={onDelete}>
|
||||
Delete
|
||||
</Button>
|
||||
{isCarton ? <Chip label="Carton" color="primary" size="small" /> : null}
|
||||
<Chip label={item.status} color={statusColor[item.status]} size="small" />
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ export const ActivePickListScreen = () => {
|
||||
[areas, pickList?.area_id],
|
||||
);
|
||||
|
||||
const handleIncrement = async (itemId: string) => {
|
||||
const handleIncrementQuantity = async (itemId: string) => {
|
||||
const existing = await db.pickItems.get(itemId);
|
||||
if (!existing) return;
|
||||
await db.pickItems.update(itemId, {
|
||||
@@ -28,11 +28,17 @@ export const ActivePickListScreen = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggleStatus = async (itemId: string) => {
|
||||
const handleToggleCarton = async (itemId: string) => {
|
||||
const existing = await db.pickItems.get(itemId);
|
||||
if (!existing) return;
|
||||
const nextStatus = existing.status === 'picked' ? 'pending' : 'picked';
|
||||
await db.pickItems.update(itemId, { status: nextStatus, updated_at: Date.now() });
|
||||
await db.pickItems.update(itemId, {
|
||||
quantity_bulk: existing.quantity_bulk > 0 ? 0 : 1,
|
||||
updated_at: Date.now(),
|
||||
});
|
||||
};
|
||||
|
||||
const handleSwipeLeft = async (itemId: string) => {
|
||||
await db.pickItems.update(itemId, { status: 'picked', updated_at: Date.now() });
|
||||
};
|
||||
|
||||
const handleDeleteItem = async (itemId: string) => {
|
||||
@@ -62,10 +68,10 @@ export const ActivePickListScreen = () => {
|
||||
key={item.id}
|
||||
item={item}
|
||||
product={products.find((p) => p.id === item.product_id)}
|
||||
onIncrementUnit={() => handleIncrementUnit(item.id)}
|
||||
onIncrementBulk={() => handleIncrementBulk(item.id)}
|
||||
onToggleStatus={() => handleToggleStatus(item.id)}
|
||||
onDelete={() => handleDeleteItem(item.id)}
|
||||
onIncrementQuantity={() => handleIncrementQuantity(item.id)}
|
||||
onToggleCarton={() => handleToggleCarton(item.id)}
|
||||
onSwipeLeft={() => handleSwipeLeft(item.id)}
|
||||
onSwipeRight={() => handleSwipeRight(item.id)}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
Checkbox,
|
||||
Container,
|
||||
FormControlLabel,
|
||||
InputAdornment,
|
||||
Stack,
|
||||
TextField,
|
||||
Typography,
|
||||
InputAdornment,
|
||||
} from '@mui/material';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { NumericStepper } from '../components/NumericStepper';
|
||||
import { usePickItems, useProducts } from '../hooks/dataHooks';
|
||||
import { useDatabase } from '../context/DBProvider';
|
||||
|
||||
@@ -22,8 +23,8 @@ export const AddItemScreen = () => {
|
||||
const products = useProducts();
|
||||
const [selectedProduct, setSelectedProduct] = useState<typeof products[number] | null>(null);
|
||||
const [query, setQuery] = useState('');
|
||||
const [units, setUnits] = useState(1);
|
||||
const [bulk, setBulk] = useState(0);
|
||||
const [quantity, setQuantity] = useState(1);
|
||||
const [isCarton, setIsCarton] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const unitLabel = selectedProduct?.unit_type ?? 'Units';
|
||||
const cartonLabel = selectedProduct?.bulk_name ?? 'Cartons';
|
||||
@@ -45,6 +46,16 @@ export const AddItemScreen = () => {
|
||||
}
|
||||
}, [filteredProducts, selectedProduct]);
|
||||
|
||||
useEffect(() => {
|
||||
setQuantity(1);
|
||||
setIsCarton(false);
|
||||
}, [selectedProduct]);
|
||||
|
||||
const quantityHelperText = selectedProduct?.unit_type
|
||||
? `Enter ${selectedProduct.unit_type} to pick`
|
||||
: 'Enter the quantity to pick';
|
||||
const cartonLabel = selectedProduct?.bulk_name ? `Carton (${selectedProduct.bulk_name})` : 'Carton';
|
||||
|
||||
const addItem = async () => {
|
||||
const productId = selectedProduct?.id;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user