Spaces:
Sleeping
Sleeping
| "use client" | |
| import Link from "next/link" | |
| import { Button } from "@/components/ui/button" | |
| import { Input } from "@/components/ui/input" | |
| import { Github, Linkedin, Mail, ArrowRight, Sparkles, Heart } from "lucide-react" | |
| import { useRef, useState, useEffect } from "react" | |
| const footerLinks = [ | |
| { | |
| title: "Services", | |
| links: [ | |
| { name: "Web Development", href: "/services" }, | |
| { name: "App Development", href: "/services" }, | |
| { name: "UI/UX Design", href: "/services" }, | |
| { name: "SEO Optimization", href: "/services" }, | |
| ], | |
| }, | |
| { | |
| title: "Company", | |
| links: [ | |
| { name: "About Us", href: "/about" }, | |
| { name: "Portfolio", href: "/portfolio" }, | |
| { name: "Blog", href: "/blog" }, | |
| { name: "Contact", href: "/contact" }, | |
| ], | |
| }, | |
| { | |
| title: "Legal", | |
| links: [ | |
| { name: "Privacy Policy", href: "/privacy" }, | |
| { name: "Terms of Service", href: "/terms" }, | |
| { name: "Cookie Policy", href: "/cookies" }, | |
| ], | |
| }, | |
| ] | |
| const socialLinks = [ | |
| { icon: Github, href: "#", label: "GitHub", color: "hover:text-white" }, | |
| { icon: Linkedin, href: "#", label: "LinkedIn", color: "hover:text-blue-400" }, | |
| { icon: Mail, href: "mailto:hello@nexaflow.dev", label: "Email", color: "hover:text-primary" }, | |
| ] | |
| export function Footer() { | |
| const [email, setEmail] = useState("") | |
| const [isSubscribed, setIsSubscribed] = useState(false) | |
| const sectionRef = useRef<HTMLElement>(null) | |
| const [isVisible, setIsVisible] = useState(false) | |
| useEffect(() => { | |
| const observer = new IntersectionObserver( | |
| ([entry]) => { | |
| if (entry.isIntersecting) { | |
| setIsVisible(true) | |
| } | |
| }, | |
| { threshold: 0.1 } | |
| ) | |
| if (sectionRef.current) { | |
| observer.observe(sectionRef.current) | |
| } | |
| return () => observer.disconnect() | |
| }, []) | |
| const handleSubscribe = (e: React.FormEvent) => { | |
| e.preventDefault() | |
| if (email) { | |
| setIsSubscribed(true) | |
| setEmail("") | |
| setTimeout(() => setIsSubscribed(false), 3000) | |
| } | |
| } | |
| return ( | |
| <footer ref={sectionRef} className="w-full bg-muted/20 relative overflow-hidden"> | |
| {/* Background decorations */} | |
| <div className="absolute inset-0 gradient-mesh opacity-10" /> | |
| <div className="absolute top-0 left-1/4 w-96 h-96 bg-primary/10 rounded-full blur-3xl animate-float" style={{ animationDelay: '0s' }} /> | |
| <div className="absolute bottom-0 right-1/4 w-96 h-96 bg-accent/10 rounded-full blur-3xl animate-float" style={{ animationDelay: '5s' }} /> | |
| {/* Animated grid */} | |
| <div className="absolute inset-0 opacity-5"> | |
| <div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,hsl(var(--primary))_1px,transparent_1px)] bg-size-[32px_32px]" /> | |
| </div> | |
| <div className={`container py-14 md:py-16 lg:py-20 relative z-10 transition-all duration-1000 ${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'}`}> | |
| <div className="grid grid-cols-1 gap-10 md:grid-cols-2 lg:grid-cols-5"> | |
| {/* Brand column */} | |
| <div className="flex flex-col gap-4 lg:col-span-2 lg:pr-8"> | |
| <Link href="/" className="text-xl font-bold tracking-tight group inline-flex items-center gap-2"> | |
| <span className="group-hover:scale-105 transition-transform inline-block"> | |
| Nexa<span className="gradient-text">Flow</span> | |
| </span> | |
| <Sparkles className="w-4 h-4 text-primary opacity-0 group-hover:opacity-100 group-hover:rotate-12 transition-all duration-300" suppressHydrationWarning /> | |
| </Link> | |
| <p className="text-sm text-muted-foreground leading-relaxed max-w-xs"> | |
| Building digital experiences that matter. We partner with forward-thinking companies to create impactful digital products. | |
| </p> | |
| {/* Social icons */} | |
| <div className="flex gap-3 mt-2"> | |
| {socialLinks.map((social) => ( | |
| <Link | |
| key={social.label} | |
| href={social.href} | |
| className={`flex h-10 w-10 items-center justify-center rounded-xl glass-card text-muted-foreground hover:scale-110 transition-all duration-300 group ${social.color}`} | |
| aria-label={social.label} | |
| > | |
| <social.icon className="h-4 w-4 transition-transform duration-300 group-hover:scale-110" suppressHydrationWarning /> | |
| </Link> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Link columns */} | |
| {footerLinks.map((section, i) => ( | |
| <div | |
| key={section.title} | |
| className="flex flex-col gap-4" | |
| style={{ transitionDelay: `${i * 100}ms` }} | |
| > | |
| <h3 className="text-sm font-semibold text-foreground flex items-center gap-2"> | |
| <span className="w-1.5 h-1.5 rounded-full bg-primary" /> | |
| {section.title} | |
| </h3> | |
| <ul className="flex flex-col gap-3"> | |
| {section.links.map((link) => ( | |
| <li key={link.name}> | |
| <Link | |
| href={link.href} | |
| className="text-sm text-muted-foreground hover:text-primary transition-colors duration-200 interactive-underline inline-block" | |
| > | |
| {link.name} | |
| </Link> | |
| </li> | |
| ))} | |
| </ul> | |
| </div> | |
| ))} | |
| </div> | |
| {/* Newsletter signup */} | |
| <div className="mt-12 relative"> | |
| {/* Animated border */} | |
| <div className="absolute -inset-0.5 rounded-3xl animated-border opacity-30" /> | |
| <div className="relative glass-card rounded-3xl p-6 md:p-8 overflow-hidden"> | |
| {/* Inner glow */} | |
| <div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-accent/5" /> | |
| <div className="relative z-10 flex flex-col md:flex-row items-start md:items-center justify-between gap-6"> | |
| <div> | |
| <h3 className="text-lg font-semibold mb-2 flex items-center gap-2"> | |
| <Mail className="w-5 h-5 text-primary" suppressHydrationWarning /> | |
| Stay in the loop | |
| </h3> | |
| <p className="text-sm text-muted-foreground">Get the latest insights on web development and design delivered to your inbox.</p> | |
| </div> | |
| <form className="flex w-full md:w-auto gap-3" onSubmit={handleSubscribe}> | |
| <Input | |
| type="email" | |
| placeholder="you@example.com" | |
| value={email} | |
| onChange={(e) => setEmail(e.target.value)} | |
| className="w-full md:w-64 glass-card border-0 focus:ring-2 focus:ring-primary/50" | |
| /> | |
| <Button type="submit" className="shine-effect group"> | |
| {isSubscribed ? ( | |
| <span className="flex items-center gap-2"> | |
| <Sparkles className="w-4 h-4" suppressHydrationWarning /> | |
| Subscribed! | |
| </span> | |
| ) : ( | |
| <span className="flex items-center"> | |
| Subscribe | |
| <ArrowRight className="ml-2 w-4 h-4 group-hover:translate-x-1 transition-transform" suppressHydrationWarning /> | |
| </span> | |
| )} | |
| </Button> | |
| </form> | |
| </div> | |
| {/* Shine effect */} | |
| <div className="absolute inset-0 shine-effect pointer-events-none rounded-3xl" /> | |
| </div> | |
| </div> | |
| {/* Bottom bar */} | |
| <div className="mt-14 border-t border-border/50 pt-8 flex flex-col md:flex-row justify-between items-center gap-4"> | |
| <p className="text-sm text-muted-foreground"> | |
| © {new Date().getFullYear()} NexaFlow. All rights reserved. | |
| </p> | |
| <p className="text-sm text-muted-foreground flex items-center gap-1"> | |
| Designed with{" "} | |
| <Heart className="w-4 h-4 text-red-500 fill-red-500 animate-pulse" suppressHydrationWarning /> | |
| {" "}by{" "} | |
| <span className="text-primary font-medium">NexaFlow</span> | |
| </p> | |
| </div> | |
| </div> | |
| </footer> | |
| ) | |
| } | |