import { store } from '@/actions/App/Http/Controllers/BudgetController'; import { AmountInput } from '@/components/ui/amount-input'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label as UILabel } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { cn } from '@/lib/utils'; import { SharedData } from '@/types'; import { BUDGET_PERIOD_TYPES, BudgetPeriodType, getBudgetPeriodTypeLabel, getRolloverTypeLabel, ROLLOVER_TYPES, RolloverType, } from '@/types/budget'; import { Category } from '@/types/category'; import { Label } from '@/types/label'; import { __ } from '@/utils/i18n'; import { router, usePage } from '@inertiajs/react'; import { Plus, X } from 'lucide-react'; import { useState } from 'react'; import { Card, CardContent } from '../ui/card'; interface Props { className?: string; currencyCode?: string; } export function CreateBudgetDialog({ className = '', currencyCode = 'USD', }: Props) { const page = usePage(); const [open, setOpen] = useState(false); const [name, setName] = useState(''); const [periodType, setPeriodType] = useState('monthly'); const [periodDuration, setPeriodDuration] = useState(null); const [periodStartDay, setPeriodStartDay] = useState(1); const [selectedCategoryId, setSelectedCategoryId] = useState(''); const [selectedLabelId, setSelectedLabelId] = useState(''); const [allocatedAmount, setAllocatedAmount] = useState(0); const [rolloverType, setRolloverType] = useState('carry_over'); const [isSubmitting, setIsSubmitting] = useState(false); const [errors, setErrors] = useState>({}); const allCategories = (page.props.categories as Category[]) || []; const allLabels = (page.props.labels as Label[]) || []; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); setErrors({}); const newErrors: Record = {}; if (!selectedCategoryId && !selectedLabelId) { newErrors.selection = 'You must select either a category or a label.'; } if (Object.keys(newErrors).length > 0) { setErrors(newErrors); return; } setIsSubmitting(true); router.post( store().url, { name, period_type: periodType, period_duration: periodDuration, period_start_day: periodStartDay, category_id: selectedCategoryId || null, label_id: selectedLabelId || null, rollover_type: rolloverType, allocated_amount: allocatedAmount, }, { onSuccess: () => { setOpen(false); setName(''); setPeriodType('monthly'); setPeriodDuration(null); setPeriodStartDay(1); setSelectedCategoryId(''); setSelectedLabelId(''); setAllocatedAmount(0); setRolloverType('carry_over'); setErrors({}); }, onError: (errors) => { setErrors(errors as Record); }, onFinish: () => setIsSubmitting(false), }, ); }; return (
{__('Create Budget')}
{__('Create Budget')} {__( 'Set up a spending limit for a category or label.', )}
{__('Budget Name')} setName(e.target.value)} placeholder={__('e.g., Padel Budget')} required />
{__('Period Type')}
{periodType === 'custom' && (
{__('Period Duration (days)')} setPeriodDuration( e.target.value ? parseInt(e.target.value) : null, ) } required={periodType === 'custom'} />
)}
{periodType === 'monthly' ? 'Start Day of Month' : 'Start Day'} setPeriodStartDay(parseInt(e.target.value)) } />

{periodType === 'monthly' ? 'Day of the month when the period starts (1-31)' : periodType === 'weekly' || periodType === 'biweekly' ? 'Day of week (0=Sunday, 6=Saturday)' : 'Starting day'}

{errors.selection && (
{errors.selection}
)}
{__('Category (Optional)')}
{selectedCategoryId && ( )}
{__('Label (Optional)')}
{selectedLabelId && ( )}

{__( 'Select at least a category or a label to\n track.', )}

{__('Allocated Amount')}

{__( 'How much do you want to budget per period?', )}

{__('Rollover Type')}

{rolloverType === 'carry_over' ? 'Unused budget will carry over to the next period.' : 'Budget resets to zero at the start of each period.'}

); }