diff --git a/docs/plans/agenda-mobile-form-criacao-usavel.md b/docs/plans/agenda-mobile-form-criacao-usavel.md new file mode 100644 index 00000000..c26f13a0 --- /dev/null +++ b/docs/plans/agenda-mobile-form-criacao-usavel.md @@ -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) diff --git a/docs/plans/agenda-tags-eventos.md b/docs/plans/agenda-tags-eventos.md new file mode 100644 index 00000000..7573c934 --- /dev/null +++ b/docs/plans/agenda-tags-eventos.md @@ -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) diff --git a/docs/plans/agenda-toggle-todo-o-dia.md b/docs/plans/agenda-toggle-todo-o-dia.md new file mode 100644 index 00000000..7d634751 --- /dev/null +++ b/docs/plans/agenda-toggle-todo-o-dia.md @@ -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)