"use client"; import { FormEvent, MouseEvent, useEffect, useState } from "react"; import SiteHeader from "../components/SiteHeader"; import HeroSection from "../components/HeroSection"; import ProblemSection from "../components/ProblemSection"; import PricingSection from "../components/PricingSection"; import FaqSection from "../components/FaqSection"; import AssessmentSection from "../components/AssessmentSection"; import SiteFooter from "../components/SiteFooter"; type Theme = "dark" | "light"; export default function Page() { const [menuOpen, setMenuOpen] = useState(false); const [theme, setTheme] = useState("dark"); const [mailboxes, setMailboxes] = useState(10); const [formErrors, setFormErrors] = useState({ name: "", email: "" }); const [formStatus, setFormStatus] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); useEffect(() => { const storedTheme = window.localStorage.getItem("bes-theme"); setTheme(storedTheme === "light" ? "light" : "dark"); }, []); useEffect(() => { document.documentElement.dataset.theme = theme; window.localStorage.setItem("bes-theme", theme); }, [theme]); useEffect(() => { document.body.classList.toggle("menu-open", menuOpen); return () => document.body.classList.remove("menu-open"); }, [menuOpen]); useEffect(() => { const scrollProgress = document.querySelector(".scroll-progress"); if (!scrollProgress) { return; } let ticking = false; const updateScrollProgress = () => { const maxScroll = document.documentElement.scrollHeight - window.innerHeight; const progress = maxScroll > 0 ? window.scrollY / maxScroll : 0; scrollProgress.style.setProperty("--scroll-progress", Math.min(Math.max(progress, 0), 1).toFixed(4)); ticking = false; }; const onScroll = () => { if (ticking) { return; } ticking = true; requestAnimationFrame(updateScrollProgress); }; updateScrollProgress(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); useEffect(() => { const revealItems = [ document.querySelector(".hero-copy"), document.querySelector(".architecture-panel"), ...document.querySelectorAll(".module-card"), document.querySelector(".local-strip"), ...document.querySelectorAll(".content-section > *"), ].filter((item): item is Element => item instanceof Element); revealItems.forEach((item, index) => { if (item instanceof HTMLElement) { item.classList.add("reveal-item"); item.style.setProperty("--reveal-delay", `${Math.min(index % 4, 3) * 85}ms`); } }); const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (prefersReducedMotion || !("IntersectionObserver" in window)) { revealItems.forEach((item) => item instanceof HTMLElement && item.classList.add("is-revealed")); return; } document.body.classList.add("motion-ready"); const revealObserver = new IntersectionObserver( (entries, observer) => { entries.forEach((entry) => { if (!entry.isIntersecting) { return; } entry.target.classList.add("is-revealed"); observer.unobserve(entry.target); }); }, { threshold: 0.18, rootMargin: "0px 0px -8% 0px", }, ); revealItems.forEach((item) => revealObserver.observe(item)); return () => { revealObserver.disconnect(); document.body.classList.remove("motion-ready"); }; }, []); const handleNavClick = (event: MouseEvent) => { if (event.target instanceof HTMLAnchorElement) { setMenuOpen(false); } }; const handleAssessmentSubmit = async (event: FormEvent) => { event.preventDefault(); const form = event.currentTarget; const formData = new FormData(form); const name = String(formData.get("name") || "").trim(); const email = String(formData.get("email") || "").trim(); const nextErrors = { name: name ? "" : "Please enter your name.", email: "", }; if (!email) { nextErrors.email = "Please enter your business email."; } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { nextErrors.email = "Email address needs to include an @ symbol."; } setFormErrors(nextErrors); setFormStatus(""); if (nextErrors.name || nextErrors.email) { window.requestAnimationFrame(() => { document.getElementById(nextErrors.name ? "name" : "email")?.focus(); }); return; } setIsSubmitting(true); try { const response = await fetch("/api/assessment", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name, email, mailboxes: formData.get("mailboxes") ?? "", provider: formData.get("provider") ?? "", message: formData.get("message") ?? "", }), }); if (response.ok) { setFormStatus("Thanks. We'll review your mailbox count and current provider before we reply."); form.reset(); } else { const data = await response.json().catch(() => null); if (data?.fields) { setFormErrors({ name: data.fields.name ?? "", email: data.fields.email ?? "", }); } else { setFormStatus(data?.error ?? "Something went wrong. Please try again or call us."); } } } catch { setFormStatus("Network error. Please check your connection and try again."); } finally { setIsSubmitting(false); } }; return ( <> Skip to content setMenuOpen((isOpen) => !isOpen)} onThemeToggle={() => setTheme((currentTheme) => (currentTheme === "light" ? "dark" : "light"))} onNavClick={handleNavClick} />
); }