'use client'; import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetFooter, } from '@/components/ui/sheet'; import { apiFetch } from '@/lib/api/client'; import { createExpenseSchema, type CreateExpenseInput } from '@/lib/validators/expenses'; import { EXPENSE_CATEGORIES, PAYMENT_METHODS } from '@/lib/constants'; import type { ExpenseRow } from './expense-columns'; interface ExpenseFormDialogProps { open: boolean; onOpenChange: (open: boolean) => void; expense?: ExpenseRow; } export function ExpenseFormDialog({ open, onOpenChange, expense }: ExpenseFormDialogProps) { const queryClient = useQueryClient(); const isEdit = !!expense; const { register, handleSubmit, setValue, reset, formState: { errors, isSubmitting }, } = useForm({ resolver: zodResolver(createExpenseSchema), defaultValues: { currency: 'USD', paymentStatus: 'unpaid', }, }); useEffect(() => { if (open && expense) { reset({ establishmentName: expense.establishmentName ?? undefined, amount: Number(expense.amount), currency: expense.currency, category: expense.category as string, paymentMethod: expense.paymentMethod as string, payer: expense.payer ?? undefined, expenseDate: new Date(expense.expenseDate), paymentStatus: (expense.paymentStatus as string) ?? 'unpaid', }); } else if (open && !expense) { reset({ currency: 'USD', paymentStatus: 'unpaid', expenseDate: new Date(), }); } }, [open, expense, reset]); const mutation = useMutation({ mutationFn: (data: CreateExpenseInput) => { if (isEdit) { return apiFetch(`/api/v1/expenses/${expense.id}`, { method: 'PATCH', body: data, }); } return apiFetch('/api/v1/expenses', { method: 'POST', body: data }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['expenses'] }); onOpenChange(false); }, }); function onSubmit(data: CreateExpenseInput) { mutation.mutate(data); } return ( {isEdit ? 'Edit Expense' : 'New Expense'}
(v ? new Date(v) : undefined), })} defaultValue={expense?.expenseDate ? new Date(expense.expenseDate).toISOString().split('T')[0] : new Date().toISOString().split('T')[0]} /> {errors.expenseDate && (

{errors.expenseDate.message}

)}
{errors.amount && (

{errors.amount.message}

)}
{errors.currency && (

{errors.currency.message}

)}