Files
VdcScoreLive/docs/02-tech-stack.md
2026-05-05 17:12:06 +01:00

4.7 KiB

02 — Stack Tecnológica

Decisão Final

Camada Tecnologia Versão
Framework React 18+
Build Tool Vite 5+
Linguagem TypeScript 5+
Routing React Router v6
Estado Global Zustand 4+
Base de Dados Firebase Firestore SDK v10
Autenticação Firebase Auth SDK v10
Hosting Firebase Hosting
Styling Tailwind CSS v3
Componentes UI shadcn/ui latest
Ícones Lucide React latest
Formulários React Hook Form + Zod latest
Notificações Sonner (toast) latest
Data/Hora date-fns latest
Testes Vitest + Testing Library latest

Justificação das Escolhas

React + Vite + TypeScript

  • React é o mais familiar e com maior ecossistema
  • Vite oferece HMR instantâneo, essencial para desenvolvimento rápido
  • TypeScript previne erros em runtime, especialmente importante com o schema Firebase

Firebase SDK v10 (Modular)

  • Já é a base de dados usada pela app cliente — obrigatório para compatibilidade
  • SDK v10 modular tem bundle size menor
  • Firestore real-time listeners são nativos — zero configuração extra para real-time

Zustand (em vez de Redux/Context)

  • Muito mais simples que Redux para este tamanho de projeto
  • Funciona bem com Firebase listeners
  • Boilerplate mínimo

Tailwind CSS + shadcn/ui

  • Tailwind permite customização total sem CSS files separados
  • shadcn/ui oferece componentes acessíveis (Radix UI) com design neutro que se adapta ao nosso design system
  • shadcn copia o código para o projeto — sem vendor lock-in

React Hook Form + Zod

  • Formulários performantes (sem re-renders desnecessários)
  • Zod faz validação e inferência de tipos em simultâneo
  • Schema Zod pode espelhar o schema Firebase

Estrutura de Ficheiros do Projeto

football-admin/
├── public/
│   └── favicon.svg
├── src/
│   ├── app/
│   │   ├── App.tsx              # Router principal
│   │   └── routes.tsx           # Definição de rotas
│   ├── components/
│   │   ├── ui/                  # shadcn/ui components
│   │   ├── layout/
│   │   │   ├── Sidebar.tsx
│   │   │   ├── Header.tsx
│   │   │   └── Layout.tsx
│   │   ├── games/
│   │   │   ├── GameCard.tsx
│   │   │   ├── LiveScoreEditor.tsx
│   │   │   └── GameForm.tsx
│   │   ├── clubs/
│   │   ├── players/
│   │   └── shared/
│   │       ├── DataTable.tsx
│   │       ├── ConfirmDialog.tsx
│   │       └── LoadingSpinner.tsx
│   ├── pages/
│   │   ├── Dashboard.tsx
│   │   ├── Games.tsx
│   │   ├── LiveGame.tsx
│   │   ├── Clubs.tsx
│   │   ├── Players.tsx
│   │   ├── Standings.tsx
│   │   ├── Scorers.tsx
│   │   └── Login.tsx
│   ├── hooks/
│   │   ├── useGames.ts
│   │   ├── useClubs.ts
│   │   ├── usePlayers.ts
│   │   └── useAuth.ts
│   ├── store/
│   │   ├── authStore.ts
│   │   └── leagueStore.ts
│   ├── lib/
│   │   ├── firebase.ts          # Firebase config e inicialização
│   │   ├── firestore.ts         # Helpers de Firestore
│   │   └── utils.ts
│   ├── types/
│   │   └── index.ts             # Todos os tipos TypeScript
│   └── main.tsx
├── .env.local                   # Firebase config (não commitar)
├── .env.example
├── firebase.json
├── firestore.rules
├── vite.config.ts
├── tailwind.config.ts
└── package.json

Variáveis de Ambiente

# .env.local (copiar de .env.example)
VITE_FIREBASE_API_KEY=
VITE_FIREBASE_AUTH_DOMAIN=
VITE_FIREBASE_PROJECT_ID=
VITE_FIREBASE_STORAGE_BUCKET=
VITE_FIREBASE_MESSAGING_SENDER_ID=
VITE_FIREBASE_APP_ID=

Scripts NPM

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test": "vitest",
    "deploy": "npm run build && firebase deploy"
  }
}

Comandos de Setup

# 1. Criar projeto
npm create vite@latest football-admin -- --template react-ts
cd football-admin

# 2. Instalar dependências
npm install firebase react-router-dom zustand react-hook-form zod @hookform/resolvers date-fns sonner lucide-react

# 3. Instalar Tailwind
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

# 4. Instalar shadcn/ui
npx shadcn@latest init

# 5. Adicionar componentes shadcn necessários
npx shadcn@latest add button input label card badge dialog table tabs select