feat: sessão #3 — lib (db/auth/email/validations), API routes, NextAuth v5, middleware, páginas account/shelters/shelter-dashboard, Prisma v7 fix
This commit is contained in:
241
app/main/donate/page.tsx
Normal file
241
app/main/donate/page.tsx
Normal file
@@ -0,0 +1,241 @@
|
||||
import Link from 'next/link';
|
||||
import { Gift, CreditCard, Truck, Heart } from 'lucide-react';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Fazer uma Doação',
|
||||
description: 'Doa ração, brinquedos ou apoio financeiro a canis parceiros PawLink em Portugal.',
|
||||
};
|
||||
|
||||
const donationTypes = [
|
||||
{
|
||||
id: 'monetary',
|
||||
icon: CreditCard,
|
||||
title: 'Doação Monetária',
|
||||
description: 'Transferência, cartão ou MBWay. O canil usa o valor para os cuidados que precisar.',
|
||||
badge: 'Mais impacto',
|
||||
badgeColor: 'var(--color-terra)',
|
||||
},
|
||||
{
|
||||
id: 'food',
|
||||
icon: Gift,
|
||||
title: 'Ração e Comida',
|
||||
description: 'Escolhes o tipo, a quantidade e se queres entregar em casa ou no canil.',
|
||||
badge: null,
|
||||
badgeColor: null,
|
||||
},
|
||||
{
|
||||
id: 'toys',
|
||||
icon: Heart,
|
||||
title: 'Brinquedos e Acessórios',
|
||||
description: 'Bolas, cordas, camas e muito mais. Podes escolher recolha em casa.',
|
||||
badge: null,
|
||||
badgeColor: null,
|
||||
},
|
||||
];
|
||||
|
||||
export default function DonatePage() {
|
||||
return (
|
||||
<div style={{ background: 'var(--color-bg)', minHeight: '100vh' }}>
|
||||
{/* Hero */}
|
||||
<div
|
||||
style={{
|
||||
background: 'var(--color-soil)',
|
||||
padding: 'clamp(48px, 8vw, 80px) 0',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div className="container" style={{ position: 'relative', zIndex: 1 }}>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: 'var(--font-mono, monospace)',
|
||||
fontSize: '11px',
|
||||
fontWeight: 500,
|
||||
letterSpacing: '0.12em',
|
||||
textTransform: 'uppercase',
|
||||
color: 'var(--color-amber)',
|
||||
marginBottom: '12px',
|
||||
}}
|
||||
>
|
||||
Faz a diferença hoje
|
||||
</p>
|
||||
<h1
|
||||
style={{
|
||||
fontFamily: 'var(--font-playfair, Georgia, serif)',
|
||||
fontWeight: 900,
|
||||
fontSize: 'clamp(36px, 6vw, 60px)',
|
||||
color: 'var(--color-cream)',
|
||||
lineHeight: 1.1,
|
||||
maxWidth: '560px',
|
||||
marginBottom: '16px',
|
||||
}}
|
||||
>
|
||||
Doa ao teu canil{' '}
|
||||
<em style={{ color: 'var(--color-amber)', fontStyle: 'italic' }}>favorito.</em>
|
||||
</h1>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: 'var(--font-body)',
|
||||
fontSize: '16px',
|
||||
color: 'rgba(250,246,240,0.65)',
|
||||
maxWidth: '440px',
|
||||
lineHeight: 1.65,
|
||||
}}
|
||||
>
|
||||
Ração, brinquedos ou apoio financeiro. Escolhe como queres ajudar.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Donation types */}
|
||||
<div className="container" style={{ padding: 'clamp(40px, 6vw, 64px) 16px' }}>
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: 'var(--font-playfair, Georgia, serif)',
|
||||
fontWeight: 900,
|
||||
fontSize: 'clamp(24px, 4vw, 36px)',
|
||||
color: 'var(--color-text)',
|
||||
marginBottom: '32px',
|
||||
}}
|
||||
>
|
||||
Como queres ajudar?
|
||||
</h2>
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))',
|
||||
gap: '20px',
|
||||
marginBottom: '48px',
|
||||
}}
|
||||
>
|
||||
{donationTypes.map(({ id, icon: Icon, title, description, badge, badgeColor }) => (
|
||||
<div
|
||||
key={id}
|
||||
style={{
|
||||
background: 'var(--color-surface)',
|
||||
border: '1.5px solid var(--color-border)',
|
||||
borderRadius: '16px',
|
||||
padding: '28px 24px',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 200ms ease',
|
||||
position: 'relative',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
const el = e.currentTarget as HTMLElement;
|
||||
el.style.borderColor = 'var(--color-terra)';
|
||||
el.style.transform = 'translateY(-4px)';
|
||||
el.style.boxShadow = '0 12px 40px rgba(45,27,14,0.1)';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const el = e.currentTarget as HTMLElement;
|
||||
el.style.borderColor = 'var(--color-border)';
|
||||
el.style.transform = 'translateY(0)';
|
||||
el.style.boxShadow = 'none';
|
||||
}}
|
||||
>
|
||||
{badge && (
|
||||
<span
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '16px',
|
||||
right: '16px',
|
||||
background: badgeColor || 'var(--color-terra)',
|
||||
color: 'white',
|
||||
fontFamily: 'var(--font-mono, monospace)',
|
||||
fontSize: '9px',
|
||||
fontWeight: 500,
|
||||
letterSpacing: '0.08em',
|
||||
textTransform: 'uppercase',
|
||||
padding: '3px 8px',
|
||||
borderRadius: '100px',
|
||||
}}
|
||||
>
|
||||
{badge}
|
||||
</span>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
width: '48px',
|
||||
height: '48px',
|
||||
background: 'var(--color-terra-light)',
|
||||
borderRadius: '12px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: '16px',
|
||||
}}
|
||||
>
|
||||
<Icon size={22} style={{ color: 'var(--color-terra)' }} />
|
||||
</div>
|
||||
<h3
|
||||
style={{
|
||||
fontFamily: 'var(--font-display)',
|
||||
fontWeight: 700,
|
||||
fontSize: '20px',
|
||||
color: 'var(--color-text)',
|
||||
marginBottom: '8px',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</h3>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: 'var(--font-body)',
|
||||
fontSize: '14px',
|
||||
lineHeight: 1.65,
|
||||
color: 'var(--color-muted)',
|
||||
marginBottom: '20px',
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
<button
|
||||
className="btn-primary"
|
||||
style={{ width: '100%', justifyContent: 'center', fontSize: '13px', padding: '12px 20px', minHeight: '44px' }}
|
||||
aria-label={`Seleccionar: ${title}`}
|
||||
>
|
||||
Escolher
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Auth notice */}
|
||||
<div
|
||||
style={{
|
||||
background: 'var(--color-linen)',
|
||||
border: '1px solid var(--color-border)',
|
||||
borderRadius: '12px',
|
||||
padding: '20px 24px',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
gap: '16px',
|
||||
}}
|
||||
>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: 'var(--font-body)',
|
||||
fontSize: '15px',
|
||||
color: 'var(--color-text)',
|
||||
maxWidth: '400px',
|
||||
}}
|
||||
>
|
||||
Para fazer uma doação precisas de ter conta PawLink. É grátis, rápido e seguro.
|
||||
</p>
|
||||
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
||||
<Link href="/auth/register" className="btn-primary" style={{ fontSize: '13px', padding: '12px 20px', minHeight: '44px' }}>
|
||||
Criar conta
|
||||
</Link>
|
||||
<Link href="/auth/login" className="btn-secondary" style={{ fontSize: '13px', padding: '12px 20px', minHeight: '44px' }}>
|
||||
Entrar
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user