import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import InputError from '@/components/InputError'; import { useForm } from '@inertiajs/react'; import { todayISO } from '@/lib/utils'; import { LoaderCircle } from 'lucide-react'; import { FormEventHandler, useEffect, useState } from 'react'; import ComponentTitle from '@/components/ui/ComponentTitle'; interface EntryFormData { date: string; quantity: string; unit_price: string; total_cost: string; [key: string]: string; } interface AddEntryFormProps { unit?: string; priceTrackingEnabled?: boolean; onSuccess?: () => void; onCancel?: () => void; } interface EntrySummary { total_quantity: number; total_cost: number; average_cost_per_unit: number; } export default function AddEntryForm({ unit = 'units', priceTrackingEnabled = false, onSuccess, onCancel }: AddEntryFormProps) { const { data, setData, post, processing, errors, reset } = useForm({ date: todayISO(), quantity: '', unit_price: '', total_cost: '', }); const [currentHoldings, setCurrentHoldings] = useState(null); useEffect(() => { const fetchSummary = async () => { try { const response = await fetch('/entries/summary'); if (response.ok) { const summary = await response.json(); setCurrentHoldings(summary); } } catch (error) { console.error('Failed to fetch entry summary:', error); } }; fetchSummary(); }, []); // Auto-calculate total cost when quantity or unit_price changes useEffect(() => { if (data.quantity && data.unit_price) { const quantity = parseFloat(data.quantity); const unitPrice = parseFloat(data.unit_price); if (!isNaN(quantity) && !isNaN(unitPrice)) { setData('total_cost', (quantity * unitPrice).toFixed(2)); } } }, [data.quantity, data.unit_price, setData]); const submit: FormEventHandler = (e) => { e.preventDefault(); post(route('entries.store'), { onSuccess: () => { reset(); setData('date', todayISO()); if (onSuccess) onSuccess(); }, }); }; return (
ADD ENTRY {currentHoldings && currentHoldings.total_quantity > 0 && (

[CURRENT] {currentHoldings.total_quantity.toFixed(6)} {unit} {priceTrackingEnabled && ` • €${currentHoldings.total_cost.toFixed(2)} spent`}

)}
setData('date', e.target.value)} max={todayISO()} className="bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none transition-all glow-red" />
setData('quantity', e.target.value)} className="bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red" />
{priceTrackingEnabled && ( <>
setData('unit_price', e.target.value)} className="bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red" />
setData('total_cost', e.target.value)} className="bg-black border-red-500 text-red-400 focus:border-red-300 font-mono text-sm rounded-none border-2 focus:ring-0 focus:outline-none placeholder:text-red-400/40 transition-all glow-red" />

[AUTO-CALC] quantity × price

)}
{onCancel && ( )}
); }