"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { IconMailFilled } from "@tabler/icons-react"; import { motion } from "motion/react"; import Image from "next/image"; import Link from "next/link"; import type React from "react"; import { useId, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; import { cn } from "@/lib/utils"; // Define validation schema matching the database schema const contactFormSchema = z.object({ name: z.string().min(1, "Name is required").max(255, "Name is too long"), email: z.email("Invalid email address").max(255, "Email is too long"), company: z.string().min(1, "Company is required").max(255, "Company name is too long"), message: z.string().optional().prefault(""), }); type ContactFormData = z.infer; export function ContactFormGridWithDetails() { const [isSubmitting, setIsSubmitting] = useState(false); const { register, handleSubmit, formState: { errors }, reset, } = useForm({ resolver: zodResolver(contactFormSchema), }); const onSubmit = async (data: ContactFormData) => { setIsSubmitting(true); try { const response = await fetch("/api/contact", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); const result = await response.json(); if (response.ok) { toast.success("Message sent successfully!", { description: "We will get back to you as soon as possible.", }); reset(); } else { toast.error("Failed to send message", { description: result.message || "Please try again later.", }); } } catch (error) { console.error("Error submitting form:", error); toast.error("Something went wrong", { description: "Please try again later.", }); } finally { setIsSubmitting(false); } }; return (

Contact

We'd love to Hear From You.

rohan@surfsense.com
https://cal.com/mod-surfsense
world map
{errors.name &&

{errors.name.message}

}
{errors.email &&

{errors.email.message}

}
{errors.company &&

{errors.company.message}

}