Aplicação full-stack composta por um frontend React (roteamento client-side, SCSS Modules, design system) e uma API REST Node.js/Express para cadastro de profissionais voluntários.
Desafio Rotas simula o portal de uma ONG de saúde comunitária — a SaúdePara Todos — que oferece serviços médicos gratuitos à população vulnerável.
O projeto demonstra:
- ✅ Roteamento client-side com React Router v7 (BrowserRouter + Routes + Route)
- ✅ Estilização isolada por componente com SCSS Modules
- ✅ Design system consistente (variáveis globais, paleta de cores, tipografia)
- ✅ Componentização com separação clara de responsabilidades
- ✅ API REST com Node.js + Express para cadastro de voluntários
- ✅ Validação de entrada, armazenamento em memória e respostas padronizadas em JSON
| Página | Rota | Descrição |
|---|---|---|
| Home | / |
Hero com chamada à ação, cards de missão e estatísticas de impacto |
| Como Ajudar | /como-ajudar |
8 serviços médicos gratuitos (clínica, odonto, saúde mental, etc.) + CTA de contato |
| Seja Voluntário | /voluntario |
Benefícios de ser voluntário, formulário de inscrição |
| Header | global | Navegação persistente com links reativos |
| Footer | global | Informações de contato e links de redes sociais |
| Camada | Tecnologia | Versão |
|---|---|---|
| UI Library | React | ^19.2.0 |
| Roteamento | React Router DOM | ^7.10.1 |
| Build Tool | Vite | ^7.2.4 |
| Estilização | SCSS Modules (sass) | ^1.94.2 |
| Linting | ESLint | ^9.39.1 |
| Linguagem | JavaScript (JSX) | ES Modules |
| Camada | Tecnologia | Versão |
|---|---|---|
| Runtime | Node.js | ≥ 18 |
| Framework | Express | ^5.1.0 |
| Linguagem | JavaScript | ES Modules |
desafio-rotas/
├── api/ # API REST (Node.js + Express)
│ ├── src/
│ │ ├── data/
│ │ │ └── voluntarios.js # Armazenamento em memória
│ │ ├── routes/
│ │ │ └── voluntarios.routes.js # GET e POST /api/profissionais
│ │ ├── validators/
│ │ │ └── voluntario.validator.js # Validação de entrada
│ │ └── app.js # Configuração do Express
│ ├── server.js # Entry point da API (porta 3000)
│ └── package.json
├── public/
│ └── vite.svg # Favicon
├── src/
│ ├── assets/ # Imagens e ícones
│ ├── components/
│ │ ├── Header/
│ │ │ ├── Header.jsx # Barra de navegação global
│ │ │ └── header.module.scss
│ │ └── NossaMissao/
│ │ ├── NossaMIssao.jsx # Cards de missão (reutilizável)
│ │ └── nossa_missao.module.scss
│ ├── pages/
│ │ ├── ComoAjudar/
│ │ │ ├── ComoAjudar.jsx # Rota /como-ajudar
│ │ │ └── comoAjudar.module.scss
│ │ ├── Footer/
│ │ │ ├── Footer.jsx # Rodapé global
│ │ │ └── estilos.module.scss
│ │ ├── Home/
│ │ │ ├── Home.jsx # Rota /
│ │ │ └── home.module.scss
│ │ └── Voluntario/
│ │ ├── Voluntario.jsx # Rota /voluntario
│ │ └── voluntario.module.scss
│ ├── App.jsx # Definição de rotas (BrowserRouter + Routes)
│ ├── main.jsx # Entry point React
│ └── globalStyle.scss # Variáveis SCSS globais e reset
├── index.html
├── vite.config.js
├── package.json
└── .gitignore
- Node.js ≥ 18.0.0
- npm ≥ 9 (ou pnpm / yarn)
git clone https://github.com/sherloCod3/desafio-rotas.git
cd desafio-rotasnpm install
npm run devDisponível em http://localhost:5173.
cd api
npm install
node server.jsDisponível em http://localhost:3000.
| Comando | Descrição |
|---|---|
npm run dev |
Inicia servidor dev com HMR |
npm run build |
Gera build de produção em dist/ |
npm run preview |
Serve o build de produção localmente |
npm run lint |
Executa o ESLint em todo o projeto |
| Comando | Descrição |
|---|---|
node server.js |
Inicia a API na porta 3000 |
O roteamento é configurado em src/App.jsx usando React Router v7:
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/voluntario" element={<Voluntario />} />
<Route path="/como-ajudar" element={<ComoAjudar />} />
</Routes>
</BrowserRouter>O <Header /> fica fora do <Routes> para ser renderizado em todas as páginas.
A navegação é feita com <Link> do React Router — sem recarregamento de página.
As variáveis globais de design ficam em src/globalStyle.scss e são importadas por cada módulo SCSS:
// Paleta de cores principal
$cor-verde-escuro: #004d40;
$cor-verde-medio: #00695c;
$cor-texto-claro: #b2dfdb;
$cor-texto-escuro: #333333;
$cor-borda: #e0e0e0;Cada componente usa CSS Modules (*.module.scss) para escopo isolado — sem vazamento de estilos entre componentes.
App (BrowserRouter)
├── Header ← navegação global (sempre visível)
├── Routes
│ ├── / → Home
│ │ ├── [hero section]
│ │ └── NossaMissao (cards)
│ ├── /como-ajudar → ComoAjudar
│ │ ├── [hero]
│ │ ├── [grade de 8 serviços médicos]
│ │ └── [CTA contato]
│ └── /voluntario → Voluntario
│ ├── [hero]
│ ├── [benefícios]
│ └── [formulário de inscrição]
└── Footer ← rodapé global (dentro de cada page)
Base URL: http://localhost:3000
Retorna todos os profissionais voluntários cadastrados.
Resposta 200:
{
"total": 1,
"profissionais": [
{
"id": 1,
"nome": "Dra. Ana Lima",
"email": "ana.lima@email.com",
"telefone": "11987654321",
"especialidade": "Medicina",
"mensagem": "Disponível aos sábados.",
"cadastradoEm": "2026-03-13T22:00:00.000Z"
}
]
}Cadastra um novo profissional voluntário.
Corpo da requisição:
| Campo | Tipo | Obrigatório | Regra |
|---|---|---|---|
nome |
string | ✅ | mínimo 3 caracteres |
email |
string | ✅ | formato válido de e-mail |
telefone |
string | ✅ | 10 ou 11 dígitos numéricos |
especialidade |
string | ✅ | não pode ser vazio |
mensagem |
string | ❌ | máximo 500 caracteres |
Resposta 201:
{
"mensagem": "Profissional cadastrado com sucesso!",
"profissional": { ... }
}Resposta 400 (dados inválidos):
{
"mensagem": "Dados inválidos. Corrija os erros abaixo.",
"erros": ["O campo \"nome\" é obrigatório e deve ter no mínimo 3 caracteres."]
}# 1. Fork e clone
git clone https://github.com/sherloCod3/desafio-rotas.git
# 2. Crie uma branch para sua feature
git checkout -b feat/minha-feature
# 3. Commit seguindo Conventional Commits
git commit -m "feat(pagina): adiciona nova seção X"
# 4. Push e abra um Pull Request
git push origin feat/minha-feature| Prefixo | Uso |
|---|---|
feat |
Nova funcionalidade |
fix |
Correção de bug |
docs |
Alterações na documentação |
style |
Formatação, sem alteração de lógica |
refactor |
Refatoração sem mudança de comportamento |
chore |
Tarefas de manutenção |
Porta 5173 já em uso (frontend):
npm run dev -- --port 4000Porta 3000 já em uso (API):
# Edite a constante PORT em api/server.js
const PORT = 3001;Erros de SCSS não resolvido:
npm install sassRota em branco / 404 em produção (frontend):
O projeto usa BrowserRouter (history API). Em servidores estáticos (Nginx, Apache), configure o redirecionamento de todas as rotas para index.html:
location / {
try_files $uri $uri/ /index.html;
}Dados da API reiniciam ao reiniciar o servidor:
Esperado — a API usa armazenamento em memória. Para persistência, integre um banco de dados (ex.: SQLite, MongoDB, PostgreSQL).
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para detalhes.
Feito com ❤️ por Alexandre Cavalari — SherloCod3