'use client';
import { useState, useEffect } from 'react';
import { notFound } from 'next/navigation';
import Image from 'next/image';
import Link from 'next/link';
import {
MapPin,
Clock,
CheckCircle2,
AlertTriangle,
ChevronRight,
ChevronLeft,
Heart,
X,
PawPrint,
Phone,
Mail,
ArrowLeft,
} from 'lucide-react';
import { MOCK_ANIMALS, formatAge, formatSex, Animal } from '@/lib/mock-data';
// TODO: substituir por query Prisma quando DATABASE_URL estiver configurada
function ConfirmationOverlay({ animal, onClose }: { animal: Animal; onClose: () => void }) {
const [pieces] = useState(() =>
Array.from({ length: 20 }, (_, i) => ({
id: i,
x: Math.random() * 100,
color: ['#C4501A', '#E8952A', '#3D6B4F', '#2D1B0E'][Math.floor(Math.random() * 4)],
delay: Math.random() * 0.8,
duration: 1.5 + Math.random() * 1.5,
size: 6 + Math.random() * 10,
}))
);
return (
{/* Confetti */}
{pieces.map(p => (
))}
{/* Card */}
{/* Paw icon */}
Pedido enviado! 🎉
O teu pedido de adopção do{' '}
{animal.name} {' '}
foi enviado para o{' '}
{animal.shelter.name} .
Vais receber um email de confirmação em breve.
Ver a minha reserva
Voltar à ficha
);
}
function Lightbox({ photos, initial, onClose }: { photos: string[]; initial: number; onClose: () => void }) {
const [current, setCurrent] = useState(initial);
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
if (e.key === 'ArrowRight') setCurrent(c => (c + 1) % photos.length);
if (e.key === 'ArrowLeft') setCurrent(c => (c - 1 + photos.length) % photos.length);
};
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
}, [photos.length, onClose]);
return (
{photos.length > 1 && (
<>
{ e.stopPropagation(); setCurrent(c => (c - 1 + photos.length) % photos.length); }}
style={{
position: 'absolute',
left: '16px',
top: '50%',
transform: 'translateY(-50%)',
background: 'rgba(255,255,255,0.1)',
border: 'none',
borderRadius: '50%',
width: '44px',
height: '44px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
color: 'white',
}}
aria-label="Foto anterior"
>
{ e.stopPropagation(); setCurrent(c => (c + 1) % photos.length); }}
style={{
position: 'absolute',
right: '16px',
top: '50%',
transform: 'translateY(-50%)',
background: 'rgba(255,255,255,0.1)',
border: 'none',
borderRadius: '50%',
width: '44px',
height: '44px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
color: 'white',
}}
aria-label="Próxima foto"
>
>
)}
e.stopPropagation()}
>
);
}
export default function AnimalDetailPage({ params }: { params: { id: string } }) {
const animal = MOCK_ANIMALS.find(a => a.id === params.id);
const [mainPhoto, setMainPhoto] = useState(0);
const [lightboxOpen, setLightboxOpen] = useState(false);
const [lightboxPhoto, setLightboxPhoto] = useState(0);
const [showConfirmation, setShowConfirmation] = useState(false);
if (!animal) return notFound();
const ageLabel = formatAge(animal.ageMonths);
const openLightbox = (index: number) => {
setLightboxPhoto(index);
setLightboxOpen(true);
};
return (
<>
{/* Lightbox */}
{lightboxOpen && (
setLightboxOpen(false)}
/>
)}
{/* Confirmation overlay */}
{showConfirmation && (
setShowConfirmation(false)} />
)}
{/* Breadcrumb */}
((e.currentTarget as HTMLElement).style.color = 'var(--color-terra)')}
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.color = 'var(--color-muted)')}
aria-label="Voltar à listagem de animais"
>
Todos os animais
{/* Main content */}
{/* Left — Gallery */}
{/* Main image */}
openLightbox(mainPhoto)}
role="button"
aria-label={`Ver foto ${mainPhoto + 1} em tamanho completo`}
tabIndex={0}
onKeyDown={e => e.key === 'Enter' && openLightbox(mainPhoto)}
>
{animal.urgent && (
)}
{/* Thumbnails */}
{animal.photos.length > 1 && (
{animal.photos.map((photo, i) => (
setMainPhoto(i)}
style={{
width: '72px',
height: '54px',
borderRadius: '8px',
overflow: 'hidden',
position: 'relative',
border: `2px solid ${i === mainPhoto ? 'var(--color-terra)' : 'var(--color-border)'}`,
cursor: 'pointer',
transition: 'border-color 180ms ease',
padding: 0,
background: 'none',
}}
aria-label={`Ver foto ${i + 1}`}
aria-pressed={i === mainPhoto}
>
))}
)}
{/* Right — Info */}
{/* Name & tags */}
{animal.name}
{[animal.breed, ageLabel, animal.sex === 'MALE' ? '♂ Macho' : '♀ Fêmea'].map((tag) => (
{tag}
))}
{animal.sterilized && (
Esterilizado/a
)}
{/* About section */}
Sobre o {animal.name}
{animal.description}
{/* Shelter info */}
Canil responsável
{animal.shelter.name}
{animal.shelter.address}
{animal.shelter.openHours}
{/* CTA — desktop */}
setShowConfirmation(true)}
id="animal-adopt-btn"
aria-label={`Adoptar ${animal.name} — enviar pedido ao ${animal.shelter.name}`}
>
Adoptar o {animal.name}
Precisas de ter conta para adoptar. É gratuito e leva 2 minutos.
{/* Sticky CTA bar — mobile */}
Guardar
setShowConfirmation(true)}
id="animal-adopt-mobile-btn"
aria-label={`Adoptar ${animal.name}`}
>
Adoptar o {animal.name}
>
);
}