'use client'; import { useEffect, useRef, useState } from 'react'; import Link from 'next/link'; import { ChevronRight, PawPrint, Heart, ArrowRight } from 'lucide-react'; import Header from '@/components/layout/Header'; import Footer from '@/components/layout/Footer'; import AnimalCard from '@/components/animals/AnimalCard'; import FilterChips, { FILTER_OPTIONS } from '@/components/animals/FilterChips'; import { MOCK_ANIMALS, Animal } from '@/lib/mock-data'; function useCountUp(target: number, duration = 1800) { const [count, setCount] = useState(0); const [started, setStarted] = useState(false); useEffect(() => { if (!started) return; const start = performance.now(); const tick = (now: number) => { const elapsed = now - start; const progress = Math.min(elapsed / duration, 1); const eased = 1 - Math.pow(1 - progress, 3); setCount(Math.floor(eased * target)); if (progress < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); }, [started, target, duration]); return { count, setStarted }; } function AnimatedCounter({ target, label }: { target: number; label: string }) { const ref = useRef(null); const { count, setStarted } = useCountUp(target); useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) setStarted(true); }, { threshold: 0.5 } ); if (ref.current) observer.observe(ref.current); return () => observer.disconnect(); }, [setStarted]); return (
{count.toLocaleString('pt-PT')}
{label}
); } function filterAnimals(animals: Animal[], filter: string): Animal[] { switch (filter) { case 'dog': return animals.filter(a => a.species === 'DOG'); case 'cat': return animals.filter(a => a.species === 'CAT'); case 'urgent': return animals.filter(a => a.urgent); case 'lisboa': return animals.filter(a => a.shelter.district.toLowerCase() === 'lisboa'); case 'porto': return animals.filter(a => a.shelter.district.toLowerCase() === 'porto'); case 'braga': return animals.filter(a => a.shelter.district.toLowerCase() === 'braga'); case 'sintra': return animals.filter(a => a.shelter.district.toLowerCase() === 'sintra'); case 'male': return animals.filter(a => a.sex === 'MALE'); case 'female': return animals.filter(a => a.sex === 'FEMALE'); case 'sterilized': return animals.filter(a => a.sterilized); default: return animals; } } export default function HomePage() { const [activeFilter, setActiveFilter] = useState('all'); const [displayed, setDisplayed] = useState(MOCK_ANIMALS.slice(0, 8)); useEffect(() => { const filtered = filterAnimals(MOCK_ANIMALS, activeFilter); setDisplayed(filtered.slice(0, 8)); }, [activeFilter]); return ( <>
{/* ── Hero ───────────────────────────────────────────────── */}
{/* ── Animais em Destaque ────────────────────────────────── */}
{/* Cabeçalho da secção */}

Disponíveis agora

Animais à espera
de ti.

Ver todos
{/* Filtros */}
{/* Grelha */} {displayed.length > 0 ? (
{displayed.map((animal, index) => ( ))}
) : (

Nenhum animal encontrado com esse filtro.

)} {displayed.length > 0 && (
Ver todos os animais
)}
{/* ── Como Funciona ──────────────────────────────────────── */}

Simples e transparente

Como funciona

{[ { step: '01', emoji: '🐾', title: 'Descobre', desc: 'Navega pelos animais disponíveis e filtra por distrito, espécie ou características.' }, { step: '02', emoji: '💛', title: 'Liga-te', desc: 'Lê a ficha completa, vê as fotos e conhece a história do animal.' }, { step: '03', emoji: '📅', title: 'Reserva', desc: 'Faz a reserva online e recebe confirmação por email. Simples e seguro.' }, { step: '04', emoji: '🏡', title: 'Adopta', desc: 'Vai ao canil na data marcada e leva o teu novo companheiro para casa.' }, ].map(({ step, emoji, title, desc }) => (
{ const el = e.currentTarget as HTMLElement; el.style.transform = 'translateY(-4px)'; el.style.boxShadow = 'var(--shadow-warm-md)'; }} onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.transform = 'translateY(0)'; el.style.boxShadow = 'none'; }} >
{emoji} {step}

{title}

{desc}

))}
{/* ── Doações ────────────────────────────────────────────── */}

Também podes ajudar assim

Doa ração, brinquedos ou apoio financeiro. Tu escolhes como ajudar.

{[ { href: '/main/donate?type=monetary', emoji: '💸', label: 'Doação Monetária', desc: 'Contribui directamente para os cuidados veterinários e alimentação.' }, { href: '/main/donate?type=food', emoji: '🥩', label: 'Doação de Ração', desc: 'Escolhe a quantidade e enviamos ao canil da tua escolha.' }, { href: '/main/donate?type=toys', emoji: '🎾', label: 'Brinquedos', desc: 'Enriquecimento ambiental para animais em espera de adopção.' }, ].map(({ href, emoji, label, desc }) => (
{ const el = e.currentTarget as HTMLElement; el.style.transform = 'translateY(-8px)'; el.style.boxShadow = 'var(--shadow-warm-lg)'; }} onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.transform = 'translateY(0)'; el.style.boxShadow = 'var(--shadow-warm-sm)'; }} >
{emoji}

{label}

{desc}

Saber mais
))}