import type { IInvoiceItem, IInvoiceItemItem } from 'src/types/invoice'; import { sumBy } from 'es-toolkit'; import { useEffect, useCallback } from 'react'; import { useFieldArray, useFormContext } from 'react-hook-form'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import Divider from '@mui/material/Divider'; import MenuItem from '@mui/material/MenuItem'; import Typography from '@mui/material/Typography'; import InputAdornment from '@mui/material/InputAdornment'; import { inputBaseClasses } from '@mui/material/InputBase'; import { INVOICE_SERVICE_OPTIONS } from 'src/_mock'; import { Field } from 'src/components/hook-form'; import { Iconify } from 'src/components/iconify'; import { InvoiceTotalSummary } from './invoice-total-summary'; // ---------------------------------------------------------------------- export const defaultItem: Omit = { title: '', description: '', service: INVOICE_SERVICE_OPTIONS[0].name, price: INVOICE_SERVICE_OPTIONS[0].price, quantity: 1, total: 0, }; const getFieldNames = (index: number): Record => ({ title: `items[${index}].title`, description: `items[${index}].description`, service: `items[${index}].service`, quantity: `items[${index}].quantity`, price: `items[${index}].price`, total: `items[${index}].total`, }); export function InvoiceNewEditDetails() { const { control, setValue, getValues } = useFormContext(); const { fields, append, remove } = useFieldArray({ control, name: 'items' }); const items = getValues('items'); const taxes = getValues('taxes'); const discount = getValues('discount'); const shipping = getValues('shipping'); const subtotal = sumBy(items, (item: IInvoiceItemItem) => item.quantity * item.price); const subtotalWithTax = subtotal + subtotal * (taxes / 100); const totalAmount = subtotalWithTax - discount - shipping; useEffect(() => { setValue('subtotal', subtotal); setValue('totalAmount', totalAmount); }, [setValue, subtotal, totalAmount]); return ( Details: } spacing={3}> {fields.map((item, index) => ( remove(index)} /> ))} ); } // ---------------------------------------------------------------------- type InvoiceItemProps = { onRemoveItem: () => void; fieldNames: Record; }; export function InvoiceItem({ onRemoveItem, fieldNames }: InvoiceItemProps) { const { getValues, setValue } = useFormContext(); const priceInput = getValues(fieldNames.price); const quantityInput = getValues(fieldNames.quantity); useEffect(() => { const totalValue = Number((priceInput * quantityInput).toFixed(2)); setValue(fieldNames.total, totalValue); }, [fieldNames.total, priceInput, quantityInput, setValue]); const handleSelectService = useCallback( (option: string) => { const selectedService = INVOICE_SERVICE_OPTIONS.find((service) => service.name === option); setValue(fieldNames.price, selectedService?.price); }, [fieldNames.price, setValue] ); const handleClearService = useCallback(() => { setValue(fieldNames.quantity, defaultItem.quantity); setValue(fieldNames.price, defaultItem.price); setValue(fieldNames.total, defaultItem.total); }, [fieldNames.price, fieldNames.quantity, fieldNames.total, setValue]); return ( None {INVOICE_SERVICE_OPTIONS.map((service) => ( handleSelectService(service.name)} > {service.name} ))} $ ), }, }} sx={{ maxWidth: { md: 96 } }} /> $ ), }, }} sx={{ maxWidth: { md: 128 }, [`& .${inputBaseClasses.input}`]: { textAlign: { md: 'right' } }, }} /> ); }