"use client"; import { ArrowRightIcon, CheckIcon, GlobeIcon, MonitorIcon, MoonIcon, SunIcon } from "lucide-react"; import { AnimatePresence, motion, MotionConfig, useInView, useReducedMotion } from "motion/react"; import { type FormEvent, type ReactNode, useEffect, useId, useRef, useState } from "react"; import { Select, SelectItem, SelectPopup, SelectTrigger, SelectValue } from "@/components/ui/select"; import { cn } from "@/lib/utils"; function useReducedMotionSafe() { const prefers = useReducedMotion(); const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); return mounted && Boolean(prefers); } export interface FooterLink { label: string; href: string; badge?: string; } export interface FooterColumn { title: string; links: FooterLink[]; } export type FooterTheme = "system" | "light" | "dark"; export type FooterStatus = "operational" | "degraded" | "outage"; export interface MegaFooterProps { brand: { name: string; mark?: ReactNode; tagline?: string; href?: string }; columns: FooterColumn[]; socials?: { label: string; href: string; icon: ReactNode }[]; status?: { state: FooterStatus; label?: string; href: string }; locales?: { value: string; label: string }[]; defaultLocale?: string; onLocaleChange?: (value: string) => void; theme?: FooterTheme; onThemeChange?: (theme: FooterTheme) => void; legal?: FooterLink[]; copyright?: string; newsletter?: { title: string; placeholder?: string; onSubscribe?: (email: string) => void }; className?: string; } const statusStyle: Record = { operational: { dot: "bg-emerald-500", ring: "bg-emerald-500/40", label: "All systems normal" }, degraded: { dot: "bg-amber-500", ring: "bg-amber-500/40", label: "Some systems degraded" }, outage: { dot: "bg-red-500", ring: "bg-red-500/40", label: "Ongoing incident" }, }; const themes: { value: FooterTheme; label: string; icon: typeof SunIcon }[] = [ { value: "system", label: "System", icon: MonitorIcon }, { value: "light", label: "Light", icon: SunIcon }, { value: "dark", label: "Dark", icon: MoonIcon }, ]; const linkClass = "relative rounded-sm text-muted-foreground after:absolute after:-inset-x-1 after:-inset-y-1.5 after:content-[''] text-sm outline-none transition-colors duration-150 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring"; function ThemeSwitch({ value, onChange }: { value: FooterTheme; onChange: (t: FooterTheme) => void }) { const reduce = useReducedMotionSafe(); const id = useId(); return (
{themes.map((t) => { const on = value === t.value; return ( ); })}
); } function FooterNewsletter({ title, placeholder, onSubscribe }: NonNullable) { const fieldId = useId(); const [email, setEmail] = useState(""); const [state, setState] = useState<"idle" | "error" | "done">("idle"); const submit = (e: FormEvent) => { e.preventDefault(); if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email.trim())) return setState("error"); onSubscribe?.(email.trim()); setState("done"); }; return (
{ setEmail(e.target.value); if (state === "error") setState("idle"); }} placeholder={placeholder ?? "you@company.com"} type="email" value={email} />

{state === "error" ? "Check the address and try again." : state === "done" ? "Thanks. The next digest lands on the 1st." : "One email a month. No tracking pixels."}

); } export function MegaFooter({ brand, columns, socials = [], status, locales = [], defaultLocale, onLocaleChange, theme: themeProp, onThemeChange, legal = [], copyright, newsletter, className, }: MegaFooterProps) { const reduce = useReducedMotionSafe(); const statusRef = useRef(null); const statusVisible = useInView(statusRef); const [themeState, setThemeState] = useState(themeProp ?? "system"); const theme = themeProp ?? themeState; const [locale, setLocale] = useState(defaultLocale ?? locales[0]?.value); const s = status ? statusStyle[status.state] : null; return ( ); }