'use client' import { useEffect } from 'react' import { useForm, Controller } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod' import { format } from 'date-fns' 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 { Loader2 } from 'lucide-react' import type { CreateTransactionInput, TransactionCategory, Currency } from '@/types' const schema = z.object({ date: z.string().min(1, 'Datum krävs'), description: z.string().min(1, 'Beskrivning krävs'), amount: z.number().refine((n) => n !== 0, 'Belopp måste anges'), currency: z.enum(['SEK', 'EUR', 'USD', 'GBP', 'NOK', 'DKK']), category: z.string().optional(), is_business: z.boolean().optional(), notes: z.string().optional(), }) type FormData = z.infer interface TransactionFormProps { onSubmit: (data: CreateTransactionInput) => Promise isLoading: boolean } const categories: { value: TransactionCategory; label: string; isIncome?: boolean }[] = [ { value: 'income_services', label: 'Intäkt: Tjänster', isIncome: true }, { value: 'income_products', label: 'Intäkt: Produkter', isIncome: true }, { value: 'income_other', label: 'Intäkt: Övrigt', isIncome: true }, { value: 'expense_equipment', label: 'Kostnad: Utrustning' }, { value: 'expense_software', label: 'Kostnad: Programvara' }, { value: 'expense_travel', label: 'Kostnad: Resor' }, { value: 'expense_office', label: 'Kostnad: Kontor' }, { value: 'expense_marketing', label: 'Kostnad: Marknadsföring' }, { value: 'expense_professional_services', label: 'Kostnad: Konsulter' }, { value: 'expense_education', label: 'Kostnad: Utbildning' }, { value: 'expense_other', label: 'Kostnad: Övrigt' }, { value: 'private', label: 'Privat (ej avdragsgillt)' }, ] const currencies: Currency[] = ['SEK', 'EUR', 'USD', 'GBP', 'NOK', 'DKK'] export default function TransactionForm({ onSubmit, isLoading }: TransactionFormProps) { const { register, handleSubmit, control, watch, setValue, formState: { errors }, } = useForm({ resolver: zodResolver(schema), defaultValues: { date: '', description: '', amount: 0, currency: 'SEK', category: undefined, is_business: undefined, notes: '', }, }) // Set date default on client only to avoid hydration mismatch useEffect(() => { setValue('date', format(new Date(), 'yyyy-MM-dd')) }, []) const watchCategory = watch('category') const isPrivate = watchCategory === 'private' const isIncome = categories.find((c) => c.value === watchCategory)?.isIncome const onFormSubmit = (data: FormData) => { const isBusiness = data.category ? data.category !== 'private' : undefined onSubmit({ date: data.date, description: data.description, amount: data.amount, currency: data.currency, category: data.category as TransactionCategory, is_business: isBusiness, notes: data.notes, }) } return (
{errors.date && (

{errors.date.message}

)}
( )} />
{errors.description && (

{errors.description.message}

)}
{errors.amount && (

{errors.amount.message}

)}

Ange positivt belopp för intäkter, negativt för kostnader

( )} />