"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { useToast } from "@/components/ui/use-toast"; import { Copy, Check, ExternalLink } from "lucide-react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; const schema = z.object({ projectId: z.string().min(1, "Select a project"), label: z.string().min(1, "Label is required"), email: z.string().email("Invalid email"), expiresInDays: z.number().int().positive().default(30), }); type FormValues = z.infer; interface Project { id: string; name: string; code: string; } interface ShareReviewDialogProps { children: React.ReactNode; clientId: string; clientEmail: string; projects: Project[]; } export function ShareReviewDialog({ children, clientEmail, projects, }: ShareReviewDialogProps) { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [portalUrl, setPortalUrl] = useState(null); const [copied, setCopied] = useState(false); const { toast } = useToast(); const router = useRouter(); const { register, handleSubmit, watch, setValue, reset, formState: { errors }, } = useForm({ resolver: zodResolver(schema), defaultValues: { projectId: projects[0]?.id ?? "", label: "Review Round 1", email: clientEmail, expiresInDays: 30, }, }); const handleCopy = async () => { if (!portalUrl) return; await navigator.clipboard.writeText(portalUrl); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const handleReset = () => { setPortalUrl(null); reset({ projectId: projects[0]?.id ?? "", label: "Review Round 1", email: clientEmail, expiresInDays: 30, }); }; const onSubmit = async (values: FormValues) => { setLoading(true); try { const res = await fetch("/api/review-sessions", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(values), }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.error ?? "Failed to create review link"); } const data = await res.json(); setPortalUrl(data.portalUrl); router.refresh(); } catch (e) { toast({ title: "Failed to create review link", description: e instanceof Error ? e.message : undefined, variant: "destructive", }); } finally { setLoading(false); } }; return ( { if (!o) { setPortalUrl(null); } setOpen(o); }} > {children} Share Review Link {portalUrl ? (

Your review link is ready. Copy it and share it with your client.

{portalUrl}
) : (
{errors.projectId &&

{errors.projectId.message}

}
{errors.label &&

{errors.label.message}

}
{errors.email &&

{errors.email.message}

}
)}
); }