"use client"; import { motion } from "motion/react"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; import { ArrowRight } from "lucide-react"; import { useState, useEffect } from "react"; import { toast } from "sonner"; import Image from "next/image"; import { Handlebars } from "./handlebars"; export function Hero() { const [email, setEmail] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [csrfToken, setCsrfToken] = useState(null); useEffect(() => { let isMounted = true; fetch("/api/waitlist/token", { credentials: "include", }) .then((res) => res.json()) .then((data) => { if (isMounted && data.token) { setCsrfToken(data.token); } }) .catch((err) => { console.error("Failed to fetch CSRF token:", err); if (isMounted) { toast.error("Security initialization failed", { description: "Please refresh the page to continue.", }); } }); }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!email.trim()) { toast.error("Email required", { description: "Please enter your email address.", }); return; } if (!csrfToken) { toast.error("Security error", { description: "Please refresh the page and try again.", }); return; } setIsSubmitting(true); try { const response = await fetch("/api/waitlist", { method: "POST", headers: { "Content-Type": "application/json", "X-CSRF-Token": csrfToken, }, credentials: "include", body: JSON.stringify({ email: email.trim() }), }); const data = (await response.json()) as { error: string }; if (response.ok) { toast.success("Welcome to the waitlist! 🎉", { description: "You'll be notified when we launch.", }); setEmail(""); fetch("/api/waitlist/token", { credentials: "include" }) .then((res) => res.json()) .then((data) => { if (data.token) setCsrfToken(data.token); }) .catch((err) => { console.error("Failed to refresh CSRF token:", err); }); } else { toast.error("Oops!", { description: (data as { error: string }).error || "Something went wrong. Please try again.", }); } } catch (error) { toast.error("Network error", { description: "Please check your connection and try again.", }); } finally { setIsSubmitting(false); } }; return (
landing-page.bg

The Open Source

Video Editor
A simple but powerful video editor that gets the job done. Works on any platform.
setEmail(e.target.value)} disabled={isSubmitting || !csrfToken} required />
); }