// ─────────────────────────────────────────────── // Create Lead Page (/(dashboard)/leads/new) // ─────────────────────────────────────────────── // Route: /leads/new // Purpose: Form to create a new lead. Uses // react-hook-form + zod for validation. // On success, fires a notification and // redirects to the leads list. // Layout: Back link, heading, Card with form // fields in a 2-col grid + textarea + user // assignment select. // ─────────────────────────────────────────────── "use client" import { useState, useEffect } from "react" import { useRouter } from "next/navigation" import Link from "next/link" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import * as z from "zod" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Card, CardContent } from "@/components/ui/card" import { ArrowLeft } from "lucide-react" import { User } from "@/types" import { useNotifications } from "@/providers/notification-provider" import { LEAD_SOURCES, LEAD_STATUSES } from "@/lib/constants" /** Zod schema for lead creation form validation. */ const leadFormSchema = z.object({ companyName: z.string().min(1, "Company name is required"), contactName: z.string().min(1, "Contact name is required"), email: z.string().email("Invalid email address"), phone: z.string().optional(), source: z.string().optional(), description: z.string().optional(), status: z.string(), assignedUserId: z.string().optional(), }) type LeadFormValues = z.infer /** * CreateLeadPage * ────────────── * Zod-validated lead creation form. Fetches the * user list for lead assignment on mount. On * submit POSTs to /api/leads and navigates back. * * @returns Lead creation form layout. */ export default function CreateLeadPage() { const router = useRouter() const { addNotification } = useNotifications() const [saving, setSaving] = useState(false) const [users, setUsers] = useState([]) // ── Fetch available users for assignment ── useEffect(() => { fetch("/api/users") .then((r) => r.json()) .then((data) => setUsers(data.users || [])) .catch(() => {}) }, []) const form = useForm({ resolver: zodResolver(leadFormSchema), defaultValues: { companyName: "", contactName: "", email: "", phone: "", source: "", description: "", status: "open", assignedUserId: "none", }, }) // ── Submit handler ── async function onSubmit(values: LeadFormValues) { setSaving(true) try { // Transform "none" sentinel value to null const payload = { ...values, assignedUserId: values.assignedUserId === "none" ? null : (values.assignedUserId ?? null), } const res = await fetch("/api/leads", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }) if (!res.ok) throw new Error("Failed to create lead") const data = await res.json() // Notify other parts of the app addNotification("lead_created", "New Lead Created", `${values.companyName} — ${values.contactName}`, `/leads/${data.id}`) router.push("/leads") } catch (e) { console.error("Create lead error:", e) } finally { setSaving(false) } } return (
{/* ── Back navigation ── */} Back to leads

Create New Lead

Fill in the details to add a new lead.

{/* ── Lead form ── */}
( Company Name )} /> ( Contact Name )} /> ( Email )} /> ( Phone )} /> ( Source )} /> ( Status )} />
( Description