Yves Gugger 6d7db54021
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
feat: Portfolio improvements, listing/yield integration, UNICORN_PLAN
2025-12-15 08:04:03 +01:00

205 lines
10 KiB
TypeScript

'use client'
import Link from 'next/link'
import Image from 'next/image'
import { Twitter, Mail, Linkedin, ArrowRight } from 'lucide-react'
import { useStore } from '@/lib/store'
import { api } from '@/lib/api'
import { useCallback, useMemo, useState } from 'react'
export function Footer() {
const { isAuthenticated } = useStore()
const [newsletterEmail, setNewsletterEmail] = useState('')
const [newsletterState, setNewsletterState] = useState<'idle' | 'loading' | 'success' | 'error'>('idle')
const [newsletterError, setNewsletterError] = useState<string | null>(null)
const canSubmitNewsletter = useMemo(() => {
const email = newsletterEmail.trim()
return email.length > 3 && email.includes('@') && email.includes('.')
}, [newsletterEmail])
const handleNewsletterSubmit = useCallback(async (e: React.FormEvent) => {
e.preventDefault()
if (!canSubmitNewsletter || newsletterState === 'loading') return
setNewsletterState('loading')
setNewsletterError(null)
try {
await api.subscribeNewsletter(newsletterEmail.trim())
setNewsletterState('success')
} catch (err: any) {
setNewsletterState('error')
setNewsletterError(err?.message || 'Subscription failed. Retry.')
}
}, [canSubmitNewsletter, newsletterEmail, newsletterState])
return (
<footer className="relative border-t border-white/10 bg-[#020202] mt-auto overflow-hidden">
<div className="absolute inset-0 bg-[url('/noise.png')] opacity-[0.03] mix-blend-overlay pointer-events-none" />
<div className="max-w-[1400px] mx-auto px-4 sm:px-6 py-12 sm:py-20 relative z-10">
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 lg:gap-8 mb-10 sm:mb-16">
{/* Brand Column */}
<div className="col-span-2 md:col-span-2 lg:col-span-2">
<div className="mb-4 sm:mb-6">
<Link href="/" className="inline-block group">
<div className="flex items-center gap-2 sm:gap-3">
<Image
src="/pounce-puma.png"
alt="POUNCE"
width={32}
height={32}
className="object-contain opacity-80 group-hover:opacity-100 transition-opacity sm:w-10 sm:h-10"
/>
<span className="text-lg sm:text-xl font-black tracking-[0.1em] text-white group-hover:text-accent transition-colors font-display">
POUNCE
</span>
</div>
</Link>
</div>
<p className="text-xs sm:text-sm font-mono text-white/50 mb-6 sm:mb-8 max-w-sm leading-relaxed">
Global domain intelligence for serious investors. Scan. Acquire. Route. Yield.
</p>
{/* Newsletter - Hidden on Mobile */}
<div className="hidden sm:block mb-8 max-w-sm">
<label className="text-[10px] font-mono uppercase tracking-widest text-white/30 mb-2 block">Mission Briefings</label>
<form onSubmit={handleNewsletterSubmit} className="flex">
<input
type="email"
value={newsletterEmail}
onChange={(e) => setNewsletterEmail(e.target.value)}
placeholder="Email address"
className="w-full bg-[#0A0A0A] border border-white/10 px-4 py-3 text-white font-mono text-xs placeholder:text-white/20 focus:outline-none focus:border-accent transition-all"
/>
<button
type="submit"
disabled={!canSubmitNewsletter || newsletterState === 'loading'}
className="px-4 bg-white text-black hover:bg-accent transition-colors border-l border-white/10 disabled:opacity-50 disabled:cursor-not-allowed"
aria-label="Subscribe to briefings"
title="Subscribe"
>
<ArrowRight className="w-4 h-4" />
</button>
</form>
{newsletterState === 'success' ? (
<p className="mt-2 text-[10px] font-mono text-accent/80">Subscribed. Briefings inbound.</p>
) : newsletterState === 'error' ? (
<p className="mt-2 text-[10px] font-mono text-rose-300/80">{newsletterError}</p>
) : (
<p className="mt-2 text-[10px] font-mono text-white/20">Weekly intel. No spam.</p>
)}
</div>
<div className="flex items-center gap-3 sm:gap-4">
<a
href="https://twitter.com/pounce_domains"
target="_blank"
rel="noopener noreferrer"
className="w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center border border-white/5 hover:border-white/20 hover:bg-white/5 transition-all group"
aria-label="Twitter"
>
<Twitter className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-white/40 group-hover:text-white transition-colors" />
</a>
<a
href="https://linkedin.com"
target="_blank"
rel="noopener noreferrer"
className="w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center border border-white/5 hover:border-white/20 hover:bg-white/5 transition-all group"
aria-label="LinkedIn"
>
<Linkedin className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-white/40 group-hover:text-white transition-colors" />
</a>
<a
href="mailto:hello@pounce.ch"
className="w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center border border-white/5 hover:border-white/20 hover:bg-white/5 transition-all group"
aria-label="Email"
>
<Mail className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-white/40 group-hover:text-white transition-colors" />
</a>
</div>
</div>
{/* Protocol Links */}
<div className="col-span-1">
<h3 className="text-[10px] sm:text-xs font-bold uppercase tracking-[0.15em] sm:tracking-[0.2em] text-white mb-4 sm:mb-6">Protocol</h3>
<ul className="space-y-3 sm:space-y-4">
{[
{ href: '/acquire', label: 'Acquire' },
{ href: '/discover', label: 'Discover' },
{ href: '/yield', label: 'Yield' },
{ href: '/pricing', label: 'Pricing' },
].map((link) => (
<li key={link.href}>
<Link href={link.href} className="text-xs sm:text-sm font-mono text-white/40 hover:text-accent transition-colors flex items-center gap-1.5 sm:gap-2 group">
<span className="w-1 h-1 bg-white/20 group-hover:bg-accent transition-colors" /> {link.label}
</Link>
</li>
))}
</ul>
</div>
{/* Info Links */}
<div className="col-span-1">
<h3 className="text-[10px] sm:text-xs font-bold uppercase tracking-[0.15em] sm:tracking-[0.2em] text-white mb-4 sm:mb-6">Intel</h3>
<ul className="space-y-3 sm:space-y-4">
<li>
<Link href="/briefings" className="text-xs sm:text-sm font-mono text-white/40 hover:text-white transition-colors">Briefings</Link>
</li>
<li>
<Link href="/about" className="text-xs sm:text-sm font-mono text-white/40 hover:text-white transition-colors">About</Link>
</li>
<li>
<Link href="/contact" className="text-xs sm:text-sm font-mono text-white/40 hover:text-white transition-colors">Contact</Link>
</li>
{!isAuthenticated && (
<li>
<Link href="/login" className="text-xs sm:text-sm font-mono text-white/40 hover:text-white transition-colors">Login</Link>
</li>
)}
</ul>
</div>
{/* Legal - Hidden on Small Mobile, Merged into Intel on Mobile */}
<div className="hidden lg:block lg:col-span-1">
<h3 className="text-xs font-bold uppercase tracking-[0.2em] text-white mb-6">Legal</h3>
<ul className="space-y-4">
<li>
<Link href="/legal/privacy" className="text-sm font-mono text-white/40 hover:text-white transition-colors">Privacy</Link>
</li>
<li>
<Link href="/legal/terms" className="text-sm font-mono text-white/40 hover:text-white transition-colors">Terms</Link>
</li>
<li>
<Link href="/legal/imprint" className="text-sm font-mono text-white/40 hover:text-white transition-colors">Imprint</Link>
</li>
</ul>
</div>
</div>
{/* Mobile Legal Links */}
<div className="lg:hidden flex flex-wrap gap-4 mb-8 text-[10px] font-mono text-white/30">
<Link href="/legal/privacy" className="hover:text-white transition-colors">Privacy</Link>
<span className="text-white/10">|</span>
<Link href="/legal/terms" className="hover:text-white transition-colors">Terms</Link>
<span className="text-white/10">|</span>
<Link href="/legal/imprint" className="hover:text-white transition-colors">Imprint</Link>
</div>
{/* Bottom Bar */}
<div className="pt-6 sm:pt-8 border-t border-white/10 flex flex-col sm:flex-row justify-between items-center gap-3 sm:gap-4 text-[9px] sm:text-[10px] font-mono text-white/20 uppercase tracking-widest">
<p>© {new Date().getFullYear()} POUNCE AG ZURICH</p>
<div className="flex items-center gap-4 sm:gap-6">
<span className="flex items-center gap-1.5">
<span className="w-1.5 h-1.5 bg-accent animate-pulse" />
Online
</span>
<span>v2.0.4</span>
</div>
</div>
</div>
</footer>
)
}