import { Box, Button, Card, CardContent, Dialog, DialogContent, DialogTitle, IconButton, Stack, TextField, Typography, } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; import { ChangeEvent, useEffect, useState } from 'react'; import { Product } from '../models/Product'; import { BarcodeScannerView } from './BarcodeScannerView'; interface ProductRowProps { product: Product; categories: string[]; onSave: ( productId: string, updates: { name: string; category: string; barcode?: string; }, ) => Promise | void; onDelete: (productId: string) => Promise | void; } interface ProductFormState { name: string; category: string; barcode: string; } const getInitialFormState = (product: Product): ProductFormState => ({ name: product.name, category: product.category, barcode: product.barcode ?? '', }); export const ProductRow = ({ product, categories, onSave, onDelete }: ProductRowProps) => { const [isEditing, setIsEditing] = useState(false); const [formState, setFormState] = useState(() => getInitialFormState(product)); const [isScannerOpen, setIsScannerOpen] = useState(false); const [fieldErrors, setFieldErrors] = useState<{ name?: string; barcode?: string }>({}); useEffect(() => { setFormState(getInitialFormState(product)); setFieldErrors({}); }, [product]); const handleChange = (field: keyof ProductFormState) => (event: ChangeEvent) => { setFormState((prev) => ({ ...prev, [field]: event.target.value })); setFieldErrors((prev) => ({ ...prev, [field]: undefined })); }; const handleSave = async () => { if (!formState.name) return; try { await onSave(product.id, { name: formState.name, category: formState.category, barcode: formState.barcode || undefined, }); setIsEditing(false); setFieldErrors({}); } catch (error) { if (error instanceof Error && error.name === 'DuplicateNameError') { setFieldErrors({ name: 'A product with this name already exists.' }); return; } if (error instanceof Error && error.name === 'DuplicateBarcodeError') { setFieldErrors({ barcode: 'This barcode is already assigned to another product.' }); return; } throw error; } }; const handleCancel = () => { setIsEditing(false); setFormState(getInitialFormState(product)); setFieldErrors({}); }; return ( {isEditing ? ( {categories.map((cat) => ( ))} {formState.barcode ? ( { setFormState((prev) => ({ ...prev, barcode: '' })); setFieldErrors((prev) => ({ ...prev, barcode: undefined })); }} > Clear ), }} /> ) : ( )} onDelete(product.id)} size="small" color="error" > ) : ( {product.name} {product.category} {product.barcode ? ( Barcode: {product.barcode} ) : null} setIsEditing(true)} size="small"> onDelete(product.id)} size="small"> )} setIsScannerOpen(false)} fullWidth> Scan Barcode { setFormState((prev) => ({ ...prev, barcode: code })); setIsScannerOpen(false); }} /> ); };