feat: internacionalizacao (PT/EN) - infra + navegacao principal - #17
Merged
Conversation
Primeira fatia de i18n: a aplicacao inteira estava 100% em portugues, sem nenhuma infraestrutura de traducao. Este PR cobre a base + as telas que todo usuario ve sempre; o restante (~65 telas, mensagens do backend, busca multilingue) fica para PRs seguintes. - react-i18next + i18next-browser-languagedetector, com deteccao por localStorage (prioridade) e idioma do navegador (fallback) - LanguageSwitcher na navbar (botao PT/EN, ao lado do tema) - a troca e instantanea e persiste sozinha via o proprio i18next - Traduzido: Sidebar (menu completo), Layout/navbar (busca rapida, titulos de pagina, botoes), Login/Register/MagicLink, Dashboard Validado navegando de verdade no browser (nao so build): troquei o idioma via localStorage e a tela de login re-renderizou 100% em ingles, sem erro de console.
Contributor
There was a problem hiding this comment.
Pull request overview
Introduz a infraestrutura de internacionalização (PT/EN) no frontend usando i18next/react-i18next, adicionando alternância de idioma na navegação e convertendo a navegação principal e autenticação/Dashboard para usar chaves de tradução.
Changes:
- Adiciona configuração de i18n (i18next + detector) e arquivos de locale
pt.json/en.json. - Integra
useTranslation()em Layout/Sidebar/QuickSearch e páginas de auth + Dashboard. - Inclui
LanguageSwitcherna navbar e adiciona dependências nopackage.json/lockfile.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/pages/Dashboard.jsx | Troca strings hardcoded por t(...) e usa i18n.t(...) fora do componente para time-ago. |
| frontend/src/pages/auth/Register.jsx | Internacionaliza labels, placeholders e mensagens de erro de validação. |
| frontend/src/pages/auth/MagicLink.jsx | Internacionaliza mensagens/labels do fluxo de magic link. |
| frontend/src/pages/auth/Login.jsx | Internacionaliza mensagens de erro/sucesso e textos do fluxo de login/magic link. |
| frontend/src/main.jsx | Inicializa i18n via import side-effect. |
| frontend/src/i18n/locales/pt.json | Adiciona traduções PT para navegação/auth/dashboard. |
| frontend/src/i18n/locales/en.json | Adiciona traduções EN para navegação/auth/dashboard. |
| frontend/src/i18n/index.js | Configura i18next + detector (localStorage/navigator), fallback e resources. |
| frontend/src/components/Sidebar.jsx | Converte menu/grupos/itens para labels traduzidos via t. |
| frontend/src/components/QuickSearch.jsx | Internacionaliza placeholder, loading e empty-state. |
| frontend/src/components/Layout.jsx | Internacionaliza títulos/labels da navbar e adiciona LanguageSwitcher. |
| frontend/src/components/LanguageSwitcher.jsx | Novo componente de alternância PT/EN na navbar. |
| frontend/package.json | Adiciona dependências i18next/react-i18next e detector. |
| frontend/package-lock.json | Atualiza lockfile para refletir novas dependências/versões. |
Files not reviewed (1)
- frontend/package-lock.json: Generated file
Suppressed comments (4)
frontend/src/i18n/locales/pt.json:116
kbsCounté usado comcounte hoje sempre retorna "{{count}} KBs"; paracount === 1resultará em "1 KBs". Use pluralização do i18next.
"kbsCount": "{{count}} KBs",
frontend/src/i18n/locales/pt.json:127
stepsCountusacountmas está sempre no plural ("passos"); comcount === 1vira "1 passos". Use chaves pluralizadas do i18next.
"stepsCount": "{{count}} passos",
frontend/src/i18n/locales/en.json:116
kbsCounté usado comcounte hoje sempre retorna "{{count}} KBs"; paracount === 1resultará em "1 KBs". Use pluralização do i18next.
"kbsCount": "{{count}} KBs",
frontend/src/i18n/locales/en.json:127
stepsCountusacountmas está sempre no plural ("steps"); comcount === 1vira "1 steps". Use chaves pluralizadas do i18next.
"stepsCount": "{{count}} steps",
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
15
to
+19
| useEffect(() => { | ||
| const token = searchParams.get('token'); | ||
|
|
||
| if (!token) { | ||
| setError('Invalid magic link'); | ||
| setError(t('auth.invalidMagicLink')); |
Comment on lines
+18
to
+23
| <button | ||
| onClick={toggle} | ||
| className="btn btn-link nav-link p-2 border-0 fw-semibold" | ||
| style={{ minWidth: '2.5rem' }} | ||
| title={t('navbar.switchLanguage')} | ||
| > |
Comment on lines
+19
to
+20
| // Menu configuration with groups. `t` vem do i18next - a config em si | ||
| // (paths, icones, roles) e fixa, so os labels mudam por idioma. |
Comment on lines
+658
to
+659
| // Fica fora do componente (usado em contexto sem hooks), por isso usa a | ||
| // instancia do i18n diretamente em vez do hook useTranslation. |
| "favorites": "Favoritos", | ||
| "growthInPeriod": "{{value}}% no período", | ||
| "contentHealth": "Saúde do Conteúdo", | ||
| "kbsAwaitingApproval": "{{count}} KBs aguardando sua aprovação", |
| "favorites": "Favorites", | ||
| "growthInPeriod": "{{value}}% in period", | ||
| "contentHealth": "Content Health", | ||
| "kbsAwaitingApproval": "{{count}} KBs awaiting your approval", |
This was referenced Aug 3, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Escopo (combinado antes de começar)
A aplicação inteira (70 arquivos entre páginas e componentes) estava em português direto no código, sem nenhuma lib de i18n instalada. Traduzir tudo de uma vez — telas, mensagens de erro do backend, emails, busca — é trabalho de várias sessões. Este PR entrega o que foi combinado como primeira fatia: infraestrutura + navegação principal, deixando a base pronta pra ir cobrindo o resto incrementalmente.
O que entra
react-i18next+i18next-browser-languagedetector, com detecção porlocalStorage(prioridade — escolha explícita do usuário) e idioma do navegador como fallback na primeira visitaLanguageSwitcherna navbar (botão PT/EN, ao lado do toggle de tema) — troca instantânea, sem reload, e persiste sozinhaO que ainda fica em português (próximos PRs)
default_languageconfigurado (bug pré-existente que isso revelou: hoje ele usa stemming em inglês sobre conteúdo em português). A busca semântica (embeddings, já existente) é o caminho mais natural pra funcionar nos dois idiomas sem reindexar tudo, mas isso fica pra quando entrarmos nesse pedaço especificamente.Validação
Não dava pra rodar a aplicação completa aqui (mesma limitação de rede de sempre — o Mongo não é alcançável deste sandbox), mas a tela de login não depende de backend pra renderizar. Servi o build de produção (
vite preview) e testei de verdade no navegador via Chrome:localStorage.languagepraene recarreguei — a tela virou 100% inglês (Sign in to your account, Email, Password, Sign In...), sem nenhum erro no consoleScreenshots do teste disponíveis se quiser conferir.
Test plan
npm run buildsem erros (1738 módulos)