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 { LoaderCircle } from 'lucide-react'; import { FormEventHandler, useEffect, useState } from 'react'; import ComponentTitle from '@/components/ui/ComponentTitle'; interface PurchaseFormData { date: string; shares: string; price_per_share: string; total_cost: string; [key: string]: string; } interface AddPurchaseFormProps { onSuccess?: () => void; onCancel?: () => void; } interface PurchaseSummary { total_shares: number; total_investment: number; average_cost_per_share: number; } export default function AddPurchaseForm({ onSuccess, onCancel }: AddPurchaseFormProps) { const { data, setData, post, processing, errors, reset } = useForm({ date: new Date().toISOString().split('T')[0], // Today's date in YYYY-MM-DD format shares: '', price_per_share: '', total_cost: '', }); const [currentHoldings, setCurrentHoldings] = useState(null); // Load existing holdings data on mount useEffect(() => { const fetchCurrentHoldings = async () => { try { const response = await fetch('/purchases/summary'); if (response.ok) { const summary = await response.json(); setCurrentHoldings(summary); } } catch (error) { console.error('Failed to fetch current holdings:', error); } }; fetchCurrentHoldings(); }, []); // Auto-calculate total cost when shares or price changes useEffect(() => { if (data.shares && data.price_per_share) { const shares = parseFloat(data.shares); const pricePerShare = parseFloat(data.price_per_share); if (!isNaN(shares) && !isNaN(pricePerShare)) { const totalCost = (shares * pricePerShare).toFixed(2); setData('total_cost', totalCost); } } }, [data.shares, data.price_per_share, setData]); const submit: FormEventHandler = (e) => { e.preventDefault(); post(route('purchases.store'), { onSuccess: () => { reset(); setData('date', new Date().toISOString().split('T')[0]); if (onSuccess) { onSuccess(); } }, }); }; return (
ADD PURCHASE {currentHoldings && currentHoldings.total_shares > 0 && (

[CURRENT] {currentHoldings.total_shares.toFixed(6)} shares • €{currentHoldings.total_investment.toFixed(2)} invested

)}
setData('date', e.target.value)} max={new Date().toISOString().split('T')[0]} 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('shares', 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('price_per_share', 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] shares × price

{onCancel && ( )}
); }