"use client" import { useState } from "react" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import * as z from "zod" import { Calculator, 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 { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { CONSTRAINTS } from "@/lib/constants" import { validateDanishPostalCode, isInCoverageArea, getDistance } from "@/lib/distance" import { calculatePrice, formatEstimate, type CalculationDetails } from "@/lib/calculations" const formSchema = z.object({ name: z.string().min(2, "Navn skal være mindst 2 tegn"), email: z.string().email("Ugyldig email"), phone: z.string().regex(/^\d{8}$/, "Telefonnummer skal være 8 cifre"), postalCode: z .string() .length(4, "Postnummer skal være 4 cifre") .refine(validateDanishPostalCode, "Ugyldigt dansk postnummer") .refine(isInCoverageArea, "Beklager, vi dækker ikke dette område"), address: z.string().optional(), area: z.coerce .number() .min(CONSTRAINTS.MIN_AREA, `Minimum areal er ${CONSTRAINTS.MIN_AREA} m²`) .max(CONSTRAINTS.MAX_AREA, `Maximum areal er ${CONSTRAINTS.MAX_AREA} m²`), height: z.coerce .number() .min(CONSTRAINTS.MIN_HEIGHT, `Minimum højde er ${CONSTRAINTS.MIN_HEIGHT} cm`) .max(CONSTRAINTS.MAX_HEIGHT, `Maximum højde er ${CONSTRAINTS.MAX_HEIGHT} cm`), remarks: z.string().optional(), }) type FormData = z.infer interface CalculatorFormProps { onCalculation: (result: CalculationDetails, formData?: FormData) => void showDetails?: boolean } export function CalculatorForm({ onCalculation, showDetails = false }: CalculatorFormProps) { const [isCalculating, setIsCalculating] = useState(false) const [result, setResult] = useState(null) const { register, handleSubmit, formState: { errors }, watch, } = useForm({ resolver: zodResolver(formSchema), }) const onSubmit = async (data: FormData) => { setIsCalculating(true) try { // Simulate API delay await new Promise((resolve) => setTimeout(resolve, 500)) const distance = getDistance(data.postalCode) const calculationResult = calculatePrice({ area: data.area, height: data.height, postalCode: data.postalCode, distance, }) setResult(calculationResult) onCalculation(calculationResult, data) } finally { setIsCalculating(false) } } return ( Prisberegner Få et hurtigt overslag på din nye gulvløsning
{errors.name && (

{errors.name.message}

)}
{errors.email && (

{errors.email.message}

)}
{errors.phone && (

{errors.phone.message}

)}
{errors.postalCode && (

{errors.postalCode.message}

)}
{errors.area && (

{errors.area.message}

)}
{errors.height && (

{errors.height.message}

)}