refactor: renomear PawLink → PetLink em todos os ficheiros
This commit is contained in:
@@ -45,7 +45,7 @@ export async function POST(request: Request) {
|
|||||||
// Email de boas-vindas (não bloqueia)
|
// Email de boas-vindas (não bloqueia)
|
||||||
sendEmail({
|
sendEmail({
|
||||||
to: user.email,
|
to: user.email,
|
||||||
subject: 'Bem-vindo à PawLink 🐾',
|
subject: 'Bem-vindo à PetLink 🐾',
|
||||||
html: buildWelcomeHtml({ userName: user.name }),
|
html: buildWelcomeHtml({ userName: user.name }),
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default function ForgotPasswordPage() {
|
|||||||
>
|
>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '28px' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '28px' }}>
|
||||||
<PawPrint size={20} style={{ color: 'var(--terra)' }} />
|
<PawPrint size={20} style={{ color: 'var(--terra)' }} />
|
||||||
<span className="logo" style={{ fontSize: '18px' }}>PawLink</span>
|
<span className="logo" style={{ fontSize: '18px' }}>PetLink</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: '26px', color: 'var(--soil)', marginBottom: '8px', lineHeight: 1.15 }}>
|
<h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: '26px', color: 'var(--soil)', marginBottom: '8px', lineHeight: 1.15 }}>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export default function LoginPage() {
|
|||||||
color: 'var(--color-terra)',
|
color: 'var(--color-terra)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
PawLink
|
PetLink
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ export default function LoginPage() {
|
|||||||
opacity: loading ? 0.75 : 1,
|
opacity: loading ? 0.75 : 1,
|
||||||
cursor: loading ? 'not-allowed' : 'pointer',
|
cursor: loading ? 'not-allowed' : 'pointer',
|
||||||
}}
|
}}
|
||||||
aria-label="Entrar na conta PawLink"
|
aria-label="Entrar na conta PetLink"
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
<span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export default function RegisterPage() {
|
|||||||
Conta criada!
|
Conta criada!
|
||||||
</h1>
|
</h1>
|
||||||
<p style={{ fontFamily: 'var(--font-body)', color: 'var(--soil-mid)', marginBottom: '24px', lineHeight: 1.6 }}>
|
<p style={{ fontFamily: 'var(--font-body)', color: 'var(--soil-mid)', marginBottom: '24px', lineHeight: 1.6 }}>
|
||||||
Bem-vindo/a à PawLink. Já podes explorar animais e fazer adopções.
|
Bem-vindo/a à PetLink. Já podes explorar animais e fazer adopções.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/auth/login" className="btn btn-primary" style={{ justifyContent: 'center' }}>
|
<Link href="/auth/login" className="btn btn-primary" style={{ justifyContent: 'center' }}>
|
||||||
Entrar na conta
|
Entrar na conta
|
||||||
@@ -106,7 +106,7 @@ export default function RegisterPage() {
|
|||||||
{/* Marca */}
|
{/* Marca */}
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '28px' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '28px' }}>
|
||||||
<PawPrint size={20} style={{ color: 'var(--terra)' }} />
|
<PawPrint size={20} style={{ color: 'var(--terra)' }} />
|
||||||
<span className="logo" style={{ fontSize: '18px' }}>PawLink</span>
|
<span className="logo" style={{ fontSize: '18px' }}>PetLink</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: '28px', color: 'var(--soil)', marginBottom: '6px', lineHeight: 1.15 }}>
|
<h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: '28px', color: 'var(--soil)', marginBottom: '6px', lineHeight: 1.15 }}>
|
||||||
@@ -201,7 +201,7 @@ export default function RegisterPage() {
|
|||||||
className="btn btn-primary"
|
className="btn btn-primary"
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
style={{ width: '100%', justifyContent: 'center', marginTop: '8px', opacity: loading ? 0.75 : 1, cursor: loading ? 'not-allowed' : 'pointer' }}
|
style={{ width: '100%', justifyContent: 'center', marginTop: '8px', opacity: loading ? 0.75 : 1, cursor: loading ? 'not-allowed' : 'pointer' }}
|
||||||
aria-label="Criar conta PawLink"
|
aria-label="Criar conta PetLink"
|
||||||
>
|
>
|
||||||
{loading ? 'A criar conta…' : 'Criar conta'}
|
{loading ? 'A criar conta…' : 'Criar conta'}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "tw-animate-css";
|
@import "tw-animate-css";
|
||||||
|
|
||||||
/* ─── PawLink Design System — Editorial Orgânico ────────────── */
|
/* ─── PetLink Design System — Editorial Orgânico ────────────── */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* ── Núcleo da paleta ─────────────────────────── */
|
/* ── Núcleo da paleta ─────────────────────────── */
|
||||||
|
|||||||
@@ -27,21 +27,21 @@ const fragmentMono = Fragment_Mono({
|
|||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
default: 'PawLink — Adopção de Animais em Portugal',
|
default: 'PetLink — Adopção de Animais em Portugal',
|
||||||
template: '%s | PawLink',
|
template: '%s | PetLink',
|
||||||
},
|
},
|
||||||
description:
|
description:
|
||||||
'Encontra o teu companheiro para a vida. PawLink conecta adoptantes, doadores e canis em todo o território português.',
|
'Encontra o teu companheiro para a vida. PetLink conecta adoptantes, doadores e canis em todo o território português.',
|
||||||
keywords: ['adopção animais', 'canis portugal', 'adoptar cão', 'adoptar gato', 'doação canil'],
|
keywords: ['adopção animais', 'canis portugal', 'adoptar cão', 'adoptar gato', 'doação canil'],
|
||||||
authors: [{ name: 'PawLink' }],
|
authors: [{ name: 'PetLink' }],
|
||||||
creator: 'PawLink',
|
creator: 'PetLink',
|
||||||
metadataBase: new URL('https://pawlink.pt'),
|
metadataBase: new URL('https://petlink.pt'),
|
||||||
openGraph: {
|
openGraph: {
|
||||||
type: 'website',
|
type: 'website',
|
||||||
locale: 'pt_PT',
|
locale: 'pt_PT',
|
||||||
url: 'https://pawlink.pt',
|
url: 'https://petlink.pt',
|
||||||
siteName: 'PawLink',
|
siteName: 'PetLink',
|
||||||
title: 'PawLink — Adopção de Animais em Portugal',
|
title: 'PetLink — Adopção de Animais em Portugal',
|
||||||
description: 'Encontra o teu companheiro para a vida.',
|
description: 'Encontra o teu companheiro para a vida.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export default function AnimalsPage() {
|
|||||||
marginBottom: '12px',
|
marginBottom: '12px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
PawLink · Adopção
|
PetLink · Adopção
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { Metadata } from 'next';
|
|||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Fazer uma Doação',
|
title: 'Fazer uma Doação',
|
||||||
description: 'Doa ração, brinquedos ou apoio financeiro a canis parceiros PawLink em Portugal.',
|
description: 'Doa ração, brinquedos ou apoio financeiro a canis parceiros PetLink em Portugal.',
|
||||||
};
|
};
|
||||||
|
|
||||||
const donationTypes = [
|
const donationTypes = [
|
||||||
@@ -224,7 +224,7 @@ export default function DonatePage() {
|
|||||||
maxWidth: '400px',
|
maxWidth: '400px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Para fazer uma doação precisas de ter conta PawLink. É grátis, rápido e seguro.
|
Para fazer uma doação precisas de ter conta PetLink. É grátis, rápido e seguro.
|
||||||
</p>
|
</p>
|
||||||
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
||||||
<Link href="/auth/register" className="btn-primary" style={{ fontSize: '13px', padding: '12px 20px', minHeight: '44px' }}>
|
<Link href="/auth/register" className="btn-primary" style={{ fontSize: '13px', padding: '12px 20px', minHeight: '44px' }}>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import Link from 'next/link';
|
|||||||
import { PawPrint, Home } from 'lucide-react';
|
import { PawPrint, Home } from 'lucide-react';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Painel do Canil | PawLink',
|
title: 'Painel do Canil | PetLink',
|
||||||
description: 'Área de gestão do canil na plataforma PawLink.',
|
description: 'Área de gestão do canil na plataforma PetLink.',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ShelterLayout({ children }: { children: React.ReactNode }) {
|
export default function ShelterLayout({ children }: { children: React.ReactNode }) {
|
||||||
@@ -28,7 +28,7 @@ export default function ShelterLayout({ children }: { children: React.ReactNode
|
|||||||
<Link href="/shelter/dashboard" style={{ display: 'flex', alignItems: 'center', gap: '8px', textDecoration: 'none' }}>
|
<Link href="/shelter/dashboard" style={{ display: 'flex', alignItems: 'center', gap: '8px', textDecoration: 'none' }}>
|
||||||
<PawPrint size={20} style={{ color: 'var(--terra)' }} />
|
<PawPrint size={20} style={{ color: 'var(--terra)' }} />
|
||||||
<span style={{ fontFamily: 'var(--font-display)', fontStyle: 'italic', fontWeight: 700, fontSize: '17px', color: 'var(--terra)' }}>
|
<span style={{ fontFamily: 'var(--font-display)', fontStyle: 'italic', fontWeight: 700, fontSize: '17px', color: 'var(--terra)' }}>
|
||||||
PawLink Canil
|
PetLink Canil
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export default function Footer() {
|
|||||||
color: 'var(--color-terra)',
|
color: 'var(--color-terra)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
PawLink
|
PetLink
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
@@ -156,7 +156,7 @@ export default function Footer() {
|
|||||||
>
|
>
|
||||||
Feito com
|
Feito com
|
||||||
<Heart size={12} style={{ color: 'var(--color-terra)', fill: 'var(--color-terra)' }} />
|
<Heart size={12} style={{ color: 'var(--color-terra)', fill: 'var(--color-terra)' }} />
|
||||||
em Portugal · PawLink © {new Date().getFullYear()}
|
em Portugal · PetLink © {new Date().getFullYear()}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ export default function Header() {
|
|||||||
<>
|
<>
|
||||||
<header className={`header${scrolled ? ' scrolled' : ''}`}>
|
<header className={`header${scrolled ? ' scrolled' : ''}`}>
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link href="/" className="logo" aria-label="PawLink — Início">
|
<Link href="/" className="logo" aria-label="PetLink — Início">
|
||||||
<PawPrint size={22} strokeWidth={2.5} />
|
<PawPrint size={22} strokeWidth={2.5} />
|
||||||
PawLink
|
PetLink
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Hambúrguer animado */}
|
{/* Hambúrguer animado */}
|
||||||
|
|||||||
@@ -93,10 +93,10 @@ export default function SideMenu({ open, onClose }: SideMenuProps) {
|
|||||||
className="logo"
|
className="logo"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
style={{ fontSize: '18px' }}
|
style={{ fontSize: '18px' }}
|
||||||
aria-label="PawLink — Início"
|
aria-label="PetLink — Início"
|
||||||
>
|
>
|
||||||
<PawPrint size={18} strokeWidth={2.5} />
|
<PawPrint size={18} strokeWidth={2.5} />
|
||||||
PawLink
|
PetLink
|
||||||
</Link>
|
</Link>
|
||||||
<button
|
<button
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ Os canis dependem maioritariamente de redes sociais e contacto telefónico para
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1.2 A Solução — PawLink
|
## 1.2 A Solução — PetLink
|
||||||
|
|
||||||
**PawLink** é uma plataforma web que centraliza a adopção de animais e a gestão de doações para canis em todo o território português. A plataforma conecta potenciais adoptantes, doadores e canis numa interface intuitiva, segura e moderna.
|
**PetLink** é uma plataforma web que centraliza a adopção de animais e a gestão de doações para canis em todo o território português. A plataforma conecta potenciais adoptantes, doadores e canis numa interface intuitiva, segura e moderna.
|
||||||
|
|
||||||
**Missão:** Reduzir o número de animais em canis portugueses através da tecnologia, tornando a adopção responsável e a doação de bens o caminho mais fácil e natural.
|
**Missão:** Reduzir o número de animais em canis portugueses através da tecnologia, tornando a adopção responsável e a doação de bens o caminho mais fácil e natural.
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ Os canis dependem maioritariamente de redes sociais e contacto telefónico para
|
|||||||
| Adoptante | Adulto(a) +18 anos, residente em Portugal | Encontrar animal compatível próximo da sua localidade |
|
| Adoptante | Adulto(a) +18 anos, residente em Portugal | Encontrar animal compatível próximo da sua localidade |
|
||||||
| Doador | Pessoa física ou empresa | Contribuir financeiramente ou com bens para canis |
|
| Doador | Pessoa física ou empresa | Contribuir financeiramente ou com bens para canis |
|
||||||
| Canil / Associação | Instituição de protecção animal | Gerir animais, reservas e doações recebidas |
|
| Canil / Associação | Instituição de protecção animal | Gerir animais, reservas e doações recebidas |
|
||||||
| Administrador | Equipa PawLink | Supervisionar toda a plataforma e garantir qualidade |
|
| Administrador | Equipa PetLink | Supervisionar toda a plataforma e garantir qualidade |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -70,4 +70,4 @@
|
|||||||
- A plataforma deve estar em conformidade com o **RGPD** (Regulamento Geral sobre a Protecção de Dados) e legislação portuguesa
|
- A plataforma deve estar em conformidade com o **RGPD** (Regulamento Geral sobre a Protecção de Dados) e legislação portuguesa
|
||||||
- Os pagamentos devem ser processados por um fornecedor certificado **PCI DSS** (Stripe)
|
- Os pagamentos devem ser processados por um fornecedor certificado **PCI DSS** (Stripe)
|
||||||
- O registo é **exclusivo para maiores de 18 anos** — validação obrigatória no servidor
|
- O registo é **exclusivo para maiores de 18 anos** — validação obrigatória no servidor
|
||||||
- Apenas canis registados e verificados pela equipa PawLink podem listar animais para adopção
|
- Apenas canis registados e verificados pela equipa PetLink podem listar animais para adopção
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## 3.1 Visão Geral
|
## 3.1 Visão Geral
|
||||||
|
|
||||||
A arquitectura da PawLink segue o padrão de aplicação web moderna com separação clara entre frontend, backend e serviços externos. Adoptamos uma abordagem **server-first** com Next.js, que permite renderização no servidor (SSR) para melhor SEO e desempenho inicial, combinada com componentes interactivos no cliente onde necessário.
|
A arquitectura da PetLink segue o padrão de aplicação web moderna com separação clara entre frontend, backend e serviços externos. Adoptamos uma abordagem **server-first** com Next.js, que permite renderização no servidor (SSR) para melhor SEO e desempenho inicial, combinada com componentes interactivos no cliente onde necessário.
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."
|
|||||||
|
|
||||||
# Email
|
# Email
|
||||||
RESEND_API_KEY="re_..."
|
RESEND_API_KEY="re_..."
|
||||||
RESEND_FROM_EMAIL="noreply@pawlink.pt"
|
RESEND_FROM_EMAIL="noreply@petlink.pt"
|
||||||
|
|
||||||
# Supabase Storage
|
# Supabase Storage
|
||||||
NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"
|
NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"
|
||||||
@@ -106,7 +106,7 @@ Next.js tem o ecossistema mais maduro para aplicações React complexas com SSR.
|
|||||||
|
|
||||||
### Porque PostgreSQL em vez de MongoDB?
|
### Porque PostgreSQL em vez de MongoDB?
|
||||||
|
|
||||||
Os dados da PawLink são fortemente relacionais (utilizador → reserva → animal → canil). Uma base de dados relacional como PostgreSQL garante integridade referencial por defeito, suporta transacções ACID (críticas para reservas e pagamentos) e tem melhor suporte a queries complexas com joins.
|
Os dados da PetLink são fortemente relacionais (utilizador → reserva → animal → canil). Uma base de dados relacional como PostgreSQL garante integridade referencial por defeito, suporta transacções ACID (críticas para reservas e pagamentos) e tem melhor suporte a queries complexas com joins.
|
||||||
|
|
||||||
### Porque Tailwind CSS em vez de CSS Modules ou Styled Components?
|
### Porque Tailwind CSS em vez de CSS Modules ou Styled Components?
|
||||||
|
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ Todos os uploads são validados antes de armazenar no Supabase Storage:
|
|||||||
|
|
||||||
## 7.3 Conformidade com o RGPD
|
## 7.3 Conformidade com o RGPD
|
||||||
|
|
||||||
| Princípio RGPD | Implementação na PawLink |
|
| Princípio RGPD | Implementação na PetLink |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Consentimento explícito** | Checkbox obrigatório no registo com link para Política de Privacidade. Consentimento separado para emails de marketing (opcional). |
|
| **Consentimento explícito** | Checkbox obrigatório no registo com link para Política de Privacidade. Consentimento separado para emails de marketing (opcional). |
|
||||||
| **Finalidade limitada** | Dados pessoais usados apenas para adopção e doação — não partilhados com terceiros excepto processadores necessários (Stripe, Resend). |
|
| **Finalidade limitada** | Dados pessoais usados apenas para adopção e doação — não partilhados com terceiros excepto processadores necessários (Stripe, Resend). |
|
||||||
@@ -175,7 +175,7 @@ Não são usados cookies de rastreamento ou publicidade.
|
|||||||
|
|
||||||
## 7.4 Segurança dos Pagamentos
|
## 7.4 Segurança dos Pagamentos
|
||||||
|
|
||||||
- Dados de cartão **nunca passam pelos servidores da PawLink** — tratados directamente pelo Stripe via Payment Element
|
- Dados de cartão **nunca passam pelos servidores da PetLink** — tratados directamente pelo Stripe via Payment Element
|
||||||
- Stripe é certificado **PCI DSS Level 1** — o mais elevado nível de conformidade
|
- Stripe é certificado **PCI DSS Level 1** — o mais elevado nível de conformidade
|
||||||
- Webhooks Stripe verificados com **assinatura HMAC-SHA256** — previne falsificação de eventos de pagamento
|
- Webhooks Stripe verificados com **assinatura HMAC-SHA256** — previne falsificação de eventos de pagamento
|
||||||
- Montantes validados no servidor antes de criar PaymentIntent — cliente não pode alterar o valor
|
- Montantes validados no servidor antes de criar PaymentIntent — cliente não pode alterar o valor
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ interface MatchContext {
|
|||||||
// lib/ai/prompts.ts
|
// lib/ai/prompts.ts
|
||||||
|
|
||||||
export const MATCH_SYSTEM_PROMPT = `
|
export const MATCH_SYSTEM_PROMPT = `
|
||||||
És um especialista em adopção responsável de animais da plataforma PawLink,
|
És um especialista em adopção responsável de animais da plataforma PetLink,
|
||||||
em Portugal. O teu papel é ajudar utilizadores a encontrar o animal de estimação
|
em Portugal. O teu papel é ajudar utilizadores a encontrar o animal de estimação
|
||||||
mais compatível com o seu estilo de vida.
|
mais compatível com o seu estilo de vida.
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ O assistente responde em tempo real usando **streaming** para melhor experiênci
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export const SUPPORT_SYSTEM_PROMPT = `
|
export const SUPPORT_SYSTEM_PROMPT = `
|
||||||
És o assistente virtual da PawLink, uma plataforma portuguesa de adopção de
|
És o assistente virtual da PetLink, uma plataforma portuguesa de adopção de
|
||||||
animais e doação a canis. Chamas-te Paws.
|
animais e doação a canis. Chamas-te Paws.
|
||||||
|
|
||||||
PAPEL:
|
PAPEL:
|
||||||
@@ -148,7 +148,7 @@ LIMITAÇÕES:
|
|||||||
- Não tens acesso a informação em tempo real sobre animais específicos ou
|
- Não tens acesso a informação em tempo real sobre animais específicos ou
|
||||||
disponibilidade actual (sugere usar os filtros da plataforma)
|
disponibilidade actual (sugere usar os filtros da plataforma)
|
||||||
- Não podes processar pagamentos ou fazer reservas directamente
|
- Não podes processar pagamentos ou fazer reservas directamente
|
||||||
- Para questões técnicas graves, sugere contacto via email: suporte@pawlink.pt
|
- Para questões técnicas graves, sugere contacto via email: suporte@petlink.pt
|
||||||
|
|
||||||
TOM:
|
TOM:
|
||||||
- Caloroso, encorajador e amigável
|
- Caloroso, encorajador e amigável
|
||||||
@@ -193,7 +193,7 @@ export function SupportChat() {
|
|||||||
initialMessages: [{
|
initialMessages: [{
|
||||||
id: 'welcome',
|
id: 'welcome',
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: 'Olá! Sou o Paws, o assistente da PawLink. Como posso ajudar-te hoje? 🐾'
|
content: 'Olá! Sou o Paws, o assistente da PetLink. Como posso ajudar-te hoje? 🐾'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ import { test, expect } from '@playwright/test';
|
|||||||
test('fluxo completo de adopção', async ({ page }) => {
|
test('fluxo completo de adopção', async ({ page }) => {
|
||||||
// Login
|
// Login
|
||||||
await page.goto('/login');
|
await page.goto('/login');
|
||||||
await page.fill('[name="email"]', 'teste@pawlink.pt');
|
await page.fill('[name="email"]', 'teste@petlink.pt');
|
||||||
await page.fill('[name="password"]', 'Password123!');
|
await page.fill('[name="password"]', 'Password123!');
|
||||||
await page.click('[type="submit"]');
|
await page.click('[type="submit"]');
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Canis base Brinquedos Match inteligente Internacionali
|
|||||||
| Email de confirmação de reserva (react-email + Resend) | Crítica | 3 dias | Reservas |
|
| Email de confirmação de reserva (react-email + Resend) | Crítica | 3 dias | Reservas |
|
||||||
| Área de conta: histórico de adopções e definições | Média | 4 dias | Auth |
|
| Área de conta: histórico de adopções e definições | Média | 4 dias | Auth |
|
||||||
| Menu lateral + modo escuro/claro | Média | 3 dias | — |
|
| Menu lateral + modo escuro/claro | Média | 3 dias | — |
|
||||||
| Deploy inicial na Vercel + domínio pawlink.pt | Alta | 1 dia | Tudo acima |
|
| Deploy inicial na Vercel + domínio petlink.pt | Alta | 1 dia | Tudo acima |
|
||||||
| **Total Fase 1** | | **~10 semanas** | |
|
| **Total Fase 1** | | **~10 semanas** | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# PawLink — Registo de Progresso
|
# PetLink — Registo de Progresso
|
||||||
|
|
||||||
## ⚡ HANDOFF — PRÓXIMA SESSÃO COMEÇA AQUI
|
## ⚡ HANDOFF — PRÓXIMA SESSÃO COMEÇA AQUI
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@
|
|||||||
| Supabase Storage | ✅ Configurado | Upload de fotos ainda não implementado na UI |
|
| Supabase Storage | ✅ Configurado | Upload de fotos ainda não implementado na UI |
|
||||||
| Vercel | ⏳ Por configurar | — |
|
| Vercel | ⏳ Por configurar | — |
|
||||||
| Stripe | ✅ Configurado | Integração Fase 2 |
|
| Stripe | ✅ Configurado | Integração Fase 2 |
|
||||||
| Resend | ✅ Configurado | Verificar domínio @pawlink.pt |
|
| Resend | ✅ Configurado | Verificar domínio @petlink.pt |
|
||||||
| Anthropic Claude API | ✅ Configurado | Integração Fase 3 |
|
| Anthropic Claude API | ✅ Configurado | Integração Fase 3 |
|
||||||
| Upstash Redis | ✅ Configurado | Rate limiting ainda não implementado |
|
| Upstash Redis | ✅ Configurado | Rate limiting ainda não implementado |
|
||||||
| Cloudflare | ⏳ Por configurar | — |
|
| Cloudflare | ⏳ Por configurar | — |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# 🐾 PawLink — Documentação do Projecto
|
# 🐾 PetLink — Documentação do Projecto
|
||||||
|
|
||||||
**Plataforma de Adopção e Doação Animal**
|
**Plataforma de Adopção e Doação Animal**
|
||||||
Prova de Aptidão Profissional (PAP) — Ano Lectivo 2024/2025
|
Prova de Aptidão Profissional (PAP) — Ano Lectivo 2024/2025
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Resend } from 'resend';
|
|||||||
|
|
||||||
const resend = new Resend(process.env.RESEND_API_KEY);
|
const resend = new Resend(process.env.RESEND_API_KEY);
|
||||||
|
|
||||||
const FROM = process.env.RESEND_FROM_EMAIL ?? 'noreply@pawlink.pt';
|
const FROM = process.env.RESEND_FROM_EMAIL ?? 'noreply@petlink.pt';
|
||||||
|
|
||||||
export interface SendEmailOptions {
|
export interface SendEmailOptions {
|
||||||
to: string;
|
to: string;
|
||||||
@@ -12,7 +12,7 @@ export interface SendEmailOptions {
|
|||||||
|
|
||||||
export async function sendEmail({ to, subject, html }: SendEmailOptions) {
|
export async function sendEmail({ to, subject, html }: SendEmailOptions) {
|
||||||
const { data, error } = await resend.emails.send({
|
const { data, error } = await resend.emails.send({
|
||||||
from: `PawLink <${FROM}>`,
|
from: `PetLink <${FROM}>`,
|
||||||
to,
|
to,
|
||||||
subject,
|
subject,
|
||||||
html,
|
html,
|
||||||
@@ -35,13 +35,13 @@ export function buildReservationConfirmationHtml(opts: {
|
|||||||
return `
|
return `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="pt">
|
<html lang="pt">
|
||||||
<head><meta charset="UTF-8"><title>Confirmação de Reserva — PawLink</title></head>
|
<head><meta charset="UTF-8"><title>Confirmação de Reserva — PetLink</title></head>
|
||||||
<body style="margin:0;padding:0;background:#F9F4ED;font-family:Georgia,serif;">
|
<body style="margin:0;padding:0;background:#F9F4ED;font-family:Georgia,serif;">
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
<table width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tr><td align="center" style="padding:40px 16px;">
|
<tr><td align="center" style="padding:40px 16px;">
|
||||||
<table width="560" cellpadding="0" cellspacing="0" style="background:#EFE6D8;border-radius:16px;overflow:hidden;">
|
<table width="560" cellpadding="0" cellspacing="0" style="background:#EFE6D8;border-radius:16px;overflow:hidden;">
|
||||||
<tr><td style="background:#C4501A;padding:28px 36px;">
|
<tr><td style="background:#C4501A;padding:28px 36px;">
|
||||||
<span style="color:white;font-size:22px;font-style:italic;font-weight:700;">PawLink</span>
|
<span style="color:white;font-size:22px;font-style:italic;font-weight:700;">PetLink</span>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td style="padding:36px;">
|
<tr><td style="padding:36px;">
|
||||||
<h1 style="margin:0 0 12px;color:#231408;font-size:28px;">Reserva confirmada! 🐾</h1>
|
<h1 style="margin:0 0 12px;color:#231408;font-size:28px;">Reserva confirmada! 🐾</h1>
|
||||||
@@ -59,11 +59,11 @@ export function buildReservationConfirmationHtml(opts: {
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
<p style="margin:0;color:#5C4033;font-size:14px;line-height:1.6;">
|
<p style="margin:0;color:#5C4033;font-size:14px;line-height:1.6;">
|
||||||
Lembra-te de levar um documento de identificação. Se precisares de alterar ou cancelar, acede à tua área de conta em <a href="https://pawlink.pt/main/account" style="color:#C4501A;">pawlink.pt</a>.
|
Lembra-te de levar um documento de identificação. Se precisares de alterar ou cancelar, acede à tua área de conta em <a href="https://petlink.pt/main/account" style="color:#C4501A;">petlink.pt</a>.
|
||||||
</p>
|
</p>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td style="padding:20px 36px;border-top:1px solid #E4D8C8;">
|
<tr><td style="padding:20px 36px;border-top:1px solid #E4D8C8;">
|
||||||
<p style="margin:0;color:#9C8070;font-size:12px;">© 2025 PawLink · Portugal · <a href="https://pawlink.pt/privacy" style="color:#9C8070;">Privacidade</a></p>
|
<p style="margin:0;color:#9C8070;font-size:12px;">© 2025 PetLink · Portugal · <a href="https://petlink.pt/privacy" style="color:#9C8070;">Privacidade</a></p>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
@@ -76,23 +76,23 @@ export function buildWelcomeHtml(opts: { userName: string }): string {
|
|||||||
return `
|
return `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="pt">
|
<html lang="pt">
|
||||||
<head><meta charset="UTF-8"><title>Bem-vindo ao PawLink</title></head>
|
<head><meta charset="UTF-8"><title>Bem-vindo ao PetLink</title></head>
|
||||||
<body style="margin:0;padding:0;background:#F9F4ED;font-family:Georgia,serif;">
|
<body style="margin:0;padding:0;background:#F9F4ED;font-family:Georgia,serif;">
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
<table width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tr><td align="center" style="padding:40px 16px;">
|
<tr><td align="center" style="padding:40px 16px;">
|
||||||
<table width="560" cellpadding="0" cellspacing="0" style="background:#EFE6D8;border-radius:16px;overflow:hidden;">
|
<table width="560" cellpadding="0" cellspacing="0" style="background:#EFE6D8;border-radius:16px;overflow:hidden;">
|
||||||
<tr><td style="background:#C4501A;padding:28px 36px;">
|
<tr><td style="background:#C4501A;padding:28px 36px;">
|
||||||
<span style="color:white;font-size:22px;font-style:italic;font-weight:700;">PawLink</span>
|
<span style="color:white;font-size:22px;font-style:italic;font-weight:700;">PetLink</span>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td style="padding:36px;">
|
<tr><td style="padding:36px;">
|
||||||
<h1 style="margin:0 0 12px;color:#231408;font-size:28px;">Bem-vindo, ${opts.userName}! 🐾</h1>
|
<h1 style="margin:0 0 12px;color:#231408;font-size:28px;">Bem-vindo, ${opts.userName}! 🐾</h1>
|
||||||
<p style="margin:0 0 20px;color:#5C4033;font-size:16px;line-height:1.6;">
|
<p style="margin:0 0 20px;color:#5C4033;font-size:16px;line-height:1.6;">
|
||||||
A tua conta PawLink está pronta. Começa a explorar animais à espera de uma família como a tua.
|
A tua conta PetLink está pronta. Começa a explorar animais à espera de uma família como a tua.
|
||||||
</p>
|
</p>
|
||||||
<a href="https://pawlink.pt/main/animals" style="display:inline-block;background:#C4501A;color:white;padding:14px 28px;border-radius:100px;text-decoration:none;font-size:14px;letter-spacing:0.08em;text-transform:uppercase;">Explorar animais</a>
|
<a href="https://petlink.pt/main/animals" style="display:inline-block;background:#C4501A;color:white;padding:14px 28px;border-radius:100px;text-decoration:none;font-size:14px;letter-spacing:0.08em;text-transform:uppercase;">Explorar animais</a>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td style="padding:20px 36px;border-top:1px solid #E4D8C8;">
|
<tr><td style="padding:20px 36px;border-top:1px solid #E4D8C8;">
|
||||||
<p style="margin:0;color:#9C8070;font-size:12px;">© 2025 PawLink · Portugal</p>
|
<p style="margin:0;color:#9C8070;font-size:12px;">© 2025 PetLink · Portugal</p>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user