diff --git a/docs/plans/barra-navegacao-inferior-mobile.md b/docs/plans/barra-navegacao-inferior-mobile.md new file mode 100644 index 00000000..7bd5d8f3 --- /dev/null +++ b/docs/plans/barra-navegacao-inferior-mobile.md @@ -0,0 +1,107 @@ +# B164 — Barra de navegação inferior no mobile (+ página Mais) + +Status: blocked (plano ainda não em main) +Atualizado em: 2026-08-06 +Issue: #400 +Priority: P1 +Model: cursor-grok-4.5-medium +Model-local: deepseek-v4-high +Impeccable: C — chrome novo no shell mobile + página hub “Mais” +Canvas UI: `/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-41rz/canvases/plan-b164-ui-draft.canvas.tsx` +Appetite: ~1–1,5 dia eng; um outcome verificável — staff no celular troca entre os 4 destinos primários e o overflow em um toque +Responsável: — + +## Intenção + +No telefone, a mesa precisa **trocar de domínio com o polegar** (Início → Municípios → o que está acontecendo → agenda → o resto) sem abrir o Sheet da sidebar a cada salto. Em 2026-07-29 o produto removeu a bottom bar (**B73**) a favor de intenção no Início + sidebar; na prática o campo ainda pede atalhos de domínio. Este item **reintroduz** a barra inferior no mobile com uma IA nova: quatro destinos de trabalho + **Mais** (página com o restante da navegação). + +O destino **Atualizações** é o feed da campanha (cada atualização = fio de discussão) — superfície de produto em **C89**; aqui só o slot de navegação + rota âncora. + +## Persona e fluxo + +- **Persona / contexto:** coordenador / assessor / candidato no celular (campo ou deslocamento); uma mão; PWA; pressão de tempo entre Zap e visita. +- **Job principal:** ir aos destinos frequentes em um toque; achar Lideranças / Assessores / Dobradinhas / etc. sem caçar no Sheet. +- **Fluxo desejado:** + 1. Em qualquer rota `(app)` no viewport mobile, vê barra fixa: **Início · Municípios · Atualizações · Agenda · Mais**. + 2. Toca um dos quatro → navega para aquele destino (estado ativo visível). + 3. Toca **Mais** → página com a lista dos destinos restantes (Lideranças, Organizações, Dobradinhas, Demandas, Apoiadores, Assessores, Quadro, Territórios, Conceitos, Perfil) + **Sair** no rodapé — filtrados por papel. + 4. Desktop/tablet: sidebar continua como hoje; barra inferior **não** compete lá. + 5. `SidebarTrigger` no header mobile **permanece** (escape hatch). +- **Anti-goals de produto:** segunda barra no desktop; spreadsheet de atalhos; reinventar catálogo de ações rápidas (FAB permanece); liberar liderança dos destinos staff; redesenhar o Início ou o FAB neste item; implementar o feed/threads neste item (→ **C89**). + +### Esboço de fluxo (C) + +```text +[qualquer página mobile staff] + → barra: Início | Municípios | Atualizações | Agenda | Mais + → [4 primários] → destino + → [Mais] → página overflow → destino secundário / Sair +``` + +## Objetivo e aceite + +- Viewport **< `md`**, papéis staff (`coordinator` / `advisor` / `candidate`): barra inferior fixa com exatamente esses cinco rótulos (copy pt-BR), na ordem pedida. +- Destinos primários (produto) — **confirmados no gate:** + - **Início** → `/campanha` + - **Municípios** → lista de municípios + - **Atualizações** → rota do feed da campanha (intenção em **C89**; até C89 landar, a rota pode existir como âncora/empty honesto, sem twin de C88) + - **Agenda** → rótulo Agenda; href da vertical de atividades até **C15**, depois cutover para `/campanha/agenda` + - **Mais** → página overflow (restante da nav + Conceitos + Perfil + Sair) +- Página **Mais**: lista clara dos destinos que **não** estão nos quatro primários; mesmo filtro de papel da nav atual (Assessores só unrestricted; Apoiadores só quem acessa a área; liderança não vê menu staff). +- Item ativo na barra (e na página Mais) reflete a rota corrente; safe-area inferior respeitada; conteúdo não fica escondido atrás da barra. +- **FAB** continua onde já existe; fica acima da barra / com folga. +- **Leader lockdown** intacto: liderança **não** ganha a barra de cinco destinos staff. +- Desktop/tablet: sem regressão da sidebar; sem barra inferior; `SidebarTrigger` mobile mantido. +- Sucessor explícito de **B73** — não editar o plano entregue. + +## Dados (intenção) + +- **Vou apresentar dados?** Não neste item — chrome de navegação. O feed (C89) é a superfície de dados/discussão. +- **Decisões desbloqueadas:** “para onde vou agora?” (domínio). +- **Forma:** adiada. + +## Direção no codebase (hipótese) + +- **Áreas prováveis:** shell `(app)` (layout, top bar mobile, padding do scroll), `src/components/campaign/shell/` (nav + bottom bar), rota overflow Mais, âncora de rota Atualizações; coexistência com FAB. +- **Precedente a olhar:** [remover-bottom-nav-mobile.md](remover-bottom-nav-mobile.md) (**B73**); `nav.ts`; [fab-acoes-rapidas-substituir-drawer.md](fab-acoes-rapidas-substituir-drawer.md); C14/C15; **C89** (feed); C87/C88 (modelo + deliberação). +- **Risco de acoplamento:** leader lockdown; filtros de papel; thumb-zone / FAB; não inventar segundo inventário de destinos fora da fonte da sidebar. + +## Dependências + +- Nenhuma dura para a barra + página Mais. +- Soft: **C15** / **C14** — cutover do href Agenda. +- Soft: **C89** — conteúdo rico do slot Atualizações (feed + threads). +- Soft: **C87** / **C88** — via C89 (modelo unificado + deliberação no fio). + +## Fora de escopo + +- Feed da campanha, interação e threads por atualização → **C89** (consome **C87** / **C88**). +- Remodel de registro / deliberação → **C87** / **C88**. +- FullCalendar / sync Google → **C15** / **C16**. +- Redesign do Início, FAB ou catálogo de ações. +- Bottom nav no desktop/tablet; esconder `SidebarTrigger` no mobile. +- Editar o plano entregue do B73. + +## Rabbit holes de produto + +- **"Já que voltou a barra, implementa o feed no mesmo PR."** Dois jobs. **Corte:** C89. +- **"Já que voltou a barra, mata o FAB / o Sheet."** Jobs diferentes. **Corte:** FAB e sidebar desktop ficam; trigger mobile fica. +- **"Coloca Quadro / Lideranças na barra primária."** **Corte:** primários fixos; resto em Mais. +- **"Liderança também ganha os cinco."** **Corte:** staff only. + +## Questões em aberto (produto) + +- Nenhuma pendente do gate anterior — respostas do humano (2026-08-06): + 1. Atualizações = feed da campanha com discussão; cada update = thread → fatiado em **C89**. + 2. Agenda = label Agenda; atividades até C15. + 3. Mais = restante da nav + Conceitos + Perfil + Sair. + 4. Manter `SidebarTrigger` no mobile. + +## Referências + +- GitHub Issue: [#400](https://github.com/fsolla/teqo/issues/400) +- Canvas UI (gate): [`plan-b164-ui-draft.canvas.tsx`](/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-41rz/canvases/plan-b164-ui-draft.canvas.tsx) +- Irmão: [feed-atualizacoes-campanha-threads.md](feed-atualizacoes-campanha-threads.md) (**C89**) +- Sucessor de B73 / [#14](https://github.com/fsolla/teqo/issues/14) — [remover-bottom-nav-mobile.md](remover-bottom-nav-mobile.md) +- Soft: C14 [#389](https://github.com/fsolla/teqo/issues/389), C15 [#390](https://github.com/fsolla/teqo/issues/390); C87 [#396](https://github.com/fsolla/teqo/issues/396), C88 [#397](https://github.com/fsolla/teqo/issues/397) +- `src/components/campaign/shell/nav.ts`, layout `(app)`, FAB de ações rápidas diff --git a/docs/plans/feed-atualizacoes-campanha-threads.md b/docs/plans/feed-atualizacoes-campanha-threads.md new file mode 100644 index 00000000..d08e04a6 --- /dev/null +++ b/docs/plans/feed-atualizacoes-campanha-threads.md @@ -0,0 +1,97 @@ +# C89 — Feed da campanha de atualizações (cada update = thread) + +Status: blocked (plano ainda não em main) +Atualizado em: 2026-08-06 +Issue: #401 +Priority: P1 +Model: cursor-grok-4.5-medium +Model-local: deepseek-v4-high +Impeccable: D — superfície nova: feed campanha-wide + interação por fio +Canvas UI: `/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-41rz/canvases/plan-c89-ui-draft.canvas.tsx` +Appetite: ~1,5–2 dias eng; um outcome verificável — staff acompanha e discute o que aconteceu na carteira num só lugar +Responsável: — + +## Intenção + +A mesa precisa de um **feed da campanha** — não só o histórico dentro de um município — para ver o que está acontecendo, comentar e deliberar. Cada **atualização** vira um **fio (thread)**: o fato registrado é o post; a conversa (e, com C88, responsável / resolvido) vive ali. O slot **Atualizações** da barra mobile (**B164**) aponta para esta superfície; desktop também a alcança pela nav. + +## Persona e fluxo + +- **Persona / contexto:** coordenador varrendo a carteira no celular ou na mesa; assessor no recorte dos municípios que administra; pressão entre campo e WhatsApp. +- **Job principal:** ver o que aconteceu recentemente, entrar no fio de uma atualização, participar da discussão (e fechar quando couber). +- **Fluxo desejado:** + 1. Abre **Atualizações** (barra mobile ou nav) → feed cronológico das atualizações da **carteira do ator** (assessor = só seus municípios; unrestricted = amplo). + 2. Cada card = uma atualização (texto, polaridade/urgente quando C87 existir, município, idade). + 3. Toca o card → o update abre como **thread**: corpo imutável do fato + comentários em sequência (+ responsável / resolvido quando **C88** estiver disponível). + 4. Comenta / atribui / marca resolvido conforme o poder do papel (regras de C88); volta ao feed. +- **Anti-goals de produto:** segundo tracker estilo Jira; chat em tempo real; feed público / liderança; misturar Demandas/Atividades; spreadsheet de KPIs; twin do modelo de atualização fora de C87/C88. + +### Esboço de fluxo (D) + +```text +[Atualizações] + → feed (carteira) + → toca update + → thread: fato + comentários (+ responsável / resolvido) + → volta ao feed +``` + +## Objetivo e aceite + +- Existe destino de produto **Atualizações** (rota de feed) usável por staff no escopo da carteira. +- Feed lista atualizações recentes com identidade do município e sinal de estado do fio (ex.: aberta / resolvida — quando C88 existir). +- Abrir um item mostra a atualização como **thread** interativa (comentar no fio); o corpo do fato permanece o registro original (imutável na intenção — alinhado a C88). +- Deliberação (responsável, resolvido, reabrir) **reusa** a intenção de **C88** — não inventa um segundo protocolo de ticket neste item. +- Leader lockdown: liderança **não** vê o feed nem os fios staff. +- Slot da barra **B164** e entrada de nav apontam para este destino (quando ambos existirem). + +## Dados (intenção) + +- **Vou apresentar dados?** Sim, superfície neste item (feed operacional, não KPI estadual). +- **Decisões desbloqueadas:** + - Coordenação/assessor: “o que aconteceu na carteira desde ontem?” + - No fio: “o que falta / quem resolve / podemos fechar?” (com C88) +- **Forma:** adiada — restrição: leitura relativa à carteira do ator; sem % estadual absoluto. + +## Direção no codebase (hipótese) + +- **Áreas prováveis:** rota `/campanha/atualizacoes` (ou equivalente), componentes de feed/thread no domínio de atualização de município, nav (`nav.ts` + slot B164), loaders no escopo do ator; actions de comentário/deliberação alinhadas a C88. +- **Precedente a olhar:** feed de atualizações no detalhe do município; C87 / C88; notificações `municipality_update`; B164. +- **Risco de acoplamento:** access por município; não criar pessoa fora de `campaignUser`/`Contact`; serialização com migrations de C87/C88. + +## Dependências + +- **Dura:** **C87** (modelo unificado de atualização) — o feed consome esse registro. +- **Dura:** **C88** (fio / responsável / resolvido) — a interação completa do thread; sem C88 o feed ainda pode listar e abrir o fato, mas deliberação fica incompleta — preferir shipar C89 **depois** de C88 ou degradar honestamente (só leitura + “comentários em breve”) se o gate pedir paralelismo com B164. +- Soft: **B164** (slot na barra); C15 irrelevante. + +## Fora de escopo + +- Chrome da barra inferior / página Mais → **B164**. +- Remodel do formulário de registro (polaridade / urgente) → **C87**. +- Definir de novo as regras de quem atribui/resolve → já em **C88** (não reabrir aqui). +- Mentions @, anexos rich, reações, SLA, kanban. +- Participação de liderança/apoiador. +- Sync externo / WhatsApp. + +## Rabbit holes de produto + +- **"Feed + barra no mesmo item."** Estoura appetite e mistura chrome com domínio. **Corte:** B164 vs C89. +- **"Vira rede social da campanha."** Curtidas, stories. **Corte:** fato + fio de trabalho. +- **"Filtros infinitos / analytics no feed."** **Corte:** cronológico da carteira; filtros só se couberem no appetite (município / abertas) sem virar BI. +- **"Comentário edita o fato."** **Corte:** corpo imutável; fio à parte (C88). + +## Questões em aberto (produto) + +- Nenhuma pendente — gate 2026-08-06 confirmou o lote com as recomendações: + 1. **Ordem:** C87 → C88 → C89 (feed completo com thread); B164 pode âncora/empty antes. + 2. **Desktop:** item “Atualizações” também na nav staff (mesmo destino). + 3. **Criar no feed:** não nesta fatia — só caminhos existentes (município / wizard). + +## Referências + +- GitHub Issue: [#401](https://github.com/fsolla/teqo/issues/401) +- Canvas UI (gate): [`plan-c89-ui-draft.canvas.tsx`](/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-41rz/canvases/plan-c89-ui-draft.canvas.tsx) +- Irmão chrome: [barra-navegacao-inferior-mobile.md](barra-navegacao-inferior-mobile.md) (**B164**) +- Depende: C87 [#396](https://github.com/fsolla/teqo/issues/396), C88 [#397](https://github.com/fsolla/teqo/issues/397) +- Planos: [atualizacao-unificada-polaridade-urgente.md](atualizacao-unificada-polaridade-urgente.md), [deliberacao-atualizacao-responsavel-thread.md](deliberacao-atualizacao-responsavel-thread.md)