# Manual do Blog inMotion

## Índice
1. [Visão Geral](#visão-geral)
2. [Aspectos Técnicos](#aspectos-técnicos)
3. [Manual do Utilizador](#manual-do-utilizador)
4. [Painel de Administração](#painel-de-administração)
5. [Gestão de Conteúdo](#gestão-de-conteúdo)
6. [Troubleshooting](#troubleshooting)

---

## Visão Geral

O **inMotion** é um blog profissional dedicado ao Pilates, desenvolvido com tecnologias modernas para oferecer uma experiência completa de gestão de conteúdo.

### Características Principais
- ✅ Blog profissional com artigos sobre Pilates
- ✅ Sistema de comentários interativos
- ✅ Formulário de contacto
- ✅ Painel de administração completo
- ✅ Pesquisa e filtros por categoria
- ✅ Design responsivo (desktop, tablet, mobile)
- ✅ SEO-friendly

---

## Aspectos Técnicos

### Arquitetura da Aplicação

```
┌─────────────────────────────────────────┐
│           Frontend (React)              │
│  - Interface do utilizador              │
│  - Componentes shadcn/ui                │
│  - Routing com React Router            │
└──────────────┬──────────────────────────┘
               │ HTTP/REST API
┌──────────────▼──────────────────────────┐
│          Backend (FastAPI)              │
│  - API REST                             │
│  - Validação de dados                   │
│  - Lógica de negócio                    │
└──────────────┬──────────────────────────┘
               │ MongoDB Driver
┌──────────────▼──────────────────────────┐
│        Base de Dados (MongoDB)          │
│  - Artigos                              │
│  - Categorias                           │
│  - Comentários                          │
│  - Mensagens de Contacto                │
└─────────────────────────────────────────┘
```

### Stack Tecnológica

#### Frontend
- **React 19.0.0**: Framework JavaScript
- **React Router v7**: Navegação
- **Axios**: Cliente HTTP
- **Shadcn/ui**: Componentes UI
- **Tailwind CSS**: Estilização
- **Lucide React**: Ícones

#### Backend
- **FastAPI 0.110.1**: Framework Python
- **Motor 3.3.1**: Driver assíncrono MongoDB
- **Pydantic**: Validação de dados
- **Python 3.8+**: Linguagem

#### Base de Dados
- **MongoDB**: Base de dados NoSQL

### Estrutura de Ficheiros

```
/app
├── frontend/
│   ├── src/
│   │   ├── components/
│   │   │   ├── ui/              # Componentes shadcn
│   │   │   ├── Header.jsx       # Cabeçalho
│   │   │   ├── Footer.jsx       # Rodapé
│   │   │   └── ArticleCard.jsx  # Card de artigo
│   │   ├── pages/
│   │   │   ├── Home.jsx         # Página inicial
│   │   │   ├── Blog.jsx         # Listagem de artigos
│   │   │   ├── Article.jsx      # Artigo individual
│   │   │   ├── About.jsx        # Sobre
│   │   │   ├── Contact.jsx      # Contactos
│   │   │   └── Admin.jsx        # Painel admin
│   │   ├── services/
│   │   │   └── api.js           # Serviço API
│   │   ├── App.js               # Aplicação principal
│   │   └── index.css            # Estilos globais
│   ├── package.json
│   └── .env                     # Variáveis de ambiente
├── backend/
│   ├── server.py                # Servidor FastAPI
│   ├── models.py                # Modelos de dados
│   ├── seed_data.py             # Dados iniciais
│   ├── requirements.txt
│   └── .env                     # Variáveis de ambiente
└── contracts.md                 # Documentação API
```

### Variáveis de Ambiente

#### Frontend (.env)
```env
REACT_APP_BACKEND_URL=https://seu-dominio.com
```

#### Backend (.env)
```env
MONGO_URL=mongodb://localhost:27017
DB_NAME=inmotion_blog
```

### API Endpoints

#### Artigos
- `GET /api/articles` - Listar todos os artigos
  - Query params: `category`, `search`, `featured`, `limit`
- `GET /api/articles/featured` - Artigos em destaque
- `GET /api/articles/:slug` - Obter artigo por slug
- `POST /api/articles` - Criar artigo
- `PUT /api/articles/:id` - Atualizar artigo
- `DELETE /api/articles/:id` - Eliminar artigo

#### Categorias
- `GET /api/categories` - Listar categorias
- `POST /api/categories` - Criar categoria
- `DELETE /api/categories/:id` - Eliminar categoria

#### Comentários
- `GET /api/articles/:articleId/comments` - Listar comentários
- `POST /api/articles/:articleId/comments` - Criar comentário

#### Mensagens
- `GET /api/messages` - Listar mensagens (admin)
- `POST /api/messages` - Criar mensagem
- `PATCH /api/messages/:id/read` - Marcar como lida

### Modelos de Dados

#### Article
```json
{
  "id": "string",
  "title": "string",
  "slug": "string (unique)",
  "excerpt": "string",
  "content": "string",
  "author": "string",
  "category": "string",
  "tags": ["string"],
  "imageUrl": "string",
  "featured": "boolean",
  "publishedAt": "datetime",
  "createdAt": "datetime",
  "updatedAt": "datetime"
}
```

#### Category
```json
{
  "id": "string",
  "name": "string",
  "slug": "string (unique)",
  "count": "integer"
}
```

#### Comment
```json
{
  "id": "string",
  "articleId": "string",
  "author": "string",
  "content": "string",
  "createdAt": "datetime"
}
```

#### ContactMessage
```json
{
  "id": "string",
  "name": "string",
  "email": "string",
  "message": "string",
  "read": "boolean",
  "createdAt": "datetime"
}
```

### Instalação e Configuração

#### Pré-requisitos
- Node.js 16+
- Python 3.8+
- MongoDB 4.4+

#### Instalação Frontend
```bash
cd /app/frontend
yarn install
yarn start
```

#### Instalação Backend
```bash
cd /app/backend
pip install -r requirements.txt
uvicorn server:app --reload --host 0.0.0.0 --port 8001
```

#### Inicializar Base de Dados
Na primeira execução, a base de dados é automaticamente populada com dados de exemplo. Para re-popular:
```bash
curl -X POST http://localhost:8001/api/seed
```

### Gestão de Serviços (Supervisor)

```bash
# Verificar status
sudo supervisorctl status

# Reiniciar serviços
sudo supervisorctl restart frontend
sudo supervisorctl restart backend
sudo supervisorctl restart all

# Ver logs
tail -f /var/log/supervisor/frontend.out.log
tail -f /var/log/supervisor/backend.out.log
```

---

## Manual do Utilizador

### Navegação no Blog

#### Página Inicial
A homepage apresenta:
- **Hero Section**: Mensagem de boas-vindas e botão para o blog
- **Artigos em Destaque**: Cards dos artigos marcados como destaque
- **Artigos Recentes**: Últimos 3 artigos publicados

#### Blog
Lista completa de artigos com:
- **Barra de Pesquisa**: Pesquisar por título ou conteúdo
- **Filtro de Categoria**: Filtrar artigos por categoria
- **Cards de Artigos**: Imagem, título, resumo, categoria e data

#### Artigo Individual
Visualização completa do artigo:
- Título e metadados (autor, data, número de comentários)
- Imagem featured
- Conteúdo completo formatado
- Tags relacionadas
- Secção de comentários
- Formulário para adicionar comentário

#### Página Sobre
Informações sobre:
- Missão do inMotion
- Valores (Paixão, Excelência, Comunidade)
- Sobre Margot Silva (instrutora)

#### Contactos
- Informações de contacto: margot@inmotionpilates.pt
- Formulário de contacto (Nome, Email, Mensagem)
- Horário de resposta

### Como Adicionar um Comentário

1. Navegue até ao artigo desejado
2. Role até à secção "Comentários"
3. Preencha o formulário:
   - **Nome**: O seu nome
   - **Comentário**: O seu comentário (mínimo 10 caracteres)
4. Clique em "Publicar Comentário"
5. O comentário aparecerá imediatamente na lista

### Como Enviar uma Mensagem de Contacto

1. Aceda à página "Contactos" no menu
2. Preencha o formulário:
   - **Nome**: O seu nome completo
   - **Email**: O seu endereço de email
   - **Mensagem**: A sua mensagem ou questão
3. Clique em "Enviar Mensagem"
4. Receberá uma notificação de sucesso
5. A equipa responderá em 24-48 horas

---

## Painel de Administração

### Acesso ao Painel Admin

URL: `https://seu-dominio.com/admin`

**Nota**: Atualmente não há autenticação implementada. Para produção, recomenda-se adicionar sistema de login.

### Interface do Painel

O painel admin tem 3 tabs principais:
1. **Artigos**: Gestão de artigos
2. **Categorias**: Gestão de categorias
3. **Mensagens**: Visualização de mensagens de contacto

---

## Gestão de Conteúdo

### Como Criar um Novo Artigo

1. Aceda ao **Painel Admin** (`/admin`)
2. Na tab "Artigos", clique em **"Novo Artigo"**
3. Preencha o formulário:

   **Campos Obrigatórios:**
   - **Título**: Título do artigo
     - Exemplo: "Pilates para Principiantes"
   
   - **Slug**: URL amigável (gerado automaticamente)
     - Exemplo: "pilates-para-principiantes"
     - Pode editar manualmente se necessário
   
   - **Resumo**: Breve descrição (2-3 linhas)
     - Aparece nos cards e listagens
     - Máximo recomendado: 150 caracteres
   
   - **Conteúdo**: Texto completo do artigo
     - Suporta formatação com `##` para títulos
     - Parágrafos separados por linha em branco
     - Exemplo:
       ```
       O Pilates é uma prática transformadora.

       ## Benefícios Principais

       O fortalecimento do core é fundamental.

       ## Como Começar

       Para iniciantes, recomendamos...
       ```
   
   - **Categoria**: Selecione uma categoria existente
     - Pilates, Iniciantes, Técnica, Saúde, Bem-estar
   
   - **Tags**: Palavras-chave separadas por vírgula
     - Exemplo: "pilates, iniciantes, exercício"
   
   - **URL da Imagem**: Link para imagem do artigo
     - Recomendado: 800x600px ou superior
     - Exemplo: `https://images.unsplash.com/photo-xxx`

   **Campos Opcionais:**
   - **Artigo em Destaque**: Marcar checkbox para destacar na homepage

4. Clique em **"Guardar Artigo"**
5. O artigo aparecerá imediatamente no blog

### Como Editar um Artigo Existente

**Nota**: Funcionalidade de edição está preparada no backend, mas precisa de ser implementada no frontend.

**Workaround atual**:
1. Elimine o artigo antigo
2. Crie um novo artigo com as alterações

**Para implementar edição** (desenvolvimento futuro):
- Adicionar botão "Editar" na listagem de artigos
- Carregar dados do artigo no formulário
- Usar endpoint `PUT /api/articles/:id`

### Como Eliminar um Artigo

1. No painel admin, tab "Artigos"
2. Localize o artigo na tabela
3. Clique no ícone **vermelho de lixeira** (🗑️)
4. Confirme a eliminação
5. O artigo e todos os seus comentários serão removidos

### Como Criar uma Nova Categoria

1. No painel admin, vá à tab **"Categorias"**
2. Clique em **"Nova Categoria"**
3. Preencha:
   - **Nome**: Nome da categoria
     - Exemplo: "Exercícios Avançados"
   - **Slug**: URL amigável (gerado automaticamente)
     - Exemplo: "exercicios-avancados"
4. Clique em **"Guardar Categoria"**
5. A categoria estará disponível para novos artigos

### Como Gerir Mensagens de Contacto

1. Aceda à tab **"Mensagens"**
2. Visualize as mensagens recebidas:
   - **Novas mensagens**: Destacadas com badge "Nova"
   - **Informações**: Nome, email, mensagem, data
3. Para responder:
   - Clique no email para abrir cliente de email
   - Envie a resposta
4. Marque como lida:
   - Clique em **"Marcar como lida"**
   - A mensagem perde o destaque "Nova"

### Boas Práticas para Conteúdo

#### Títulos de Artigos
- ✅ Claros e descritivos
- ✅ 40-60 caracteres
- ✅ Incluir palavra-chave principal
- ❌ Evitar clickbait
- ❌ Não usar maiúsculas excessivas

**Exemplos:**
- ✅ "Os 5 Exercícios de Pilates para Fortalecer o Core"
- ✅ "Pilates Durante a Gravidez: Guia Completo"
- ❌ "VOCÊ NÃO VAI ACREDITAR NISTO!"

#### Resumos
- ✅ 100-150 caracteres
- ✅ Resumir o valor do artigo
- ✅ Incluir palavra-chave
- ❌ Não copiar primeira frase do artigo

#### Conteúdo
- ✅ Usar títulos (##) para estrutura
- ✅ Parágrafos curtos (3-4 linhas)
- ✅ Listas quando apropriado
- ✅ Linguagem clara e acessível
- ❌ Evitar jargão excessivo

#### Imagens
- ✅ Relevantes ao tema
- ✅ Alta qualidade (min. 800px largura)
- ✅ Formato: JPG ou PNG
- Recomendação: Usar Unsplash (gratuito)

#### Tags
- ✅ 3-5 tags por artigo
- ✅ Palavras-chave relevantes
- ✅ Minúsculas, separadas por vírgula
- Exemplo: "pilates, exercício, saúde, bem-estar"

#### Categorias
- Usar categorias existentes sempre que possível
- Criar nova categoria apenas se necessário
- Manter estrutura organizada (5-10 categorias máximo)

### SEO e Otimização

#### Slugs (URLs)
O slug é gerado automaticamente a partir do título, mas pode ser editado:
- ✅ Curto e descritivo
- ✅ Apenas letras, números e hífens
- ✅ Palavra-chave principal incluída
- ❌ Sem caracteres especiais ou espaços

**Exemplo:**
- Título: "A Importância da Respiração no Pilates"
- Slug automático: `a-importancia-da-respiracao-no-pilates`
- Slug otimizado: `respiracao-pilates` ✅

#### Palavra-chave Principal
Incluir em:
- Título do artigo
- Slug
- Resumo
- Primeiro parágrafo
- Pelo menos um título (##)
- Tags

---

## Troubleshooting

### Problemas Comuns e Soluções

#### Frontend não carrega / Página em branco

**Problema**: A página não carrega ou mostra erro

**Soluções:**
```bash
# 1. Verificar se o frontend está a correr
sudo supervisorctl status frontend

# 2. Ver logs de erro
tail -n 50 /var/log/supervisor/frontend.err.log

# 3. Reiniciar frontend
sudo supervisorctl restart frontend

# 4. Se não resolver, reinstalar dependências
cd /app/frontend
rm -rf node_modules
yarn install
sudo supervisorctl restart frontend
```

#### API retorna erro 500

**Problema**: Erros ao criar/editar artigos

**Soluções:**
```bash
# 1. Verificar logs do backend
tail -n 50 /var/log/supervisor/backend.err.log

# 2. Verificar conexão MongoDB
mongo --eval "db.adminCommand('ping')"

# 3. Reiniciar backend
sudo supervisorctl restart backend

# 4. Verificar variáveis de ambiente
cat /app/backend/.env
```

#### Artigos não aparecem

**Problema**: Blog vazio ou artigos não carregam

**Soluções:**
```bash
# 1. Re-popular base de dados
curl -X POST http://localhost:8001/api/seed

# 2. Verificar MongoDB
mongo inmotion_blog --eval "db.articles.count()"

# 3. Verificar logs da API
tail -n 50 /var/log/supervisor/backend.out.log
```

#### Imagens não carregam

**Problema**: Imagens quebradas nos artigos

**Causas comuns:**
- URL inválida
- Imagem foi removida da fonte
- Problemas de CORS

**Soluções:**
- Usar URLs de serviços confiáveis (Unsplash, Imgur)
- Testar URL no navegador antes de usar
- Considerar hospedar imagens localmente

#### Formulário de contacto não envia

**Problema**: Mensagem não é enviada

**Soluções:**
```bash
# 1. Verificar console do navegador (F12)
# 2. Testar API diretamente
curl -X POST http://localhost:8001/api/messages \
  -H "Content-Type: application/json" \
  -d '{"name":"Teste","email":"teste@teste.pt","message":"Teste"}'

# 3. Verificar logs
tail -n 30 /var/log/supervisor/backend.out.log
```

#### Comentários não aparecem

**Problema**: Comentários enviados mas não aparecem

**Soluções:**
```bash
# 1. Verificar base de dados
mongo inmotion_blog --eval "db.comments.find().pretty()"

# 2. Limpar cache do navegador
# 3. Verificar articleId correto
```

### Logs Importantes

#### Ver todos os logs
```bash
# Frontend output
tail -f /var/log/supervisor/frontend.out.log

# Frontend errors
tail -f /var/log/supervisor/frontend.err.log

# Backend output
tail -f /var/log/supervisor/backend.out.log

# Backend errors
tail -f /var/log/supervisor/backend.err.log
```

#### Limpar logs antigos
```bash
# Limpar logs frontend
> /var/log/supervisor/frontend.out.log
> /var/log/supervisor/frontend.err.log

# Limpar logs backend
> /var/log/supervisor/backend.out.log
> /var/log/supervisor/backend.err.log
```

### Backup e Restauro

#### Backup da Base de Dados
```bash
# Exportar todos os dados
mongodump --db inmotion_blog --out /backup/$(date +%Y%m%d)

# Exportar apenas artigos
mongoexport --db inmotion_blog --collection articles --out articles_backup.json
```

#### Restaurar Base de Dados
```bash
# Restaurar backup completo
mongorestore --db inmotion_blog /backup/20240103/inmotion_blog

# Importar artigos
mongoimport --db inmotion_blog --collection articles --file articles_backup.json
```

### Performance

#### Otimizar MongoDB
```bash
# Criar índices para melhor performance
mongo inmotion_blog --eval '
  db.articles.createIndex({"slug": 1});
  db.articles.createIndex({"category": 1});
  db.articles.createIndex({"featured": 1});
  db.articles.createIndex({"publishedAt": -1});
'
```

#### Limpar dados antigos
```bash
# Remover comentários com mais de 1 ano
mongo inmotion_blog --eval '
  db.comments.deleteMany({
    "createdAt": {
      $lt: new Date(new Date().setFullYear(new Date().getFullYear() - 1))
    }
  })
'
```

---

## Manutenção Regular

### Tarefas Diárias
- ✅ Verificar mensagens de contacto novas
- ✅ Responder a comentários
- ✅ Verificar se o site está online

### Tarefas Semanais
- ✅ Publicar 1-2 artigos novos
- ✅ Revisar e responder todas as mensagens
- ✅ Verificar logs de erro

### Tarefas Mensais
- ✅ Backup completo da base de dados
- ✅ Analisar artigos mais populares
- ✅ Limpar comentários spam (se existirem)
- ✅ Verificar e atualizar imagens quebradas

### Tarefas Trimestrais
- ✅ Revisar e atualizar artigos antigos
- ✅ Adicionar novas categorias se necessário
- ✅ Otimizar base de dados (índices)

---

## Suporte Técnico

### Informações de Contacto

**Para questões técnicas:**
- Verificar documentação: `/app/contracts.md`
- Logs: `/var/log/supervisor/`
- Código fonte: `/app/frontend` e `/app/backend`

### Recursos Adicionais

**Documentação das Tecnologias:**
- React: https://react.dev
- FastAPI: https://fastapi.tiangolo.com
- MongoDB: https://docs.mongodb.com
- Shadcn/ui: https://ui.shadcn.com
- Tailwind CSS: https://tailwindcss.com

**Comunidades:**
- Stack Overflow
- Reddit: r/reactjs, r/FastAPI
- Discord: Reactiflux, FastAPI

---

## Roadmap de Melhorias Futuras

### Curto Prazo (1-3 meses)
- [ ] Sistema de autenticação para admin
- [ ] Edição de artigos no painel admin
- [ ] Paginação de artigos
- [ ] Upload de imagens local
- [ ] Sistema de tags mais robusto

### Médio Prazo (3-6 meses)
- [ ] Sistema de likes/reações
- [ ] Partilha em redes sociais
- [ ] Newsletter por email
- [ ] Analytics e estatísticas
- [ ] Pesquisa avançada

### Longo Prazo (6+ meses)
- [ ] Múltiplos autores
- [ ] Agendamento de publicações
- [ ] Versões de artigos (histórico)
- [ ] Tradução multi-idioma
- [ ] App mobile

---

**Versão do Manual**: 1.0  
**Última Atualização**: Janeiro 2026  
**Blog**: inMotion Pilates  
**Email**: margot@inmotionpilates.pt
