plan(C103/C104/C105): agenda mobile — form de criação usável, todo o dia, tags (planos de intenção)
This commit is contained in:
parent
3f7f0cc552
commit
fc8cecb427
3 changed files with 269 additions and 0 deletions
96
docs/plans/agenda-mobile-form-criacao-usavel.md
Normal file
96
docs/plans/agenda-mobile-form-criacao-usavel.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Agenda mobile: formulário de criação usável no celular (sheet do topo, rolável, salvar alcançável, popover dentro da tela, form sem labels)
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: 2026-08-09
|
||||
Issue: #504
|
||||
Priority: P1
|
||||
Model: composer-2.5
|
||||
Model-local: deepseek-v4-flash-high
|
||||
Impeccable: B — encaixe na superfície existente (bottom sheet + popover de data/hora da criação inline, C91/C97)
|
||||
Canvas UI: /home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-plans-plan-issue-13/canvases/plan-c103-ui-draft.canvas.tsx
|
||||
Appetite: ~0,5–1 dia eng; um outcome verificável — no celular o formulário de criação preenche até o fim e salva
|
||||
Responsável: —
|
||||
|
||||
## Intenção
|
||||
|
||||
No celular, o sheet de criação rápida (C91) corta o formulário embaixo: "Responsáveis" e o botão "Salvar" ficam fora da tela e **não há rolagem** — o coordenador/assessor de campo não consegue concluir a criação pelo telefone, que é a mesa do campo. Pior, o popover de data/hora (C97) estoura a tela e os seletores de hora/minuto aparecem espremidos. Queremos o formulário **preenchível de ponta a ponta no celular**: o sheet abre do topo (mais espaço), o conteúdo rola, "Salvar" sempre alcançável, o seletor de data/hora abre **como bottom sheet** no mobile (inteiro na tela, sem colisão de popover), e o form fica mais enxuto — sem labels nem margens, só a linha divisória entre os campos; os placeholders dão o contexto ("Adicionar título", "Adicionar responsáveis").
|
||||
|
||||
## Persona e fluxo
|
||||
|
||||
- **Persona / contexto:** coordenador ou assessor de campo, em pé, um polegar, sol/ruído; o celular é a ferramenta de trabalho.
|
||||
- **Job principal:** criar um compromisso no slot certo da agenda **pelo celular**, sem perder nenhum campo do caminho.
|
||||
- **Fluxo desejado:**
|
||||
1. Toca num slot vazio → o sheet abre **do topo**, preenchendo a altura útil da tela, com cabeçalho fixo ("Nova atividade" + data do slot).
|
||||
2. O formulário aparece sem labels — "Adicionar título", data/hora, "Município", "Local (opcional)", "Adicionar responsáveis".
|
||||
3. Rola o conteúdo livremente até o fim; "Salvar" fica fixo no rodapé do sheet, sempre na mão.
|
||||
4. Toca em Início/Término → no mobile, o seletor de data/hora abre como **bottom sheet** (calendário + hora/minuto inteiros na tela), por cima do sheet de criação.
|
||||
- **Anti-goals de produto:** não vira o formulário completo (tarefas, resultados, organizações continuam no detalhe); não muda a página de edição (`/atividades/[slug]/editar`) nem o formulário completo (`/nova`); não mexe no chrome do calendário (C101); não muda o desktop além do que o mesmo mecanismo de "caber na viewport" resolver (B181).
|
||||
|
||||
### Esboço de fluxo (B)
|
||||
|
||||
```text
|
||||
[toca no slot vazio] → [sheet do topo: "Nova atividade" + data fixos]
|
||||
→ "Adicionar título" | Início/Término (popover inteiro na tela) | Município | "Adicionar responsáveis"
|
||||
→ rolagem livre até o fim
|
||||
→ rodapé fixo: [Mais detalhes] [Salvar] → evento aparece no calendário
|
||||
```
|
||||
|
||||
## Objetivo e aceite
|
||||
|
||||
- No celular, tocar num slot abre o sheet de criação **do topo** (ou equivalente que maximize a área útil do formulário — ver questão em aberto), em vez do bottom sheet atual que corta o conteúdo.
|
||||
- O conteúdo do formulário **rola até o fim**: "Responsáveis" e "Salvar" alcançáveis em viewport pequeno (ex. 640×480) e com teclado aberto.
|
||||
- **"Salvar" sempre visível** no rodapé do sheet (recomendação) ou alcançável ao rolar — sem gesto oculto.
|
||||
- O formulário **não exibe labels visíveis**: os placeholders dão o contexto ("Adicionar título", "Adicionar responsáveis", "Município", "Local (opcional)"); campos obrigatórios continuam marcados (asterisco) e a acessibilidade é mantida (labels via `aria`/visualmente ocultos, erros anunciados).
|
||||
- Os campos do formulário ficam **empilhados sem margens/gaps**: apenas uma **linha divisória** entre eles (estilo lista — ex.: configurações do iOS), sem respiro nem card entre os inputs.
|
||||
- No celular, o seletor de **data/hora abre como bottom sheet** (drawer aninhado por cima do sheet de criação): calendário e seletores de hora/minuto ficam **inteiros na tela**, legíveis — sem colisão de popover. No **desktop, o popover continua** como hoje.
|
||||
- Sem regressão: desktop mantém o fluxo atual; criar não navega; salvar insere o evento no calendário; leader lockdown intacto.
|
||||
|
||||
## Dados (intenção)
|
||||
|
||||
- **Vou apresentar dados?** Não. `Dados: N/A` — affordance de escrita sobre a agenda; nenhuma métrica/série/mapa envolvida.
|
||||
- **Decisões desbloqueadas:** o usuário decide "criar o compromisso agora, pelo telefone, sem perder o rascunho".
|
||||
|
||||
## Direção no codebase (hipótese)
|
||||
|
||||
- **Áreas prováveis:**
|
||||
- `src/components/campaign/activity/ActivityInlineCreate.tsx` — o braço mobile (`Drawer`) hoje abre do fundo com conteúdo `overflow-hidden`; é aqui que a posição do sheet, a rolagem do form e o rodapé fixo de "Salvar" se resolvem.
|
||||
- `src/components/campaign/activity/ActivityDateTimeField.tsx` — no mobile, o disparo do campo abre um **bottom sheet** com o mesmo conteúdo (calendário + hora/minuto); no desktop, o popover atual continua.
|
||||
- `src/components/ui/Drawer.tsx` — primitiva de drawer (posição do topo / altura / scroll interno do conteúdo / drawer aninhado), se o ajuste não couber só no uso.
|
||||
- **Precedente a olhar:** B181 (#490 — clip do topo do overlay no desktop ≤720px; mecanismo irmão "cabe na viewport com scroll interno", mesmo padrão do `max-h` do C97), C91 (`agenda-criar-evento-inline.md` — desenho do sheet), C97 (popover de data/hora), drawer aninhado já suportado pela primitiva (`CalendarFeedDialog`).
|
||||
- **Risco de acoplamento:** o `Drawer` é primitiva compartilhada (`CalendarFeedDialog`, listas) — mudança de posicionamento/scroll deve ser scoped ao uso da criação inline ou ser backward-compatible; o popover é portado para o body, então o posicionamento precisa levar a viewport inteira em conta, não só o sheet.
|
||||
|
||||
## Dependências
|
||||
|
||||
- Nenhuma dura. Coordenação suave com **C101** (#497 — o plano dele exclui explicitamente o overlay de criação; nada de colisão) e **B181** (#490 — clip do popover **desktop**; com o seletor mobile virando sheet, as superfícies não se sobrepõem).
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
- Formulário completo `/campanha/atividades/nova` e página de edição `/campanha/atividades/[slug]/editar` (labels/placeholders/seletor ficam como estão).
|
||||
- Abrir evento existente em sheet de edição (continua indo ao detalhe).
|
||||
- "Todo o dia" → **C104**. Tags → **C105**.
|
||||
- Chrome do calendário mobile (header contextual, arrasto, filtro sticky) → **C101**.
|
||||
- Clip do topo do overlay/popover **desktop** em viewport baixa (≤720px) → **B181**.
|
||||
|
||||
## Rabbit holes de produto
|
||||
|
||||
- **"Sheet vira página."** Se alguém "só completar", o sheet vira o formulário grande. **Corte:** mesmo conteúdo do C91, só posição/altura/rolagem/rodapé.
|
||||
- **"Redesenhar todos os forms /campanha."** Labels/placeholders são decisão deste sheet. **Corte:** só a criação inline da agenda; o resto dos forms fica intacto.
|
||||
- **"Mexer no desktop junto."** **Corte:** o desktop fica como está — o seletor continua em popover e o form com labels; B181 segue na fila.
|
||||
|
||||
## Questões em aberto (produto)
|
||||
|
||||
- **Sheet do topo vs outras formas de maximizar o formulário?** **Opções:** A) sheet que desce do topo da tela (como pedido — "trazer até o topo") | B) bottom sheet em altura cheia com scroll | C) overlay de tela cheia sem swipe. **Recomendação: A** — é o pedido explícito, dá o máximo de espaço e mantém o gesto de fechar. _(assumido — validar)_
|
||||
- **"Salvar" fixo ou no fim do form?** **Opções:** A) rodapé fixo do sheet, sempre visível | B) fim do formulário (alcançável ao rolar). **Recomendação: A** — thumb-zone; o usuário nunca perde o botão. _(assumido — validar)_
|
||||
- **Placeholders puros ou micro-labels flutuantes?** **Opções:** A) placeholders puros (como pedido) | B) labels que sobem ao digitar. **Recomendação: A** — o form é curto e os obrigatórios continuam marcados. _(assumido — validar)_
|
||||
- **B181 (clip do topo do overlay desktop ≤720px): absorver ou manter?** **Opções:** A) manter B181 na fila — o C103 mexe no seletor mobile (bottom sheet) e não toca o posicionamento do popover desktop; B181 segue seu próprio caminho | B) fundir B181 no C103. **Recomendação: A** — com o seletor mobile virando sheet, as superfícies deixam de se sobrepor; B181 permanece o ajuste do popover desktop. _(decidido no gate)_
|
||||
- **Seletor de data/hora no mobile: popover ajustado ou bottom sheet?** **Opções:** A) popover com colisão/limite de viewport | B) **bottom sheet** com calendário + hora/minuto inteiros na tela (padrão nativo; evita controlar colisão dentro do sheet de criação). **Recomendação: B** — pedido do usuário no gate; mais simples de garantir visualização total. _(decidido no gate)_
|
||||
- **Edição de evento existente na agenda mobile?** **Opções:** A) continua indo à página de detalhe/edição (atual) | B) abre o mesmo sheet pré-preenchido para editar. **Recomendação: A** — fora deste lote; se a mesa pedir, vira item futuro. _(assumido — validar)_
|
||||
|
||||
## Referências
|
||||
|
||||
- GitHub Issue: — (a registrar)
|
||||
- Canvas UI (gate): `/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-plans-plan-issue-13/canvases/plan-c103-ui-draft.canvas.tsx`
|
||||
- `src/components/campaign/activity/ActivityInlineCreate.tsx` — braço mobile do sheet de criação (C91)
|
||||
- `src/components/campaign/activity/ActivityDateTimeField.tsx` — popover de data/hora (C97)
|
||||
- `src/components/ui/Drawer.tsx` / `src/components/ui/Popover.tsx` — primitivas
|
||||
- Precedentes: `docs/plans/agenda-criar-evento-inline.md` (C91), `docs/plans/c97-agenda-popover-seletor-data-hora.md`, Issue #490 (B181)
|
||||
88
docs/plans/agenda-tags-eventos.md
Normal file
88
docs/plans/agenda-tags-eventos.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# Agenda: tags para agrupar e filtrar compromissos
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: 2026-08-09
|
||||
Issue: #506
|
||||
Priority: P2
|
||||
Model: composer-2.5
|
||||
Model-local: deepseek-v4-flash-high
|
||||
Impeccable: B — encaixe na superfície existente (sheet de criação + strip de filtros + evento do calendário da agenda)
|
||||
Canvas UI: /home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-plans-plan-issue-13/canvases/plan-c105-ui-draft.canvas.tsx
|
||||
Appetite: ~1 dia eng; um outcome verificável — cada equipe agrupa os compromissos do jeito dela e a agenda filtra por tag
|
||||
Responsável: —
|
||||
|
||||
## Intenção
|
||||
|
||||
Os compromissos da agenda são heterogêneos — caminhada, panfletagem, reunião, comício, gravação — e hoje só dá para agrupar por município e pelos filtros existentes. Queremos **tags livres** no compromisso (chips digitados pelo usuário, com sugestões das tags já usadas) e um **filtro por tag na agenda dentro da filter omnibox existente** (C94), para cada equipe organizar do jeito que achar melhor: o coordenador prepara o dia por tipo de atividade, o assessor filtra "só panfletagem" no território dele.
|
||||
|
||||
## Persona e fluxo
|
||||
|
||||
- **Persona / contexto:** coordenador e assessores de campo; cada um tem o próprio vocabulário de trabalho ("giro", "panfletagem", "reunião de rua").
|
||||
- **Job principal:** agrupar os compromissos do próprio jeito e **ver a agenda filtrada por esse grupo** com um toque.
|
||||
- **Fluxo desejado:**
|
||||
1. Cria um compromisso no sheet → digita tags no campo "Adicionar tags" (chips que entram ao teclar; sugestões das tags já usadas na campanha aparecem).
|
||||
2. Salva → o evento no calendário mostra um rótulo leve de tag.
|
||||
3. Na agenda, a **filter omnibox** (C94) ganha a tag como opção: escolheu a tag dentro da omnibox, ela vira chip no próprio campo da omnibox, combinando com os filtros atuais (município etc.) → a agenda mostra só os compromissos com aquela tag.
|
||||
- **Anti-goals de produto:** tag **não** é pessoa (`Contact`) nem taxonomia editorial (coleção `Tag` dos posts é outra coisa — nada de relação com ela); **não** é lista curada obrigatória com admin; **não** vira o formulário completo (tarefas/organizações continuam no detalhe); liderança não acessa a agenda (inalterado).
|
||||
|
||||
### Esboço de fluxo (B)
|
||||
|
||||
```text
|
||||
[sheet de criação] → "Adicionar tags" → chips: caminhada · panfletagem
|
||||
→ salvar → evento com rótulo de tag no calendário
|
||||
[agenda] → filter omnibox → escolhe a tag (ex.: caminhada) → chip na omnibox, combina com o resto
|
||||
```
|
||||
|
||||
## Objetivo e aceite
|
||||
|
||||
- O sheet de criação ganha um campo de **tags** (chips adicionáveis/removíveis; texto livre; sugestões das tags já usadas na campanha; sem duplicatas).
|
||||
- As tags do compromisso aparecem como **rótulo leve** no evento do calendário (ver questão em aberto).
|
||||
- A agenda ganha **filtro por tag dentro da filter omnibox existente** (C94): a tag aparece como opção da omnibox; escolhida, vira chip no próprio campo da omnibox (mesmo padrão dos chips atuais de município etc.), com multisseleção, **combinando** com os demais filtros e persistindo no estado/URL como eles.
|
||||
- Limites de produto: poucas tags por compromisso (recomendação: até 3) e texto curto (recomendação: ~24 caracteres) — ver questão em aberto.
|
||||
- Sem regressão: criar com horário, remanejo por arrasto (C15), filtros atuais (C94) e "Mais detalhes" (C91) intactos.
|
||||
|
||||
## Dados (intenção)
|
||||
|
||||
- **Vou apresentar dados?** Não. `Dados: N/A` — filtro é estado de tela/URL, não apresentação de dados.
|
||||
|
||||
## Direção no codebase (hipótese)
|
||||
|
||||
- **Áreas prováveis:**
|
||||
- `src/components/campaign/activity/ActivityInlineCreate.tsx` — campo de tags no sheet (chips; há precedente de chips em inputs na campanha).
|
||||
- `src/components/campaign/activity/ActivityAgendaFilters.tsx` (filter omnibox C94) — a tag entra como **opção da omnibox** (chips no campo, mesmo padrão dos filtros atuais); e `src/utilities/activityUi.ts` (estado/URL dos filtros da agenda).
|
||||
- `src/components/campaign/activity/ActivityAgenda.tsx` (`toEventInput`) — rótulo de tag no evento.
|
||||
- Fluxo completo de persistência: `src/app/(campaign)/campanha/actions/activity.ts`, `src/lib/schemas/activity.ts`, e o campo novo viaja no prefill do "Mais detalhes" (`buildActivityCreateHref`).
|
||||
- **Precedente a olhar:** C94 (combobox de filtro da agenda), C91 (`agenda-criar-evento-inline.md` — sheet e "Mais detalhes"), chips de filtro em outras listas (`filtros-municipios-dobradinha-lideranca`), a distinção taxonomia `Tag` (posts) vs dados de campanha.
|
||||
- **Risco de acoplamento:** a omnibox é chassis compartilhado das listas /campanha — a tag entra como **dimensão a mais da omnibox da agenda**, sem mudar o combobox das demais listas; o estado de filtro novo segue o padrão de URL existente para o "Mais detalhes"/compartilhamento continuarem coerentes.
|
||||
|
||||
## Dependências
|
||||
|
||||
- Suave: **C103** (mesma superfície — sheet da criação; prefira C103 primeiro). **C104** independente.
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
- Taxonomia administrativa (lista de tags fixa, cores por tag, admin) → se pedirem, item futuro.
|
||||
- Filtro de tags nas demais listas /campanha (só a agenda).
|
||||
- Tags como critério do feed iCal/import (C92–C96 não mudam).
|
||||
- Multi-dia, recorrência.
|
||||
|
||||
## Rabbit holes de produto
|
||||
|
||||
- **"Tags viram a taxonomia editorial (Tag dos posts)."** A coleção `Tag` do site é outra coisa (categorias de notícia + `hidden`). **Corte:** tags livres da agenda, sem relação com `Tag` nem admin.
|
||||
- **"Sugestões viram lista obrigatória."** **Corte:** texto livre; as sugestões são só autocomplete das já usadas.
|
||||
- **"Filtro de tag vira busca exclusiva."** **Corte:** a omnibox ganha a tag como **uma** dimensão a mais — município, deputado presente, busca de texto e os demais filtros continuam como estão; a tag é opção dentro da mesma omnibox, não uma nova barra.
|
||||
- **"Tag precisa de identidade visual."** **Corte:** rótulo neutro e discreto; o filtro ativo já é o destaque.
|
||||
|
||||
## Questões em aberto (produto)
|
||||
|
||||
- **Texto livre ou lista curada?** **Opções:** A) livre com sugestões das tags já usadas | B) lista fixa definida pela equipe | C) híbrido (livre + mais usadas em destaque). **Recomendação: A** — o pedido é "agrupar como acharem melhor"; a curadoria nasce naturalmente pelas sugestões. _(assumido — validar)_
|
||||
- **Onde o filtro de tag vive?** **Opções:** A) chips separados no strip | B) dentro da filter omnibox existente (C94), como opção + chip no campo | C) os dois. **Recomendação: B** — pedido explícito do usuário no gate: o filtro é parte da omnibox, não chips separados. _(decidido no gate)_
|
||||
- **Tags aparecem no evento do calendário?** **Opções:** A) rótulo pequeno no card do evento | B) só na criação e nos filtros. **Recomendação: A** — reconhecimento visual leve; se poluir em visões densas (mês), cai para B. _(assumido — validar)_
|
||||
- **Limites:** **Opções:** A) até 3 tags por compromisso, ~24 caracteres | B) sem limites. **Recomendação: A** — limite leve evita card poluído; ajustável depois. _(assumido — validar)_
|
||||
|
||||
## Referências
|
||||
|
||||
- GitHub Issue: — (a registrar)
|
||||
- Canvas UI (gate): `/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-plans-plan-issue-13/canvases/plan-c105-ui-draft.canvas.tsx`
|
||||
- `src/components/campaign/activity/ActivityInlineCreate.tsx`, `ActivityAgendaFilters.tsx`, `ActivityAgenda.tsx` (`toEventInput`)
|
||||
- Precedentes: `docs/plans/c94-agenda-combobox-header-acoes-rapidas.md`, `docs/plans/agenda-criar-evento-inline.md` (C91)
|
||||
85
docs/plans/agenda-toggle-todo-o-dia.md
Normal file
85
docs/plans/agenda-toggle-todo-o-dia.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Agenda: compromisso "Todo o dia" na criação rápida
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: 2026-08-09
|
||||
Issue: #505
|
||||
Priority: P2
|
||||
Model: composer-2.5
|
||||
Model-local: deepseek-v4-flash-high
|
||||
Impeccable: B — encaixe na superfície existente (sheet de criação inline da agenda, C91)
|
||||
Canvas UI: /home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-plans-plan-issue-13/canvases/plan-c104-ui-draft.canvas.tsx
|
||||
Appetite: ~0,5 dia eng; um outcome verificável — um compromisso de dia inteiro se cria no sheet sem inventar horário
|
||||
Responsável: —
|
||||
|
||||
## Intenção
|
||||
|
||||
Muitos compromissos da agenda duram o dia inteiro — congresso, viagem, evento de município, dia de gravação — e alguns duram **vários dias inteiros**. Hoje o sheet de criação só aceita horário e o usuário inventa "09:00–18:00", o que polui a agenda e engana quem lê. Queremos um toggle **"Todo o dia"** no formulário (entre o título e a data de início): ligou, os horários somem e ficam **só as datas** — início **e** término, que pode ser outro dia (vários dias inteiros) — e o compromisso aparece no calendário como **faixa de dia inteiro** — igual ao Google Calendar que a mesa já usa.
|
||||
|
||||
## Persona e fluxo
|
||||
|
||||
- **Persona / contexto:** coordenador ou assessor de campo planejando a semana; compromissos de dia cheio são comuns (eventos fora da base, viagens de vários dias).
|
||||
- **Job principal:** registrar um compromisso que ocupa um ou mais dias inteiros sem precisar inventar um intervalo de horário.
|
||||
- **Fluxo desejado:**
|
||||
1. Toca num slot vazio → sheet de criação abre.
|
||||
2. Alterna **"Todo o dia"** (entre o título e a data de início) → os seletores de horário somem; **início e término viram só data**; o término pode apontar para outro dia (vários dias inteiros).
|
||||
3. Preenche o resto (título, município…), salva → o compromisso aparece no calendário como **faixa de dia inteiro** (topo da visão de dia/semana).
|
||||
4. "Mais detalhes" leva ao formulário completo **preservando** a escolha todo-dia.
|
||||
- **Anti-goals de produto:** não é recorrência nem semântica de timezone (granularidade de dia); não vira campo obrigatório nem afeta quem cria com horário; liderança não acessa a agenda (inalterado).
|
||||
|
||||
### Esboço de fluxo (B)
|
||||
|
||||
```text
|
||||
[toca no slot] → [sheet] → título → alterna "Todo o dia"
|
||||
→ Início vira só data · Término continua, como data (pode ser outro dia)
|
||||
→ salvar → faixa de dia inteiro no calendário (sem horário)
|
||||
```
|
||||
|
||||
## Objetivo e aceite
|
||||
|
||||
- O sheet de criação ganha um toggle **"Todo o dia"**, posicionado **entre o título e a data de início**.
|
||||
- Com o toggle ligado: o campo de início mostra **apenas a data** (sem hora/minuto) e o campo de **término continua visível, também só data** — podendo ser **outro dia** (compromisso de vários dias inteiros).
|
||||
- O compromisso salvo com "Todo o dia" aparece no calendário como **evento de dia inteiro** (faixa no topo da visão de dia/semana, sem horário impresso), ocupando todos os dias do intervalo.
|
||||
- "Mais detalhes" leva ao formulário completo com a escolha todo-dia **preservada** (e, se o form completo tiver o toggle — ver questão em aberto —, editar depois não quebra o evento).
|
||||
- Criar com horário continua funcionando exatamente como hoje.
|
||||
|
||||
## Dados (intenção)
|
||||
|
||||
- **Vou apresentar dados?** Não. `Dados: N/A` — o toggle é estado do formulário; a forma de guardar (flag vs horários de borda) fica para o plano de implementação.
|
||||
|
||||
## Direção no codebase (hipótese)
|
||||
|
||||
- **Áreas prováveis:**
|
||||
- `src/components/campaign/activity/ActivityInlineCreate.tsx` — toggle + campos condicionais (data-only quando ligado).
|
||||
- `src/components/campaign/activity/ActivityAgenda.tsx` (`toEventInput`, hoje fixa `allDay: false`) — o evento todo-dia precisa ser renderizado como faixa de dia inteiro.
|
||||
- Fluxo completo: `src/app/(campaign)/campanha/actions/activity.ts` (criação/edição) e `src/components/campaign/activity/ActivityForm.tsx` (se o toggle entrar no form completo), `src/lib/schemas/activity.ts` (validação).
|
||||
- **Precedente a olhar:** `ActivityDateTimeField.tsx` (C97 — controle de data/hora; a data-only já é meio caminho), `agenda-criar-evento-inline.md` (C91), FullCalendar `allDay` (C15).
|
||||
- **Risco de acoplamento:** a representação do todo-dia (flag vs 00:00–23:59) afeta o que o "Mais detalhes" e a edição veem — a escolha é do plano de implementação, mas o **aceite de produto** (preserva a escolha, edição não quebra) vale para qualquer caminho.
|
||||
|
||||
## Dependências
|
||||
|
||||
- Suave: **C103** (mesma superfície — sheet da criação; prefira C103 primeiro para o sheet estar usável no celular).
|
||||
|
||||
## Fora de escopo
|
||||
|
||||
- Recorrência de compromissos.
|
||||
- Troca de modo no calendário (o seletor de vista C95 não muda).
|
||||
- Tags/filtros → **C105**.
|
||||
|
||||
## Rabbit holes de produto
|
||||
|
||||
- **"Todo o dia vira semântica de timezone."** Se alguém "só completar": meia-noite, fusos, atrito com `endAt`. **Corte neste item:** granularidade de dia — horário nunca aparece com o toggle ligado; multi-dia é só o término em outra data.
|
||||
- **"Toggle em todos os lugares de uma vez."** **Corte:** começa no sheet (pedido); o form completo entra só se a edição de eventos todo-dia ficar quebrada sem ele (ver questão em aberto).
|
||||
- **"Todo-dia precisa de cor/ícone especial."** **Corte:** o calendário já diferencia pela posição (faixa no topo); sem identidade visual nova.
|
||||
|
||||
## Questões em aberto (produto)
|
||||
|
||||
- **O toggle vive também no formulário completo/edição?** **Opções:** A) só no sheet; editar um evento todo-dia mostra horário "00:00" (regressão de leitura) | B) o mesmo toggle no form completo (`/nova` e `/editar`), reusando o mecanismo do sheet. **Recomendação: B** — é o mesmo controle; evita evento todo-dia "quebrado" ao editar. _(assumido — validar)_
|
||||
- **Prefill do slot com "Todo o dia" ligado?** **Opções:** A) o toggle nasce desligado e o usuário liga | B) slots de dia cheio (mês) abrem com ele ligado. **Recomendação: A** — comportamento previsível; o prefill do horário continua como está. _(assumido — validar)_
|
||||
- **Término multi-dia, como funciona na prática?** **Opções:** A) término em data posterior = compromisso de vários dias inteiros (faixa contínua no calendário) | B) término sempre igual ao início (um dia só). **Recomendação: A** — pedido explícito do usuário no gate (pode ser mais de um dia inteiro); o término continua sendo só data. _(decidido no gate)_
|
||||
|
||||
## Referências
|
||||
|
||||
- GitHub Issue: — (a registrar)
|
||||
- Canvas UI (gate): `/home/fsolla/.cursor/projects/home-fsolla-cursor-worktrees-teqo-plans-plan-issue-13/canvases/plan-c104-ui-draft.canvas.tsx`
|
||||
- `src/components/campaign/activity/ActivityInlineCreate.tsx`, `ActivityAgenda.tsx` (`toEventInput`), `ActivityDateTimeField.tsx` (C97)
|
||||
- Precedentes: `docs/plans/agenda-criar-evento-inline.md` (C91), `docs/plans/fullcalendar-agenda-campanha.md` (C15)
|
||||
Loading…
Reference in a new issue