## Resumo Geral do Projeto (Atualizado em 27/11/2025) ### 1. Visão Geral - Plataforma Next.js full-stack com duas frentes principais: - **Site público** dentro de `src/app/(public)` e rotas localizadas em `src/app/[locale]` alimentadas por conteúdo dinâmico vindo do CMS. - **Painel Admin** em `src/app/admin` para operação interna (gestão de páginas, serviços, projetos, usuários e mensagens). - Back-end único via rotas App Router + Prisma/PostgreSQL (`prisma/pageContent`, `project`, `service`, etc.). ### 2. Conteúdo Dinâmico & CMS - CRUD de páginas no admin acessa `/api/pages` (genérico) e `/api/pages/[slug]` (detalhe com autenticação JWT). - Páginas gerenciadas até agora: `home`, `sobre`, `contato`, além de `config` (metadados globais) e rotas públicas estruturadas. - Formular pós-edição acionam `translation:refresh` no front para atualizar badges do sininho. - Layout administrativo (`admin/layout.tsx`) fornece sidebar, menu, avatar modal, confirmação padrão e o **painel de traduções** com polling + badge. ### 3. Plataforma de Traduções - Salvar conteúdo em PT dispara `translateInBackground` (EN/ES) dentro de `src/app/api/pages/[slug]/route.ts` utilizando LibreTranslate + cache em `prisma.translation`. - API auxiliar `/api/admin/translate-pages` permite rodadas manuais e retorno de status consolidado. - Front exibe estado por slug (Concluída / Em andamento) e dispara notificações quando pendências são resolvidas. - Job `prisma/check-translations.mjs` e script `scripts/checkTranslations.cjs` ajudam na auditoria dos timestamps. - Endpoint redundante `/api/pages/contact` foi removido para evitar inconsistências; tudo passa pelo handler dinâmico. ### 4. Experiência do Editor - Campos do CMS agora possuem limites visuais via `CharLimitBadge` (estilo Twitter) com `LabelWithLimit`, aplicados a **Home**, **Sobre** e **Contato**. - Limites também reforçados com `maxLength` para impedir que textos comprometam o layout público. - Foram definidos ícones reutilizáveis (selector custom) e componentes de formulário padronizados. ### 5. Site Público - Utiliza `useTranslatedContent` + `` para mesclar conteúdo dinâmico com fallback estático. - Páginas principais refletem exatamente o que foi configurado no admin (banner hero, diferenciais, CTA, depoimentos, etc.). - Formulário de contato envia para `/api/messages`, com feedback via `ToastContext`. ### 6. Segurança e Infra - Autenticação do admin baseada em cookie `auth_token` (JWT) validado nas rotas protegidas. - Upload/remoção de avatar gerenciado via `/api/auth/avatar` com modal padrão. - Prisma centraliza o schema (`User`, `Project`, `Service`, `Message`, `PageContent`, `Translation`). ### 7. Histórico de Entregas Relevantes 1. Estruturação do CMS e rotas dinâmicas para páginas públicas. 2. Implementação de tradução automática assíncrona + cache. 3. Criação do painel de notificações com polling/badges. 4. Inclusão de limites de caracteres visíveis e enforce client-side. 5. Remoção de API duplicada e ajustes para manter EN/ES sincronizados. ### 8. Pendências & Próximos Passos - Rodar tradução manual para `contact` e `config` (EN/ES ainda desatualizados segundo `scripts/checkTranslations.cjs`). - Expandir o CMS para outras páginas (ex.: serviços e projetos públicos) caso necessário. - Opcional: reforçar validação server-side dos limites e criar testes automatizados para o fluxo de tradução. Este resumo deve servir como onboarding rápido para qualquer pessoa ou nova IA que precise continuar o desenvolvimento. --- ## CMS 1.1 - Atualizações (27/11/2025) ### 🔧 Correções de Infraestrutura - Tipagem de `params` para Next.js 15 nas API routes (`/api/projects/[id]`, `/api/services/[id]`) - Correção para usar `Promise<{ id: string }>` e `await params` --- ### 📊 Dashboard Admin Dinâmico O dashboard agora exibe dados reais do banco de dados: | Estatística | Descrição | |-------------|-----------| | Projetos | Total e quantidade de ativos | | Mensagens | Total e quantidade não lidas | | Serviços | Total e quantidade ativos | **Novas funcionalidades:** - Últimas 5 mensagens com iniciais do nome, tempo relativo e indicador de não lida - Últimos 5 projetos com imagem de capa, categoria e badge de status - Cards clicáveis que redirecionam para as páginas correspondentes - Botões "Ver todos" funcionais --- ### 🛠️ Módulo de Serviços (CRUD Completo) #### Admin - Lista de Serviços (`/admin/servicos`) - Dados dinâmicos da API `/api/services` - Filtro por status (Todos/Ativos/Inativos) - Busca por título e descrição - Botões de Editar e Excluir - Modal de confirmação antes de excluir #### Admin - Novo Serviço (`/admin/servicos/novo`) - Formulário conectado à API `POST /api/services` - **Seletor visual de ícones em galeria** com busca em tempo real - **70+ ícones** organizados por categoria: - Veículos e Transporte - Ferramentas e Engenharia - Documentos e Laudos - Segurança - Construção e Equipamentos - Inspeção e Verificação - Geral - Campos: título, ícone, status, ordem, descrição curta, descrição completa #### Admin - Editar Serviço (`/admin/servicos/[id]/editar`) - **NOVO** - Página criada do zero - Carrega dados do serviço existente via `GET /api/services/:id` - Atualiza via `PUT /api/services/:id` - Mesmo seletor visual de ícones da página de criação #### Páginas Públicas de Serviços - `/servicos` e `/[locale]/servicos` agora são dinâmicas - Exibe apenas serviços **ativos** - Ordenados pelo campo `order` - Fallback para dados estáticos se API vazia - Loading state durante carregamento --- ### 📁 Módulo de Projetos (Melhorias) #### Admin - Lista de Projetos (`/admin/projetos`) - Filtros por categoria e status - Busca por título, cliente e descrição - Botão de Editar em cada projeto #### Admin - Editar Projeto (`/admin/projetos/[id]/editar`) - **NOVO** - Página criada do zero - Carrega dados do projeto existente - Upload de imagem de capa - Upload de galeria de imagens (até 8) - Todos os campos editáveis --- ### 🎨 Melhorias de UX/UI | Feature | Descrição | |---------|-----------| | Seletor de Ícones | Galeria visual clicável com busca em tempo real | | Loading States | Indicadores visuais de carregamento em todas as páginas | | Toasts | Feedback de sucesso e erro nas operações | | Confirmação | Modal antes de ações destrutivas (exclusão) | | Navegação | Links e botões funcionais em todo admin | --- ### 📁 Arquivos Modificados/Criados ``` frontend/src/app/admin/ ├── page.tsx # Dashboard com dados reais ├── projetos/ │ ├── page.tsx # Lista com filtros e busca │ └── [id]/editar/page.tsx # ✨ NOVO - Edição de projeto └── servicos/ ├── page.tsx # Lista com filtros e busca ├── novo/page.tsx # Seletor visual de ícones └── [id]/editar/page.tsx # ✨ NOVO - Edição de serviço frontend/src/app/ ├── (public)/servicos/page.tsx # Página pública dinâmica └── [locale]/servicos/page.tsx # Página com locale dinâmica frontend/src/app/api/projects/[id]/ └── route.ts # Corrigido tipagem Next.js 15 ``` --- **Branch**: `cms-1.1` **Status**: ✅ Produção --- ## CMS 1.2 - Atualizações (28/11/2025) ### 📱 WhatsApp Dinâmico #### API de Informações de Contato (`/api/contact-info`) - Nova rota que busca número do WhatsApp dinamicamente do CMS - Busca dados da página `contato` slug - Cache de 1 minuto para otimizar performance - Fallback para número padrão `(35) 9882-9445` com link `https://wa.me/5535988229445` - Retorna JSON: `{ whatsapp: string, whatsappLink: string }` #### Integração no Botão Flutuante - `WhatsAppButton.tsx` agora busca número da API `/api/contact-info` - Abre WhatsApp diretamente com número do CMS - Exibe label traduzido `whatsapp.label` #### Integração no Header - Botão "Fale Conosco" no header desktop agora abre WhatsApp diretamente - Menu mobile também integrado - Ambos buscam número da API em tempo real #### Tradução do Label - Adicionada chave `whatsapp.label` em todos os locales: - PT: "Fale Conosco" - EN: "Contact Us" - ES: "Contáctenos" - Adicionada no `LanguageContext.tsx` para fallback --- ### 🌙 Dark Mode no Painel Admin #### Novo Botão de Tema - Adicionado botão sol/lua no header do painel admin - Localizado ao lado das notificações - Mesmo comportamento do botão no site público - Integrado com `useTheme` hook #### Funcionalidade - Toggle claro/escuro funcional em todo o admin - Persistência de preferência via `next-themes` - Ícone muda conforme tema: `ri-sun-line` (dark) / `ri-moon-line` (light) --- ### 🔗 Correção de Links do Dashboard #### Links das Mensagens - Card "Mensagens" → `/admin/mensagens` - Botão "Ver todas" → `/admin/mensagens` - Cada item de mensagem → `/admin/mensagens` - Antes: apontavam para `/admin/contatos` (rota inexistente) #### Estrutura de Rotas - Confirmado que rota correta é `/admin/mensagens` - Não existe `/admin/contatos` no projeto --- ### ✅ Correções Finais de WhatsApp #### Formato Correto do Número - **Número fornecido**: `+55 35 9882-9445` - **Formato wa.me**: `5535988229445` - `55` = código Brasil - `35` = DDD - `988229445` = número com 9 dígitos (padrão celular BR) #### Atualização em Todos os Arquivos - API `/api/contact-info/route.ts` - Componente `WhatsAppButton.tsx` - Componente `Header.tsx` - Todos agora usam `5535988229445` como padrão --- ### 📁 Arquivos Modificados (28/11) ``` frontend/src/app/api/ └── contact-info/ └── route.ts # ✨ NOVO - API WhatsApp dinâmico frontend/src/components/ ├── WhatsAppButton.tsx # Integração API contact-info └── Header.tsx # Integração API contact-info frontend/src/app/admin/ ├── layout.tsx # Dark mode + links corrigidos └── page.tsx # Links mensagens corrigidos frontend/src/contexts/ └── LanguageContext.tsx # Adicionado whatsapp.label frontend/src/locales/ ├── pt.json # Adicionado whatsapp.label ├── en.json # Adicionado whatsapp.label └── es.json # Adicionado whatsapp.label ``` --- ## Commits Realizados (28/11/2025) ### Commit 1: WhatsApp Dinâmico ``` feat: WhatsApp dinâmico do CMS - Criada API /api/contact-info que busca número do CMS - Header e botão flutuante agora puxam número dinamicamente - Número padrão: (35) 9882-9445 ``` ### Commit 2: Tradução WhatsApp ``` fix: WhatsApp label tradução e número correto (35) 9882-9445 - Adicionada chave whatsapp.label nos arquivos de locale (pt, en, es) - Adicionada chave whatsapp.label no LanguageContext ``` ### Commit 3: Formato Correto ``` fix: número WhatsApp correto 5535988229445 - Corrigido número padrão em todos os arquivos - Formato correto: 55 (Brasil) + 35 (DDD) + 988229445 (número) ``` ### Commit 4: Dark Mode e Links ``` fix: dark mode no admin, links mensagens dashboard, WhatsApp correto - Adicionado botão de dark mode no header do painel admin - Corrigido links do dashboard: /admin/contatos -> /admin/mensagens - Corrigido número WhatsApp: 5535988229445 (formato correto BR) ``` --- ## 🚀 Status de Deployment ### Ambiente de Produção - **Domínio**: www.octtoengenharia.com.br - **Docker Compose**: `docker-compose.yml` (production) - **Banco**: PostgreSQL `occto_db` - **Storage**: MinIO `occto_minio` - **Frontend**: `occto_frontend` - **Network**: `dokploy-network` ### Infraestrutura - **Versão PostgreSQL**: 12-alpine - **Versão MinIO**: RELEASE.2023-09-04T19-57-37Z - **Framework**: Next.js 15.1 - **ORM**: Prisma - **Deploy Platform**: Dokploy (com auto-deploy) --- **Branch**: `cms-1.1` **Status**: ✅ Produção (Deploy 28/11/2025)