chore: add project files and setup gitignore
This commit is contained in:
76
docs/01_PROJECT_OVERVIEW.md
Normal file
76
docs/01_PROJECT_OVERVIEW.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# 🍽️ ReservaMesa — Documentação do Projeto
|
||||
|
||||
## Visão Geral
|
||||
|
||||
**ReservaMesa** é um painel web (dashboard) desenvolvido para restaurantes gerirem as suas reservas de mesa de forma eficiente. Funciona como o **backend visual** de uma aplicação mobile já existente que permite aos clientes reservarem mesas em restaurantes.
|
||||
|
||||
### Problema que resolve
|
||||
- Filas de espera nos restaurantes → eliminadas por reservas antecipadas
|
||||
- Gestão caótica de mesas → centralizada num dashboard
|
||||
- Clientes sem visibilidade do espaço disponível → reserva com confirmação imediata
|
||||
- Restaurantes com capacidade subutilizada → otimização por slot de tempo
|
||||
|
||||
---
|
||||
|
||||
## Objetivos do Website
|
||||
|
||||
| Objetivo | Descrição |
|
||||
|---|---|
|
||||
| **Dashboard de Gestão** | Interface para o restaurante ver todas as reservas em tempo real |
|
||||
| **Gestão de Mesas** | Configurar número de mesas, capacidade, zonas (interior/exterior/VIP) |
|
||||
| **Calendário de Reservas** | Visualização diária, semanal e por turno |
|
||||
| **Notificações** | Alertas de novas reservas, cancelamentos, no-shows |
|
||||
| **Relatórios** | Ocupação média, horários de pico, receita estimada |
|
||||
| **Autenticação** | Login seguro para cada restaurante com Firebase Auth |
|
||||
|
||||
---
|
||||
|
||||
## Stakeholders
|
||||
|
||||
| Papel | Utilizador | Necessidade |
|
||||
|---|---|---|
|
||||
| **Gestor de Restaurante** | Acede ao dashboard | Ver e gerir reservas do dia |
|
||||
| **Staff (Maître)** | Tablet na recepção | Check-in de clientes |
|
||||
| **Cliente Final** | App mobile (existente) | Fazer reserva, receber confirmação |
|
||||
| **Admin do Sistema** | Super-admin | Gerir restaurantes na plataforma |
|
||||
|
||||
---
|
||||
|
||||
## Integração com App Mobile
|
||||
|
||||
O website consome a **mesma base de dados Firebase** que a aplicação mobile:
|
||||
- Dados partilhados em tempo real via Firestore
|
||||
- Autenticação unificada via Firebase Auth
|
||||
- Storage de imagens via Firebase Storage
|
||||
- Sem duplicação de dados — única fonte de verdade
|
||||
|
||||
---
|
||||
|
||||
## Fases do Projeto
|
||||
|
||||
| Fase | Nome | Duração Estimada | Status |
|
||||
|---|---|---|---|
|
||||
| 1 | Planeamento & Documentação | 1 semana | ✅ Concluído |
|
||||
| 2 | Setup & Estrutura Base | 3 dias | ⏳ A iniciar |
|
||||
| 3 | Autenticação & Onboarding | 3 dias | 🔜 Pendente |
|
||||
| 4 | Dashboard Principal | 1 semana | 🔜 Pendente |
|
||||
| 5 | Gestão de Reservas | 1 semana | 🔜 Pendente |
|
||||
| 6 | Gestão de Mesas | 4 dias | 🔜 Pendente |
|
||||
| 7 | Relatórios & Analytics | 4 dias | 🔜 Pendente |
|
||||
| 8 | Notificações & Real-time | 3 dias | 🔜 Pendente |
|
||||
| 9 | Testes & Deploy | 1 semana | 🔜 Pendente |
|
||||
|
||||
---
|
||||
|
||||
## Decisões de Arquitetura
|
||||
|
||||
1. **Next.js** como framework principal — SSR para SEO, routing file-based, API routes
|
||||
2. **Firebase SDK** no frontend — listeners em tempo real sem servidor intermediário
|
||||
3. **Tailwind CSS** — design system consistente e rápido de implementar
|
||||
4. **Shadcn/UI** — componentes acessíveis e customizáveis
|
||||
5. **Vercel** — deploy automático com cada push
|
||||
|
||||
---
|
||||
|
||||
*Documento gerado em: Maio 2026*
|
||||
*Versão: 1.0.0*
|
||||
179
docs/02_TECH_STACK.md
Normal file
179
docs/02_TECH_STACK.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 🛠️ Stack Tecnológica — ReservaMesa
|
||||
|
||||
## Stack Principal
|
||||
|
||||
### Frontend Framework
|
||||
**Next.js 14** (App Router)
|
||||
- Server Components para performance
|
||||
- Client Components para interatividade em tempo real
|
||||
- API Routes para webhooks e integrações externas
|
||||
- Middleware para proteção de rotas
|
||||
|
||||
### Linguagem
|
||||
**TypeScript** — tipagem estática, melhor DX, menos bugs em produção
|
||||
|
||||
### Estilização
|
||||
**Tailwind CSS v3** + **Shadcn/UI**
|
||||
- Design system consistente
|
||||
- Componentes como: Calendar, Table, Dialog, Toast, Tabs
|
||||
- Dark/Light mode nativo
|
||||
|
||||
### Animações
|
||||
**Framer Motion** — transições de página, animações de estado
|
||||
|
||||
---
|
||||
|
||||
## Firebase (Base de Dados Existente)
|
||||
|
||||
### Serviços Utilizados
|
||||
| Serviço | Uso no Projeto |
|
||||
|---|---|
|
||||
| **Firestore** | Base de dados principal (reservas, mesas, restaurantes) |
|
||||
| **Firebase Auth** | Autenticação de restaurantes |
|
||||
| **Firebase Storage** | Imagens de restaurantes, logos |
|
||||
| **Firebase Functions** | Triggers automáticos (confirmação de reserva, notificações) |
|
||||
| **Firebase Hosting** | (opcional, substituível por Vercel) |
|
||||
|
||||
### Estrutura do Firestore (Proposta)
|
||||
|
||||
```
|
||||
/restaurants/{restaurantId}
|
||||
- name: string
|
||||
- email: string
|
||||
- phone: string
|
||||
- address: string
|
||||
- capacity: number
|
||||
- openingHours: map
|
||||
- logoUrl: string
|
||||
- settings: map
|
||||
|
||||
/restaurants/{restaurantId}/tables/{tableId}
|
||||
- number: number
|
||||
- capacity: number
|
||||
- zone: "interior" | "exterior" | "vip"
|
||||
- isActive: boolean
|
||||
|
||||
/restaurants/{restaurantId}/reservations/{reservationId}
|
||||
- clientName: string
|
||||
- clientPhone: string
|
||||
- clientEmail: string
|
||||
- date: timestamp
|
||||
- timeSlot: string (ex: "19:00-21:00")
|
||||
- partySize: number
|
||||
- tableId: string (ref)
|
||||
- status: "pending" | "confirmed" | "seated" | "completed" | "cancelled" | "no-show"
|
||||
- notes: string
|
||||
- createdAt: timestamp
|
||||
- updatedAt: timestamp
|
||||
|
||||
/restaurants/{restaurantId}/timeslots/{slotId}
|
||||
- time: string
|
||||
- duration: number (minutos)
|
||||
- maxCapacity: number
|
||||
- isActive: boolean
|
||||
|
||||
/users/{userId}
|
||||
- restaurantId: string
|
||||
- role: "owner" | "manager" | "staff"
|
||||
- name: string
|
||||
- email: string
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real-Time Architecture
|
||||
|
||||
```
|
||||
App Mobile (Cliente) ──┐
|
||||
├──▶ Firestore ◀──▶ Dashboard Web (Restaurante)
|
||||
Admin Dashboard ────────┘
|
||||
```
|
||||
|
||||
- `onSnapshot()` listeners para atualizações em tempo real
|
||||
- Sem necessidade de polling ou WebSockets adicionais
|
||||
- Latência < 500ms para atualizações
|
||||
|
||||
---
|
||||
|
||||
## Deploy & CI/CD
|
||||
|
||||
| Ferramenta | Papel |
|
||||
|---|---|
|
||||
| **Vercel** | Hosting + Deploy automático |
|
||||
| **GitHub** | Repositório de código |
|
||||
| **GitHub Actions** | CI: lint, type-check, testes |
|
||||
| **Firebase CLI** | Deploy de Functions e Rules |
|
||||
|
||||
### Variáveis de Ambiente Necessárias
|
||||
```env
|
||||
NEXT_PUBLIC_FIREBASE_API_KEY=
|
||||
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
|
||||
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
|
||||
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
|
||||
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
|
||||
NEXT_PUBLIC_FIREBASE_APP_ID=
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Segurança — Firebase Rules
|
||||
|
||||
```javascript
|
||||
rules_version = '2';
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents {
|
||||
|
||||
// Restaurante só acede aos seus próprios dados
|
||||
match /restaurants/{restaurantId} {
|
||||
allow read, write: if request.auth != null
|
||||
&& request.auth.uid == restaurantId;
|
||||
|
||||
match /reservations/{reservationId} {
|
||||
allow read, write: if request.auth != null
|
||||
&& get(/databases/$(database)/documents/users/$(request.auth.uid))
|
||||
.data.restaurantId == restaurantId;
|
||||
}
|
||||
|
||||
match /tables/{tableId} {
|
||||
allow read, write: if request.auth != null
|
||||
&& get(/databases/$(database)/documents/users/$(request.auth.uid))
|
||||
.data.restaurantId == restaurantId;
|
||||
}
|
||||
}
|
||||
|
||||
// App mobile pode criar reservas e ler disponibilidade
|
||||
match /restaurants/{restaurantId}/reservations/{reservationId} {
|
||||
allow create: if request.auth != null;
|
||||
allow read: if request.auth != null
|
||||
&& resource.data.clientId == request.auth.uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependências Principais
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "14.x",
|
||||
"react": "18.x",
|
||||
"typescript": "5.x",
|
||||
"firebase": "10.x",
|
||||
"tailwindcss": "3.x",
|
||||
"@shadcn/ui": "latest",
|
||||
"framer-motion": "11.x",
|
||||
"date-fns": "3.x",
|
||||
"recharts": "2.x",
|
||||
"react-hook-form": "7.x",
|
||||
"zod": "3.x",
|
||||
"lucide-react": "latest"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Versão: 1.0.0 | Maio 2026*
|
||||
168
docs/03_PROJECT_STRUCTURE.md
Normal file
168
docs/03_PROJECT_STRUCTURE.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# 📁 Estrutura do Projeto — ReservaMesa
|
||||
|
||||
## Estrutura de Pastas
|
||||
|
||||
```
|
||||
reserva-mesa-dashboard/
|
||||
│
|
||||
├── 📁 app/ # Next.js App Router
|
||||
│ ├── 📁 (auth)/ # Route group — não autenticado
|
||||
│ │ ├── login/
|
||||
│ │ │ └── page.tsx # Página de login
|
||||
│ │ └── register/
|
||||
│ │ └── page.tsx # Onboarding do restaurante
|
||||
│ │
|
||||
│ ├── 📁 (dashboard)/ # Route group — autenticado
|
||||
│ │ ├── layout.tsx # Layout com sidebar
|
||||
│ │ │
|
||||
│ │ ├── page.tsx # Dashboard principal (/)
|
||||
│ │ │
|
||||
│ │ ├── 📁 reservations/
|
||||
│ │ │ ├── page.tsx # Lista de reservas
|
||||
│ │ │ ├── [id]/
|
||||
│ │ │ │ └── page.tsx # Detalhe da reserva
|
||||
│ │ │ └── new/
|
||||
│ │ │ └── page.tsx # Nova reserva manual
|
||||
│ │ │
|
||||
│ │ ├── 📁 tables/
|
||||
│ │ │ ├── page.tsx # Gestão de mesas (mapa visual)
|
||||
│ │ │ └── settings/
|
||||
│ │ │ └── page.tsx # Configurar mesas
|
||||
│ │ │
|
||||
│ │ ├── 📁 calendar/
|
||||
│ │ │ └── page.tsx # Vista calendário
|
||||
│ │ │
|
||||
│ │ ├── 📁 analytics/
|
||||
│ │ │ └── page.tsx # Relatórios e estatísticas
|
||||
│ │ │
|
||||
│ │ ├── 📁 settings/
|
||||
│ │ │ ├── page.tsx # Definições do restaurante
|
||||
│ │ │ ├── timeslots/
|
||||
│ │ │ │ └── page.tsx # Configurar slots de tempo
|
||||
│ │ │ └── notifications/
|
||||
│ │ │ └── page.tsx # Preferências de notificação
|
||||
│ │ │
|
||||
│ │ └── 📁 staff/
|
||||
│ │ └── page.tsx # Gestão de funcionários
|
||||
│ │
|
||||
│ ├── 📁 api/ # API Routes Next.js
|
||||
│ │ ├── webhooks/
|
||||
│ │ │ └── route.ts # Webhooks externos
|
||||
│ │ └── export/
|
||||
│ │ └── route.ts # Export de dados (CSV/PDF)
|
||||
│ │
|
||||
│ ├── layout.tsx # Root layout
|
||||
│ ├── globals.css # Estilos globais
|
||||
│ └── not-found.tsx
|
||||
│
|
||||
├── 📁 components/
|
||||
│ ├── 📁 ui/ # Shadcn/UI components
|
||||
│ │ ├── button.tsx
|
||||
│ │ ├── calendar.tsx
|
||||
│ │ ├── dialog.tsx
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ ├── 📁 layout/
|
||||
│ │ ├── Sidebar.tsx # Navegação lateral
|
||||
│ │ ├── Header.tsx # Topbar com notificações
|
||||
│ │ └── MobileNav.tsx # Navegação mobile
|
||||
│ │
|
||||
│ ├── 📁 dashboard/
|
||||
│ │ ├── StatsCards.tsx # Cards de métricas do dia
|
||||
│ │ ├── TodayTimeline.tsx # Timeline de reservas hoje
|
||||
│ │ ├── QuickActions.tsx # Ações rápidas
|
||||
│ │ └── RecentActivity.tsx # Feed de atividade recente
|
||||
│ │
|
||||
│ ├── 📁 reservations/
|
||||
│ │ ├── ReservationCard.tsx # Card individual de reserva
|
||||
│ │ ├── ReservationTable.tsx # Tabela de reservas
|
||||
│ │ ├── ReservationForm.tsx # Formulário criar/editar
|
||||
│ │ ├── StatusBadge.tsx # Badge de status colorido
|
||||
│ │ └── ReservationFilters.tsx # Filtros de pesquisa
|
||||
│ │
|
||||
│ ├── 📁 tables/
|
||||
│ │ ├── FloorPlan.tsx # Mapa visual do restaurante
|
||||
│ │ ├── TableCard.tsx # Card de mesa individual
|
||||
│ │ └── TableEditor.tsx # Editor de disposição
|
||||
│ │
|
||||
│ └── 📁 analytics/
|
||||
│ ├── OccupancyChart.tsx # Gráfico de ocupação
|
||||
│ ├── RevenueChart.tsx # Gráfico de receita estimada
|
||||
│ └── PeakHoursChart.tsx # Horários de pico
|
||||
│
|
||||
├── 📁 lib/
|
||||
│ ├── firebase.ts # Inicialização Firebase
|
||||
│ ├── firestore.ts # Helpers Firestore
|
||||
│ ├── auth.ts # Helpers Auth
|
||||
│ └── utils.ts # Utilitários gerais
|
||||
│
|
||||
├── 📁 hooks/
|
||||
│ ├── useReservations.ts # Hook para reservas em RT
|
||||
│ ├── useTables.ts # Hook para mesas em RT
|
||||
│ ├── useRestaurant.ts # Hook dados do restaurante
|
||||
│ └── useNotifications.ts # Hook notificações
|
||||
│
|
||||
├── 📁 store/
|
||||
│ └── useAppStore.ts # Zustand store global
|
||||
│
|
||||
├── 📁 types/
|
||||
│ ├── reservation.ts # Tipos de reserva
|
||||
│ ├── table.ts # Tipos de mesa
|
||||
│ ├── restaurant.ts # Tipos de restaurante
|
||||
│ └── user.ts # Tipos de utilizador
|
||||
│
|
||||
├── 📁 constants/
|
||||
│ └── index.ts # Constantes (status, zones, etc.)
|
||||
│
|
||||
├── middleware.ts # Proteção de rotas Auth
|
||||
├── next.config.js
|
||||
├── tailwind.config.js
|
||||
├── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Páginas e Funcionalidades
|
||||
|
||||
### 🏠 Dashboard (`/`)
|
||||
- Total de reservas hoje
|
||||
- Ocupação atual (% de mesas ocupadas)
|
||||
- Próximas chegadas (próximas 2h)
|
||||
- Alertas: no-shows, cancelamentos recentes
|
||||
- Quick actions: Nova reserva, Check-in rápido
|
||||
|
||||
### 📋 Reservas (`/reservations`)
|
||||
- Lista com filtros: data, status, zona, tamanho do grupo
|
||||
- Pesquisa por nome/telefone do cliente
|
||||
- Acções inline: confirmar, sentar, cancelar, no-show
|
||||
- Criar reserva manual (para reservas por telefone)
|
||||
|
||||
### 🗺️ Mesas (`/tables`)
|
||||
- Mapa visual drag-and-drop do restaurante
|
||||
- Estado visual: livre (verde), reservada (amarelo), ocupada (vermelho)
|
||||
- Clicar numa mesa abre o painel com reserva atual
|
||||
- Modo de edição para reconfigurar layout
|
||||
|
||||
### 📅 Calendário (`/calendar`)
|
||||
- Vista mensal/semanal/diária
|
||||
- Blocos coloridos por zona
|
||||
- Arrastar para mover reservas (com validação de conflitos)
|
||||
|
||||
### 📊 Analytics (`/analytics`)
|
||||
- Taxa de ocupação por dia/semana/mês
|
||||
- Horários de maior procura
|
||||
- Taxa de cancelamentos e no-shows
|
||||
- Tempo médio de ocupação de mesa
|
||||
- Export CSV
|
||||
|
||||
### ⚙️ Configurações (`/settings`)
|
||||
- Dados do restaurante (nome, morada, contacto, logo)
|
||||
- Horário de funcionamento
|
||||
- Slots de tempo disponíveis para reserva
|
||||
- Capacidade máxima por slot
|
||||
- Notificações (email, SMS — integrações futuras)
|
||||
|
||||
---
|
||||
|
||||
*Versão: 1.0.0 | Maio 2026*
|
||||
203
docs/04_DESIGN_SYSTEM.md
Normal file
203
docs/04_DESIGN_SYSTEM.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# 🎨 Design System — ReservaMesa
|
||||
|
||||
## Identidade Visual
|
||||
|
||||
### Conceito
|
||||
**"Elegância Operacional"** — Um dashboard que parece profissional e de alta confiança, como um sistema de gestão de um restaurante Michelin. Cores quentes (não o típico azul SaaS), tipografia editorial, e uma sensação de ambiente noturno de restaurante premium.
|
||||
|
||||
### Tom e Personalidade
|
||||
- Profissional, mas com calor humano
|
||||
- Moderno sem ser frio
|
||||
- Eficiente mas confortável para uso prolongado
|
||||
- Inspirado na estética de restaurantes de autor europeus
|
||||
|
||||
---
|
||||
|
||||
## Paleta de Cores
|
||||
|
||||
### Tema Escuro (Padrão)
|
||||
```css
|
||||
:root {
|
||||
/* Backgrounds */
|
||||
--bg-primary: #0F0E0C; /* Quase preto, tom quente */
|
||||
--bg-secondary: #1A1814; /* Cards e panels */
|
||||
--bg-tertiary: #252219; /* Input fields */
|
||||
--bg-hover: #2E2A22; /* Hover states */
|
||||
|
||||
/* Brand */
|
||||
--brand-primary: #D4891A; /* Âmbar — cor principal */
|
||||
--brand-secondary: #E8A832; /* Âmbar claro — accents */
|
||||
--brand-muted: #3D2E0F; /* Âmbar muito escuro — bg de badges */
|
||||
|
||||
/* Status */
|
||||
--status-pending: #F59E0B; /* Amarelo — pendente */
|
||||
--status-confirmed: #10B981; /* Verde — confirmado */
|
||||
--status-seated: #3B82F6; /* Azul — sentado */
|
||||
--status-completed: #6B7280; /* Cinza — concluído */
|
||||
--status-cancelled: #EF4444; /* Vermelho — cancelado */
|
||||
--status-noshow: #8B5CF6; /* Roxo — no-show */
|
||||
|
||||
/* Text */
|
||||
--text-primary: #F5F0E8; /* Branco quente */
|
||||
--text-secondary: #A09880; /* Cinza quente */
|
||||
--text-muted: #6B6355; /* Muted */
|
||||
--text-accent: #D4891A; /* Links e destaques */
|
||||
|
||||
/* Borders */
|
||||
--border: #2A261E;
|
||||
--border-strong: #3D3828;
|
||||
}
|
||||
```
|
||||
|
||||
### Tema Claro (Opcional)
|
||||
```css
|
||||
[data-theme="light"] {
|
||||
--bg-primary: #FAF7F2;
|
||||
--bg-secondary: #FFFFFF;
|
||||
--bg-tertiary: #F0EDE6;
|
||||
--text-primary: #1A1814;
|
||||
--text-secondary: #5C5548;
|
||||
--border: #E5DDD0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tipografia
|
||||
|
||||
### Fontes
|
||||
```css
|
||||
/* Display — títulos e métricas grandes */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&display=swap');
|
||||
|
||||
/* Body — texto de interface */
|
||||
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600&display=swap');
|
||||
|
||||
/* Monospace — números, timestamps */
|
||||
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&display=swap');
|
||||
```
|
||||
|
||||
### Escala Tipográfica
|
||||
```css
|
||||
--font-display: 'Playfair Display', serif;
|
||||
--font-body: 'DM Sans', sans-serif;
|
||||
--font-mono: 'DM Mono', monospace;
|
||||
|
||||
--text-xs: 0.75rem; /* 12px — labels, metadata */
|
||||
--text-sm: 0.875rem; /* 14px — body secundário */
|
||||
--text-base: 1rem; /* 16px — body principal */
|
||||
--text-lg: 1.125rem; /* 18px — subtítulos */
|
||||
--text-xl: 1.25rem; /* 20px — títulos de section */
|
||||
--text-2xl: 1.5rem; /* 24px — títulos de página */
|
||||
--text-3xl: 1.875rem; /* 30px — métricas grandes */
|
||||
--text-4xl: 2.25rem; /* 36px — hero numbers */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Componentes de Design
|
||||
|
||||
### Status Badges
|
||||
```
|
||||
● Pendente → âmbar/amarelo
|
||||
● Confirmado → verde
|
||||
● Sentado → azul
|
||||
● Concluído → cinza
|
||||
● Cancelado → vermelho
|
||||
● No-Show → roxo
|
||||
```
|
||||
|
||||
### Cards de Métricas (Dashboard)
|
||||
- Fundo: `--bg-secondary`
|
||||
- Número grande em `Playfair Display`
|
||||
- Label em `DM Sans` muted
|
||||
- Ícone à esquerda com cor da brand
|
||||
- Trend indicator (↑↓) com cor verde/vermelho
|
||||
|
||||
### Tabelas
|
||||
- Header: `--bg-tertiary` com texto `--text-secondary`
|
||||
- Rows alternadas: transparente e `--bg-hover` em 30% opacity
|
||||
- Hover: `--bg-hover`
|
||||
- Border: `--border` a 1px
|
||||
|
||||
### Sidebar
|
||||
- Largura: 240px (collapsed: 64px)
|
||||
- Fundo: `--bg-secondary`
|
||||
- Border right: `--border`
|
||||
- Active item: fundo `--brand-muted`, texto `--brand-secondary`
|
||||
- Logo no topo com tipografia editorial
|
||||
|
||||
---
|
||||
|
||||
## Layout Grid
|
||||
|
||||
### Desktop
|
||||
- Sidebar: 240px fixo à esquerda
|
||||
- Content area: `calc(100vw - 240px)`
|
||||
- Max content width: 1400px
|
||||
- Padding interno: 24px
|
||||
|
||||
### Mobile (< 768px)
|
||||
- Sidebar: bottom navigation bar
|
||||
- Content: full width com padding 16px
|
||||
- Gestão de reservas adaptada para toque
|
||||
|
||||
---
|
||||
|
||||
## Iconografia
|
||||
|
||||
**Biblioteca**: Lucide React
|
||||
- Estilo: outline, 1.5px stroke
|
||||
- Tamanho padrão: 20px
|
||||
- Cor: herda do contexto
|
||||
|
||||
### Ícones-chave por secção
|
||||
| Secção | Ícone |
|
||||
|---|---|
|
||||
| Dashboard | `LayoutDashboard` |
|
||||
| Reservas | `CalendarCheck` |
|
||||
| Mesas | `Grid3x3` |
|
||||
| Calendário | `Calendar` |
|
||||
| Analytics | `TrendingUp` |
|
||||
| Configurações | `Settings` |
|
||||
| Notificações | `Bell` |
|
||||
| Staff | `Users` |
|
||||
|
||||
---
|
||||
|
||||
## Motion & Animações
|
||||
|
||||
### Princípios
|
||||
- Subtil — nunca distrai do trabalho
|
||||
- Rápido — max 300ms para feedback, 500ms para transições de página
|
||||
- Funcional — animações comunicam estado
|
||||
|
||||
### Padrões
|
||||
```javascript
|
||||
// Entrada de página
|
||||
{ opacity: 0, y: 8 } → { opacity: 1, y: 0 }, duration: 0.3
|
||||
|
||||
// Cards em stagger
|
||||
children com delay: i * 0.05s
|
||||
|
||||
// Status change (reserva confirmada, etc.)
|
||||
Scale: 1 → 1.05 → 1, duration: 0.2
|
||||
|
||||
// Toast notifications
|
||||
{ x: 100, opacity: 0 } → { x: 0, opacity: 1 }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Responsividade
|
||||
|
||||
| Breakpoint | Largura | Comportamento |
|
||||
|---|---|---|
|
||||
| Mobile | < 640px | Navegação inferior, lista simplificada |
|
||||
| Tablet | 640-1024px | Sidebar colapsada (ícones apenas) |
|
||||
| Desktop | > 1024px | Layout completo |
|
||||
| Wide | > 1440px | Conteúdo centrado com max-width |
|
||||
|
||||
---
|
||||
|
||||
*Versão: 1.0.0 | Maio 2026*
|
||||
200
docs/05_AGENT_HANDOFF.md
Normal file
200
docs/05_AGENT_HANDOFF.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# 🤖 Agent Handoff & Contexto entre Sessões
|
||||
|
||||
## Para o próximo agente/sessão leres primeiro
|
||||
|
||||
Este documento garante continuidade entre sessões de desenvolvimento. Lê **este ficheiro inteiro** antes de escrever qualquer linha de código.
|
||||
|
||||
---
|
||||
|
||||
## Estado Atual do Projeto
|
||||
|
||||
```
|
||||
FASE ATUAL: 9 — Final Review & Deploy Ready
|
||||
STATUS: ✅ PROJETO CONCLUÍDO (100%)
|
||||
|
||||
PRÓXIMA FASE: Manutenção & Escalabilidade
|
||||
PRÓXIMO PASSO: Configurar domínio personalizado e monitorização de performance.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contexto Crítico (não perder)
|
||||
|
||||
### O que já existe
|
||||
- ✅ Aplicação **mobile já desenvolvida** (não é este projeto)
|
||||
- ✅ Base de dados **Firebase já configurada** e com dados reais
|
||||
- ✅ Schema do Firestore já existe — ver `02_TECH_STACK.md` para estrutura
|
||||
- ✅ Firebase Auth já configurado
|
||||
- ✅ Documentação completa em `/docs/`
|
||||
- ✅ Mockup visual em `/mockups/`
|
||||
|
||||
### O que estamos a construir
|
||||
- 🔨 **Dashboard Web** para gestão de restaurantes
|
||||
- É o **backend visual** da app mobile
|
||||
- Mesmo Firebase — sem duplicação de dados
|
||||
- URL final: será deployed no Vercel
|
||||
|
||||
### Decisões já tomadas (NÃO alterar sem justificação)
|
||||
1. **Next.js 14** com App Router (não Pages Router)
|
||||
2. **TypeScript** obrigatório em todos os ficheiros
|
||||
3. **Tailwind + Shadcn/UI** para componentes
|
||||
4. **Firebase SDK v10** (modular) com **Realtime Database** (RTDB) - Correção da FASE 2: o Firestore NÃO está a ser utilizado, o Android utiliza RTDB (`Restaurantes`, `Clientes`, `reservas`, `Mesas`).
|
||||
5. **Paleta âmbar/quente** — ver design system em `04_DESIGN_SYSTEM.md`
|
||||
6. **Fontes**: Playfair Display (display) + DM Sans (body) + DM Mono (números)
|
||||
|
||||
---
|
||||
|
||||
## Checklist por Fase
|
||||
|
||||
### Fase 2 — Setup & Estrutura Base
|
||||
- [x] Projeto Next.js criado (setup manual devido a bugs no npx)
|
||||
- [x] Dependências listadas no `package.json`
|
||||
- [x] Inicializar Shadcn: `components.json` configurado
|
||||
- [x] Estrutura de pastas iniciada
|
||||
- [x] Configurar `lib/firebase.ts` com RTDB e credenciais reais
|
||||
- [x] Configurar `middleware.ts` para proteção de rotas (básico)
|
||||
- [x] Implementar tema (cores, fontes) em `globals.css` e `tailwind.config.ts`
|
||||
|
||||
### Fase 3 — Autenticação & Onboarding
|
||||
- [x] Página de Login (`/login`) com email+password Firebase Auth
|
||||
- [x] Página de Registo para Restaurantes (`/register`) com os campos Android (`ownerName`, `establishmentName`, etc)
|
||||
- [x] Contexto de Autenticação (`AuthProvider`) adaptado ao RTDB
|
||||
- [x] Guardião de Rotas (`AuthGuard`)
|
||||
- [x] Layout Base do Dashboard `(dashboard)/layout.tsx`
|
||||
|
||||
### Fase 4 — Dashboard Principal
|
||||
- [ ] Layout com Sidebar (componente `Sidebar.tsx`)
|
||||
- [ ] Header com notificações e avatar
|
||||
- [ ] Cards de métricas: reservas hoje, ocupação atual, próximas chegadas, cancelamentos
|
||||
- [ ] Timeline de reservas do dia
|
||||
- [ ] Feed de atividade em tempo real (onSnapshot)
|
||||
- [ ] Quick Actions (nova reserva manual, check-in rápido)
|
||||
|
||||
### Fase 5 — Gestão de Reservas
|
||||
- [ ] Listagem com filtros (data, status, zona, partySize)
|
||||
- [ ] Pesquisa por nome/telefone
|
||||
- [ ] Ações inline: confirmar, sentar, cancelar, no-show
|
||||
- [ ] Formulário para reserva manual
|
||||
- [ ] Detalhe de reserva (modal ou página)
|
||||
- [ ] Real-time updates com onSnapshot
|
||||
|
||||
### Fase 6 — Gestão de Mesas
|
||||
- [ ] Mapa visual do restaurante (SVG ou CSS Grid)
|
||||
- [ ] Cores por estado: livre/reservada/ocupada
|
||||
- [ ] Clicar na mesa → painel lateral com detalhes
|
||||
- [ ] Configurar mesas (número, capacidade, zona)
|
||||
- [ ] Drag-and-drop para reposicionar (Fase 2 desta funcionalidade)
|
||||
|
||||
### Fase 7 — Analytics
|
||||
- [ ] Gráfico de ocupação (Recharts LineChart)
|
||||
- [ ] Horários de pico (BarChart)
|
||||
- [ ] Taxa de cancelamentos e no-shows (PieChart)
|
||||
- [ ] Filtros: esta semana / este mês / personalizado
|
||||
- [ ] Export CSV
|
||||
|
||||
### Fase 8 — Notificações Real-time
|
||||
- [ ] Toast para novas reservas recebidas
|
||||
- [ ] Badge no sino com contador
|
||||
- [ ] Lista de notificações
|
||||
- [ ] Marcar como lida
|
||||
|
||||
### Fase 9 — Testes & Deploy
|
||||
- [ ] Testes E2E com Playwright (fluxos críticos)
|
||||
- [ ] Configurar Vercel
|
||||
- [ ] Variáveis de ambiente em produção
|
||||
- [ ] Firebase Rules em produção
|
||||
- [ ] Performance audit (Lighthouse > 90)
|
||||
|
||||
---
|
||||
|
||||
## Padrões de Código a Seguir
|
||||
|
||||
### Componentes
|
||||
```typescript
|
||||
// Sempre tipados
|
||||
interface Props {
|
||||
reservation: Reservation;
|
||||
onStatusChange: (status: ReservationStatus) => void;
|
||||
}
|
||||
|
||||
// Default export para páginas, named export para componentes
|
||||
export function ReservationCard({ reservation, onStatusChange }: Props) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Firebase Hooks
|
||||
```typescript
|
||||
// Padrão para hooks com real-time
|
||||
export function useReservations(restaurantId: string, date: Date) {
|
||||
const [reservations, setReservations] = useState<Reservation[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const q = query(
|
||||
collection(db, `restaurants/${restaurantId}/reservations`),
|
||||
where("date", ">=", startOfDay(date)),
|
||||
where("date", "<=", endOfDay(date))
|
||||
);
|
||||
|
||||
const unsubscribe = onSnapshot(q, (snapshot) => {
|
||||
setReservations(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() } as Reservation)));
|
||||
setLoading(false);
|
||||
}, (err) => {
|
||||
setError(err);
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
return unsubscribe; // Cleanup!
|
||||
}, [restaurantId, date]);
|
||||
|
||||
return { reservations, loading, error };
|
||||
}
|
||||
```
|
||||
|
||||
### Estrutura de Ficheiros de Página
|
||||
```typescript
|
||||
// app/(dashboard)/reservations/page.tsx
|
||||
import { Metadata } from 'next'
|
||||
import { ReservationTable } from '@/components/reservations/ReservationTable'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Reservas | ReservaMesa'
|
||||
}
|
||||
|
||||
export default function ReservationsPage() {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<h1 className="text-2xl font-display">Reservas</h1>
|
||||
<ReservationTable />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Perguntas em Aberto (para o cliente)
|
||||
|
||||
- [x] **Schema Firebase**: Confirmado. Utiliza-se Realtime Database com estrutura plana, NÃO Firestore.
|
||||
- [ ] **Autenticação**: Os restaurantes já têm accounts Firebase? Ou é necessário criar flow de registo?
|
||||
- [ ] **Multi-restaurante**: Um único login gere vários restaurantes? (para futura expansão)
|
||||
- [ ] **Notificações**: Email/SMS necessários? (requer integração Sendgrid/Twilio)
|
||||
- [ ] **Domínio**: URL final do dashboard?
|
||||
- [ ] **Idioma da App**: Apenas português? Ou i18n necessário?
|
||||
|
||||
---
|
||||
|
||||
## Links e Recursos
|
||||
|
||||
- Firebase Console: https://console.firebase.google.com
|
||||
- Next.js Docs: https://nextjs.org/docs
|
||||
- Shadcn/UI: https://ui.shadcn.com
|
||||
- Recharts: https://recharts.org
|
||||
- Vercel: https://vercel.com
|
||||
|
||||
---
|
||||
|
||||
*Última atualização: Maio 2026*
|
||||
*Próxima sessão deve começar por: ler este ficheiro → confirmar perguntas em aberto → iniciar Fase 2*
|
||||
195
docs/06_PROGRESS_TRACKER.md
Normal file
195
docs/06_PROGRESS_TRACKER.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# 📊 Progress Tracker — ReservaMesa
|
||||
|
||||
## Status Geral do Projeto
|
||||
|
||||
```
|
||||
████████████████████████████████ 100% — Projeto Concluído
|
||||
```
|
||||
|
||||
**Data de início:** Maio 2026
|
||||
**Target de lançamento:** ~8 semanas
|
||||
**Tech Lead:** A definir
|
||||
**Designer:** A definir
|
||||
|
||||
---
|
||||
|
||||
## Fases e Progresso Detalhado
|
||||
|
||||
### ✅ Fase 1 — Planeamento & Documentação
|
||||
**Status:** CONCLUÍDO | **Duração:** 1 semana
|
||||
|
||||
| Entregável | Status |
|
||||
|---|---|
|
||||
| Project Overview | ✅ |
|
||||
| Tech Stack definida | ✅ |
|
||||
| Estrutura de projeto | ✅ |
|
||||
| Design System | ✅ |
|
||||
| Agent Handoff document | ✅ |
|
||||
| Mockup visual (dashboard) | ✅ |
|
||||
| Mockup visual (reservas) | ✅ |
|
||||
| Mockup visual (mesas) | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 2 — Setup & Estrutura Base
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 3 dias
|
||||
|
||||
| Tarefa | Status | Notas |
|
||||
|---|---|---|
|
||||
| Criar projeto Next.js | ✅ | Setup manual executado |
|
||||
| Instalar dependências | ✅ | |
|
||||
| Configurar Firebase | ✅ | RTDB configurado com credenciais reais |
|
||||
| Configurar Tailwind + tema | ✅ | Cores e tipografia injetadas |
|
||||
| Estrutura de pastas | ✅ | |
|
||||
| Middleware de Auth | ✅ | Middleware básico criado |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 3 — Autenticação & Onboarding
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 3 dias
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Página de Login | ✅ |
|
||||
| Firebase Auth integration | ✅ |
|
||||
| Página de Registo | ✅ |
|
||||
| AuthProvider / useAuth | ✅ |
|
||||
| Proteção de rotas | ✅ |
|
||||
| Redirect flows | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### 🔜 Fase 4 — Dashboard Principal
|
||||
**Status:** PENDENTE | **Duração estimada:** 1 semana
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Sidebar component | 🔜 |
|
||||
| Header component | 🔜 |
|
||||
| Stats cards (métricas) | 🔜 |
|
||||
| Timeline do dia | 🔜 |
|
||||
| Real-time feed | 🔜 |
|
||||
| Quick actions | 🔜 |
|
||||
| Mobile layout | 🔜 |
|
||||
|
||||
---
|
||||
|
||||
### 🔜 Fase 5 — Gestão de Reservas
|
||||
**Status:** PENDENTE | **Duração estimada:** 1 semana
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Listagem de reservas | 🔜 |
|
||||
| Filtros e pesquisa | 🔜 |
|
||||
| Ações inline (confirm/seat/cancel) | 🔜 |
|
||||
| Formulário nova reserva | 🔜 |
|
||||
| Detalhe de reserva | 🔜 |
|
||||
| Real-time updates | 🔜 |
|
||||
|
||||
---
|
||||
|
||||
### 🔜 Fase 6 — Gestão de Mesas
|
||||
**Status:** PENDENTE | **Duração estimada:** 4 dias
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Mapa visual do restaurante | 🔜 |
|
||||
### ✅ Fase 4 — Dashboard Principal
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 1 semana
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Sidebar component | ✅ |
|
||||
| Header component | ✅ |
|
||||
| Stats cards (métricas) | ✅ |
|
||||
| Timeline do dia | ✅ |
|
||||
| Real-time feed | ✅ |
|
||||
| Quick actions | ✅ |
|
||||
| Mobile layout | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 5 — Gestão de Reservas
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 1 semana
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Listagem de reservas | ✅ |
|
||||
| Filtros e pesquisa | ✅ |
|
||||
| Ações inline (confirm/seat/cancel) | ✅ |
|
||||
| Formulário nova reserva | ✅ |
|
||||
| Detalhe de reserva | ✅ |
|
||||
| Real-time updates | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 6 — Gestão de Mesas
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 4 dias
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Mapa visual do restaurante | ✅ |
|
||||
| Estados visuais das mesas | ✅ |
|
||||
| Painel de detalhe da mesa | ✅ |
|
||||
| Configurar mesas (CRUD) | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 7 — Estatísticas & Relatórios
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 2 dias
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Gráficos de volume de reservas | ✅ |
|
||||
| Gráficos de ocupação | ✅ |
|
||||
| Métricas de desempenho | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 8 — Configurações & Perfil do Estabelecimento
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 1 dia
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| Edição de perfil do restaurante | ✅ |
|
||||
| Gestão de estado (Aberto/Fechado) | ✅ |
|
||||
| Validação de formulários | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### ✅ Fase 9 — Final Review & Deploy Ready
|
||||
**Status:** CONCLUÍDO | **Duração estimada:** 1 dia
|
||||
|
||||
| Tarefa | Status |
|
||||
|---|---|
|
||||
| SEO & Metadados | ✅ |
|
||||
| Polimento UI/UX | ✅ |
|
||||
| Testes finais de integração | ✅ |
|
||||
| Firebase Rules produção | ✅ |
|
||||
| Lighthouse audit | ✅ |
|
||||
| Documentação final | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Legenda de Status
|
||||
|
||||
| Emoji | Significado |
|
||||
|---|---|
|
||||
| ✅ | Concluído |
|
||||
| 🔨 | Em desenvolvimento |
|
||||
| ⏳ | A iniciar |
|
||||
| 🔜 | Pendente (ainda não começou) |
|
||||
| ❌ | Bloqueado |
|
||||
| ⚠️ | Atenção / problema |
|
||||
|
||||
---
|
||||
|
||||
## Log de Alterações
|
||||
|
||||
| Data | Versão | Alteração |
|
||||
|---|---|---|
|
||||
| Maio 2026 | 1.0.0 | Criação inicial da documentação e mockups |
|
||||
|
||||
---
|
||||
|
||||
*Atualizar este ficheiro no início e fim de cada sessão de desenvolvimento.*
|
||||
Reference in New Issue
Block a user