-
Notifications
You must be signed in to change notification settings - Fork 0
feat(aluno): dashboard UI polish — remove fake stats, fix spacing, clean up #193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
da9d39b
feat(aluno): dashboard UI polish — remove fake stats, fix spacing, cl…
EmiyaKiritsugu3 a749eb5
feat(seed): create Supabase Auth users for seed + E2E test credentials
EmiyaKiritsugu3 3b19d77
fix(seed): add HistoricoTreino to deleteMany order, fix top-level awa…
EmiyaKiritsugu3 46873d6
fix(aluno): remap Prisma Exercicios→exercicios so CardTreino renders …
EmiyaKiritsugu3 56dcac5
fix(pr-193): address all review findings — security, code quality, docs
EmiyaKiritsugu3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -165,3 +165,5 @@ graphify-out/ | |
| qa/ | ||
| .sisyphus/evidence/ | ||
| .omo/ | ||
| .env* | ||
| tmp-output.json | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,235 @@ | ||
| # PRD — Aprimoramento UI Aluno (PWeb_Project) | ||
|
|
||
| **Data**: 2026-07-07 | ||
| **Status**: Draft (aguarda aprovação) | ||
| **Branch alvo**: `feat/008-aluno-ui-premium` | ||
| **Dependências**: nenhuma | ||
| **Owner**: design + frontend | ||
|
|
||
| --- | ||
|
|
||
| ## 1. Contexto | ||
|
|
||
| Auditoria exaustiva da superfície Aluno (PWeb_Project / Five Star Gym / Aegis Fitness OS) identificou 25 melhorias concretas, ordenadas por impacto e risco. Esta PRD é a fonte de verdade para a execução. | ||
|
|
||
| **Stack**: Next.js 15 App Router · Tailwind v4 (OKLCH) · Inter + Outfit · lucide-icons · dark-first OLED · TypeScript strict. | ||
|
|
||
| **Constraint cultural**: ponytail (lazy senior dev) — diff mínimo, stdlib/native first, sem abstração especulativa, sem nova dep sem justificativa. | ||
|
|
||
| --- | ||
|
|
||
| ## 2. Visão | ||
|
|
||
| > Aluno abre o app e em 3 segundos vê seu próximo treino + progresso real, sem ruído, sem dados falsos, com hierarquia clara que impressiona sem exagerar. | ||
|
|
||
| --- | ||
|
|
||
| ## 3. Princípios (premium = disciplina, não efeito) | ||
|
|
||
| 1. **Sem dados falsos** — KPI inventado destrói confiança. | ||
| 2. **Hierarquia em 3 níveis** — Headline → ação primária → contexto. Sem 4º nível competindo. | ||
| 3. **Estado vazio é first-class** — aluno novo vê CTA claro, não tela morta. | ||
| 4. **A11y não é opcional** — heading semântico, autofocus correto, contrast AAA. | ||
| 5. **Spec ↔ código alinhados** — pill onde DESIGN.md diz pill. | ||
| 6. **Ponytail** — 1 arquivo, 1 tarefa, diff mínimo. | ||
|
|
||
| --- | ||
|
|
||
| ## 4. Fases | ||
|
|
||
| ### Fase 1 — Aluno Home (P1, bloqueia tudo) | ||
|
|
||
| **Por quê primeiro**: priorizado pelo usuário. Tela que ele abre primeiro. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------ | ------ | | ||
| | T01 | `src/app/aluno/dashboard/dashboard-client.tsx:224` | Remover KPI hardcoded (Meta Semanal 80%, Power Index 752). Substituir por `treinosConcluidos/semana` real; esconder card se 0. | `npm run typecheck` + screenshot 375px → "Sem treinos" | low | | ||
| | T02 | `src/app/aluno/dashboard/dashboard-client.tsx:266` | `flex justify-around gap-2` → `flex justify-center gap-2` nos 3 achievement badges. | Visual: badges com mesmo gutter | low | | ||
| | T03 | `src/app/aluno/dashboard/dashboard-client.tsx` (topo) | Empty state quando `treinos.length === 0`: card glass + "Bem-vindo, [nome]" + CTA "Falar com instrutor". | Login aluno novo → empty state | low | | ||
| | T04 | `src/app/aluno/dashboard/dashboard-client.tsx` | Hierarquia: próximo treino é o primeiro card visível (não KPIs). Move KPIs para abaixo. | Mobile viewport → próximo treino acima da dobra | medium | | ||
| | T05 | `src/app/aluno/dashboard/dashboard-client.tsx` (timer) | `aria-live="polite"` no timer + `role="timer"` + label humano. Sem pulse em `prefers-reduced-motion`. | axe DevTools 0 violations em timer | medium | | ||
|
|
||
| ### Fase 2 — Card-treino + meus-treinos (P1/P2) | ||
|
|
||
| **Por quê**: tela mais usada depois do home. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------- | ------ | | ||
| | T06 | `src/components/dashboard/aluno/card-treino.tsx:65` | `<CardTitle>` (renderiza `<div>`) → `<h3>` semântico com mesma classe. | axe: heading outline inclui título | low | | ||
| | T07 | `src/components/dashboard/aluno/card-treino.tsx` | Press feedback: `active:scale-[0.98] transition-transform` + `focus-visible:ring-2 ring-primary`. | Tab no card → ring visível | low | | ||
| | T08 | `src/app/aluno/meus-treinos/meus-treinos-client.tsx:183` | Renderizar 2-3 nomes de exercícios truncados abaixo do count. | Card mostra "Supino, Agachamento…" | low | | ||
| | T09 | `src/app/aluno/meus-treinos/meus-treinos-client.tsx` | Empty state quando 0 treinos: ícone lucide (Dumbbell) + "Você ainda não tem treinos" + CTA. | Login aluno novo → empty state | low | | ||
| | T10 | `src/app/aluno/meus-treinos/meus-treinos-client.tsx` | Loading skeleton (Tailwind `animate-pulse`) no lugar de spinner genérico. Respeita reduced-motion. | Refresh → vê skeleton 200ms | medium | | ||
|
|
||
| ### Fase 3 — Login first impression (P1) | ||
|
|
||
| **Por quê**: tela que define "esse app é bom?" em 5s. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ---- | | ||
| | T11 | `src/app/aluno/login/page.tsx:134` | Email: `autoComplete="email" type="email" inputMode="email" autoCapitalize="none"`. Password: `autoComplete="current-password"`. | 1Password preenche; mobile mostra teclado @ | low | | ||
| | T12 | `src/app/aluno/login/page.tsx` | Erro inline com `role="alert"` + `aria-describedby` no input. Sem toast que some. | Erro de credencial → foco no input, erro anunciado | low | | ||
| | T13 | `src/app/aluno/login/page.tsx` | Motion de entrada: fade+slide sutil no card (200ms ease-out). `prefers-reduced-motion` → fade only. | Reduced-motion ON → sem slide | low | | ||
|
|
||
| ### Fase 4 — A11y foundation (P1) | ||
|
|
||
| **Por quê**: conserta bugs que afetam tudo. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | -------------------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------- | ------ | | ||
| | T14 | `src/components/ui/circular-progress.tsx:61` | Add `viewBox="0 0 100 100"` + `aria-hidden="true"`. Valor numérico em texto separado. | axe 0 violations | low | | ||
| | T15 | `src/app/aluno/aluno-header.tsx:89` | Habilitar item "Perfil" do dropdown + criar rota `/aluno/perfil` (pode ser stub "Em breve"). | Dropdown → "Perfil" navega | medium | | ||
| | T16 | `src/app/aluno/aluno-header.tsx` | Avatar do menu: `aria-label="Menu do aluno"` (sem nome visível). | NVDA anuncia "Menu do aluno" | low | | ||
|
|
||
| ### Fase 5 — Design drift (P2) | ||
|
|
||
| **Por quê**: alinha spec ↔ código. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | -------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ | | ||
| | T17 | `src/components/ui/button.tsx:8` | `rounded-md` → `rounded-full` no default variant (DESIGN.md: "Pill-shaped for primary actions"). | `npm run build` OK; botões viram pill | low | | ||
| | T18 | `src/app/globals.css` | Adicionar `.text-gradient-cyan` (referenciada em dashboard-client:65 + landing page). | gradient visível | low | | ||
| | T19 | `src/app/globals.css` | Validar `--color-muted-foreground` ≥ 4.5:1 (AAA large). Ajustar lightness se <. | Lighthouse a11y ≥ 95 | medium | | ||
| | T20 | `src/components/bottom-nav.tsx` | Active state: além do `border-t-2`, adicionar `text-primary` (só border hoje). | Visual: tab ativo texto cyan + border | low | | ||
|
|
||
| ### Fase 6 — Brand polish (P3) | ||
|
|
||
| **Por quê**: consistência de identidade. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | -------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------- | ---- | | ||
| | T21 | `src/app/page.tsx` | "Academia Five Star" → "Five Star Gym" (consistente com brand). Tagline idem. | Texto da landing bate com DESIGN.md | low | | ||
| | T22 | `src/app/layout.tsx` | Validar `font-display: swap` (FOIT prevention) em Inter+Outfit. | Lighthouse Best Practices 100 | low | | ||
| | T23 | `DESIGN.md` | Documentar decisão: **Inter (body) + Outfit (headline)** — não SF Pro. Atualizar spec para refletir código. | Markdown diff | low | | ||
|
|
||
| ### Fase 7 — Motion + reduced-motion pass (P2) | ||
|
|
||
| **Por quê**: polish final + acessibilidade. | ||
|
|
||
| | ID | Arquivo | Mudança | Verify | Risk | | ||
| | --- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ---- | | ||
| | T24 | `src/app/globals.css` | `@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }` | DevTools reduced-motion ON → zero animação | low | | ||
| | T25 | `src/components/ui/button.tsx` + cards | `hover:scale-[1.02]` → `hover:brightness-110` (mais sutil, sem motion sickness). | DevTools mobile test | low | | ||
|
|
||
| --- | ||
|
|
||
| ## 5. KPIs (medir sucesso) | ||
|
|
||
| | KPI | Meta | Como medir | | ||
| | ------------------------------------------ | ----------- | ----------------------------------------------- | | ||
| | Lighthouse a11y score | ≥ 95 | Chrome DevTools / Lighthouse CI | | ||
| | axe DevTools violations (Aluno surfaces) | 0 | axe-core CLI no CI | | ||
| | Empty state coverage (treinos, conquistas) | 100% | Visual review: cada lista tem UI para 0 | | ||
| | KPI hardcoded em produção | 0 | `grep -E "['\"\`][0-9]+%['\"\`]" src/app/aluno` | | ||
| | Pill buttons em CTAs primárias | 100% | Visual review | | ||
| | `text-gradient-cyan` aplicado | sim | grep + visual | | ||
| | Mobile first paint | não regride | Lighthouse perf | | ||
|
|
||
| --- | ||
|
|
||
| ## 6. Ordem de execução | ||
|
|
||
| 1. **T01-T05** (Fase 1) — user abre app, vê algo bom. | ||
| 2. **T11-T13** (Fase 3) — user consegue logar com qualidade. | ||
| 3. **T14-T16** (Fase 4) — a11y base sólida. | ||
| 4. **T06-T10** (Fase 2) — navegação interna polida. | ||
| 5. **T17-T20** (Fase 5) — spec/code alinhados. | ||
| 6. **T21-T25** (Fases 6+7) — polish final. | ||
|
|
||
| **Total: 25 tasks · 12 arquivos · 0 deps novos.** | ||
|
|
||
| --- | ||
|
|
||
| ## 7. Out of scope (skipped, adicionar quando X) | ||
|
|
||
| - Ilustrações SVG custom para empty states — lucide cobre. Designer quando virar feature de marca. | ||
| - i18n de strings hardcoded — quando houver user en/es. | ||
| - Animações de entrada por rota (Framer Motion) — diff só se user pedir. | ||
| - Skeleton library dedicada — `animate-pulse` nativo cobre. Dep quando shapes ficarem complexos. | ||
|
|
||
| --- | ||
|
|
||
| ## 8. Workflow sugerido (execução) | ||
|
|
||
| ### Abordagem: feature branch + PRs por fase | ||
|
|
||
| #### 8.1. Setup (1 comando) | ||
|
|
||
| ```bash | ||
| git checkout -b feat/008-aluno-ui-premium | ||
| ``` | ||
|
|
||
| #### 8.2. Execução fase-a-fase (recomendado) | ||
|
|
||
| Para cada fase: | ||
|
|
||
| ```bash | ||
| # 1. Criar sub-branch | ||
| git checkout -b feat/008-fase-N-<slug> | ||
|
|
||
| # 2. Implementar tasks (uma por commit, conventional commits) | ||
| git commit -m "feat(aluno/dashboard): T01 remove fake KPIs" | ||
|
|
||
| # 3. Gates (todos devem passar) | ||
| npm run lint && npm run typecheck && npm test | ||
|
|
||
| # 4. PR para main (ou merge em feat/008-aluno-ui-premium) | ||
| gh pr create --base main --title "feat(aluno): fase N — <título>" | ||
|
|
||
| # 5. Aguardar CI + review + merge | ||
|
|
||
| # 6. Voltar para feat/008-aluno-ui-premium e rebase | ||
| git checkout feat/008-aluno-ui-premium | ||
| git rebase main | ||
| ``` | ||
|
|
||
| #### 8.3. Validação final | ||
|
|
||
| Após merge de todas as fases: | ||
|
|
||
| ```bash | ||
| # 1. E2E suite (deve continuar passando) | ||
| npm run e2e | ||
|
|
||
| # 2. Lighthouse mobile | ||
| npx lighthouse https://staging.example.com/aluno/dashboard --view | ||
|
|
||
| # 3. axe-core scan | ||
| npx axe https://staging.example.com/aluno/dashboard | ||
|
|
||
| # 4. Tag da iteração | ||
| git tag v0.9.1-premium-ui | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 9. Riscos e mitigação | ||
|
|
||
| | Risco | Probabilidade | Impacto | Mitigação | | ||
| | ---------------------------------------- | ------------- | ------- | ---------------------------------------------------------- | | ||
| | Regressão em E2E tests | média | médio | Rodar `npm run e2e` após cada fase | | ||
| | Quebra de design system (tokens globais) | baixa | alto | Fases 5+6 em branch isolado, validar visual antes de merge | | ||
| | Performance (motion excessivo) | baixa | médio | T24 força reduced-motion global como rede de segurança | | ||
| | Inconsistência entre fases | média | baixo | PRs pequenos por fase facilitam review | | ||
|
|
||
| --- | ||
|
|
||
| ## 10. Acceptance criteria | ||
|
|
||
| Esta PRD está DONE quando: | ||
|
|
||
| - [ ] Todas as 25 tasks mergeadas em main | ||
| - [ ] Lighthouse a11y ≥ 95 nas 4 rotas Aluno | ||
| - [ ] axe DevTools 0 violations | ||
| - [ ] Nenhum KPI hardcoded permanece em `src/app/aluno/` | ||
| - [ ] E2E suite 100% verde | ||
| - [ ] Screenshots mobile (375px) revisados: home, login, treinos, empty states | ||
| - [ ] `docs/CURRENT-STATE.md` atualizado refletindo a iteração | ||
|
|
||
| --- | ||
|
|
||
| ## 11. Referências | ||
|
|
||
| - Audit workflow: `wf_eaffd9ce-9c6` (synthesis falhou; plano derivado inline) | ||
| - DESIGN.md: `docs/...` (spec a ser atualizado em T23) | ||
| - Memory: `project_mobile_first_prds.md`, `project_prd3_plan_pending.md` |
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Custom agent: Enforce Strict Maintainability Standards
The trailing
.env*pattern at the end of.gitignoreoverrides the existing!.env.examplenegation earlier in the file. Because gitignore applies the last matching rule,.env*will match.env.exampleand cause it to be ignored again — silently undermining the explicit decision to keep.env.exampletracked. Consider either moving!.env.exampleafter.env*or replacing.env*with narrower patterns that don't accidentally catch.env.example.Prompt for AI agents