Calendário de Pagamentos
Tela principal do app e rosto do produto no dia a dia do cliente. Apresenta os pagamentos do mês em um calendário, com os guias empilhados dentro da célula do dia de vencimento. Ao clicar num dia, um modal lista os guias daquele dia; ao selecionar um guia, o modal fecha e o painel da direita exibe os detalhes (PDF, código de barras, status). Esta seção identifica cinco pontos de evolução - dois críticos, dois de alto impacto e uma proposta estrutural (drawer) que resolve os dois principais.
Quando um dia concentra três ou mais guias, a célula do calendário limita a altura e os itens adicionais ficam truncados na borda inferior, sem nenhum indicador de que há mais. O usuário não tem sinal visual de pagamentos além dos que aparecem.
Impacto: risco real de perder vencimentos - especialmente em dias de múltiplos tributos (fechamento mensal com FGTS, DAS e DARF, por exemplo).
Limitar a 2 guias visíveis por célula e exibir um chip contador para o restante.
Dentro de cada célula do calendário, renderizar no máximo 2 cards de guia. Se houver mais, mostrar abaixo um chip no padrão + N guias que, ao ser clicado, abre o drawer do dia (ver UX-M-003) com a lista completa. O chip deve ter cor neutra e aria-label descritivo para leitores de tela.
Ao clicar num dia do calendário, abre um modal com a lista de guias. Selecionar um guia fecha o modal e atualiza o painel da direita com as informações daquela guia - comportamento funcional correto. O problema aparece quando o usuário volta ao calendário, reabre o modal no mesmo dia e seleciona um segundo guia: a coluna da direita é atualizada, mas como todas as guias compartilham a mesma estrutura visual (nome do arquivo, código de barras, status), a troca é praticamente indistinguível a olho nu. Nomes de arquivo parecidos (guia-darf-03-2026.pdf vs guia-das-03-2026.pdf) reforçam a ambiguidade.
Impacto: o usuário perde a referência de qual guia está ativa no painel. Risco alto de copiar o código de barras errado, baixar o PDF errado ou marcar o status na guia errada.
A correção definitiva é estrutural e está em UX-M-003 (drawer).
Como mitigação imediata enquanto o drawer não é implementado, dar identidade visual explícita ao guia ativo no painel direito: exibir no topo um cabeçalho destacado com o tipo do tributo (FGTS, DAS, DARF) em cor e ícone próprios, e uma barra de cor superior que indique o status. Assim, mesmo que a estrutura dos campos se repita, o usuário reconhece imediatamente qual guia está vendo.
Substituir o modal centralizado por um drawer que desliza da direita ao clicar num dia com guias. O drawer lista os guias como cards empilhados; cada card mostra tipo do tributo (FGTS/DAS/DARF), nome do arquivo e cor de status. Ao clicar num card, ele se expande inline, revelando download, código de barras e seletor de status - tudo sem sair do drawer e sem depender do painel lateral.
Por que resolve os dois problemas de uma vez:
A identidade do guia ativo passa a ser o próprio card expandido - não mais um painel genérico compartilhado. O usuário sempre vê, de maneira explícita, qual card está aberto. Isso substitui a dependência cognitiva de "perceber que o conteúdo do painel mudou" por "ver qual card está expandido" - muito mais barato para o cérebro. E o overflow de guias some porque o drawer acomoda quantos itens forem necessários com scroll.
Implementar drawer lateral single-open em substituição ao modal.
Largura ~400-440px, slide-in da direita com overlay semitransparente. Cards em accordion single-open (abrir um fecha os demais). Cabeçalho fixo do drawer com data do dia e botão de fechar. Cada card do guia deve ter: ícone e label do tributo, nome do arquivo, chip de status colorido (ver UX-A-004). Ao expandir, revelar download do PDF, código de barras com botão copiar, e o seletor de status corrigido (ver UX-C-005).
Hoje o app já usa três cores distintas para status de guia: verde para pagas, vermelho para vencidas e azul para pendentes. As duas primeiras estão conceitualmente corretas e devem ser mantidas - o problema está no azul usado para pendentes.
Azul transmite a sensação de "documento arquivado, neutro, sem urgência" - o oposto do que um guia pendente precisa comunicar. Uma guia pendente é, por definição, algo que exige atenção antes de virar vencida. O amarelo, por outro lado, é o sinal universal de "atenção" (semáforo, placas de trânsito, avisos de sistema) e dispara um pré-atentivo completamente diferente: em vez de "mais um documento solto na tela", o cérebro lê como "isso aqui precisa da sua ação".
Impacto: o calendário hoje mostra guias, mas não prioriza visualmente o que precisa ser pago. Com a troca, a home vira um semáforo financeiro instantâneo - o usuário abre o app, bate o olho no mês e já sabe exatamente o que fazer. A escala passa a ser coerente: verde (seguro) → amarelo (atenção) → vermelho (urgente).
Substituir o azul dos guias pendentes por amarelo.
O verde de "Pago" e o vermelho de "Vencida" já estão aplicados corretamente - basta conferir se o hex bate com os tokens sugeridos abaixo (ajuste fino opcional). A mudança principal é o pendente: trocar os tokens azuis atuais pelos amarelos da tabela. Aplicar em dois lugares: blocos dentro da célula do calendário e cards dentro do drawer (UX-M-003) - consistência de leitura em toda a home.
| Status | Preenchimento | Borda | Texto | Ícone Solar |
|---|---|---|---|---|
| Pago | #DCFCE7 |
#16A34A |
#15803D |
check-circle-bold-duotone |
| Pendente | #FEF3C7 |
#F59E0B |
#B45309 |
clock-circle-bold-duotone |
| Vencida | #FEE2E2 |
#DC2626 |
#B91C1C |
danger-triangle-bold-duotone |
Passos para reproduzir:
- Abrir um dia que tenha 2 ou mais guias
- Selecionar qualquer guia da lista no modal
- Clicar em "Pago" → nada acontece, o status não muda
- Clicar em "Marcar como não pago" → o guia é marcado como pago (checkbox verde aparece, tag PAGO é aplicada)
Importante: o bug não ocorre em dias com um único guia. Isso sugere que o problema está no loop de render de múltiplas guias - provavelmente na key do .map() ou em uma closure que captura o guia errado.
Impacto: bug funcional crítico - pode causar inconsistência de dados (marcar paga a guia errada, ou não conseguir alterar o status de nenhuma). Compromete a credibilidade do app num fluxo central.
Investigar e corrigir o handler de status no componente que renderiza a lista de guias.
Três hipóteses a verificar, em ordem de probabilidade:
- A
keydo.map()está usando o índice em vez do id da guia. Isso faz o React reaproveitar o DOM de forma incorreta entre renders. - O
onClickdos botões está capturando uma closure antiga do loop - o botão "Pago" pode estar apontando para o handler do último item iterado. - O estado do status está sendo compartilhado entre instâncias (state lifted no nível errado). Cada guia deve ter seu próprio estado isolado ou receber
guiaIdcomo argumento no handler.
Checagem prática: abrir o React DevTools na lista de guias, clicar em "Pago" num guia, e observar qual componente efetivamente dispara o re-render. Se o componente que renderiza é diferente do esperado, a key está errada.
Mobile e Legenda
Quatro ajustes adicionais na mesma tela - dois voltados à experiência mobile e dois ao modal de legenda acionado pelo botão ⓘ. No mobile, o overflow identificado em UX-A-001 fica ainda mais severo por causa do espaço limitado; a proposta é deixar o calendário mais limpo com badges contadores. Já o modal de legenda combina copy confuso com layout totalmente quebrado em telas pequenas - a saída é substituí-lo por uma legenda inline fixa.
O calendário mobile replica o padrão desktop de exibir o nome completo do arquivo da guia dentro da célula do dia. Como a largura útil de cada célula é de apenas alguns caracteres, basta ter duas guias para gerar truncamento severo, quebra visual e ruído. É a mesma patologia do UX-A-001, mas mais grave porque o real estate é muito menor.
Impacto: no dispositivo que o usuário mais usa no dia a dia (celular), a tela principal do app fica visualmente apertada justamente nos dias mais importantes - aqueles com múltiplos vencimentos.
Mobile deve ter tratamento próprio - ver solução estrutural em UX-M-007.
No mobile, o padrão recomendado é não mostrar o nome da guia dentro da célula. Em vez disso, o dia recebe um badge contador que sinaliza quantos pagamentos existem naquela data e a cor do status mais urgente. A lista detalhada fica em uma seção dedicada abaixo do calendário (ver UX-M-007).
A proposta do cliente para mobile tem três camadas complementares que, juntas, transformam a home em um painel de leitura imediata:
1. Calendário limpo com badge contador. A célula do dia deixa de mostrar o nome das guias. No lugar, um pequeno badge no canto superior indica quantas guias existem naquela data. A cor do badge segue o status mais urgente presente no dia - verde se tudo pago, amarelo se há pendentes, vermelho se há alguma vencida. O mês inteiro passa a funcionar como um mapa de calor financeiro.
2. Seção "Próximos vencimentos" abaixo do calendário. Lista agrupada por data, filtrada apenas para guias não-pagas. Usa os cards coloridos da paleta semafórica (amarelo para pendentes, vermelho para vencidas). Resolve dois níveis de leitura: panorâmica no calendário e acionável na lista.
3. Drawer idêntico ao desktop. Ao clicar num dia do calendário, abre o mesmo drawer definido em UX-M-003 - só que responsivo, ocupando praticamente a largura inteira do viewport no celular. Cards de guia empilhados com cores, expandem inline ao toque.
Implementar tratamento mobile-first para o calendário com três entregáveis.
Entregável A - Badge contador na célula do dia: componente pequeno, posicionado absoluto no canto superior direito. Cor derivada do status mais urgente do dia (vencido > pendente > pago). Acessível via aria-label descritivo.
Entregável B - Seção "Próximos vencimentos": lista agrupada por data, ordenada crescente. Filtra apenas guias com status diferente de "pago". Cada item é um card colorido (amarelo para pendente, vermelho para vencido) que, ao clicar, abre o drawer do dia correspondente com aquele guia pré-expandido.
Entregável C - Drawer responsivo: mesmo componente do UX-M-003. No breakpoint mobile, ocupa ~92% da largura do viewport e tem handle superior opcional para arrastar-para-fechar. Animação de entrada da direita mantém-se.
O botão ⓘ ao lado do mês abre um modal de legenda com dois problemas simultâneos:
Problema de linguagem. As descrições das cores tentam cobrir todas as condições temporais possíveis e terminam confundindo o leitor:
- "No vencimento, a vencer ou vencido, porém pago" → é só "Pago", em qualquer contexto temporal
- "No vencimento ou a vencer e não pago" → é só "Pendente"
- "Vencido e não pago" → esta está clara
O esforço em descrever o estado combinado (quando venceu + se pagou) não ajuda - o usuário só precisa saber o estado final: Pago, Pendente ou Vencido.
Problema de layout no mobile. O modal não é responsivo. No celular, o título quebra linha de forma estranha, o conteúdo transborda, a sidebar de navegação aparece por trás (vazando elementos visuais), e a tipografia é cortada. O usuário vê uma tela rachada.
Impacto: o componente que deveria ajudar a entender o calendário acaba adicionando fricção - seja pela redação, seja pela experiência mobile. É fácil resolver os dois problemas de uma vez com a proposta do UX-M-009.
Não corrigir este modal - removê-lo e usar a solução de UX-M-009.
Tentar consertar o copy + deixar o modal responsivo é esforço desperdiçado. A estratégia é eliminar o modal inteiro e substituí-lo por uma legenda inline fixa abaixo do calendário, resolvendo os dois problemas com menos código e menos componentes na árvore.
Sugestão de destino para a seção "Documentos": a lista "DAS - Documento de Arrecadação do Simples Nacional" e similares tem valor e não precisa ser descartada. Pode migrar para um tooltip no próprio card do guia (ao passar o mouse/manter o toque no tipo do tributo, mostra a definição) ou virar uma FAQ acessível por link no rodapé do app.
Remover completamente o modal e o botão ⓘ. No lugar, adicionar uma faixa de legenda inline logo abaixo do calendário - sempre visível, compacta, com três indicadores horizontais:
● VENCIDO · ● PENDENTE DE PAGAMENTO · ● PAGO
Benefícios acumulados:
- Elimina um componente quebrado - o modal responsivo inteiro sai de cena, sem necessidade de correção
- Elimina a fricção do clique - a legenda que antes exigia abrir um modal agora está à vista o tempo todo
- Copy enxuto - uma palavra-estado por cor, sem descrições temporais
- Funciona em qualquer viewport - três chips em linha no desktop, podem quebrar em duas linhas no mobile se necessário
- Reforça o aprendizado - o usuário vê a legenda enquanto olha para o calendário, associando cor → significado de forma imediata
Remover modal + botão ⓘ; inserir legenda inline abaixo do calendário.
Layout: uma faixa horizontal ocupando a largura do calendário, padding vertical ~12px, fundo neutro ou transparente, alinhamento à esquerda ou centralizado. Três indicadores como dot + label, separados por espaço generoso ou ponto mediano.
Responsividade: no mobile, os três chips podem ficar em linha se couberem; se não couberem, quebrar em duas linhas (dois em cima, um embaixo) sem perder legibilidade. Fonte em caixa alta, letter-spacing leve, cor do texto em cinza médio.
Cores dos dots: os mesmos tokens do UX-A-004. Consistência total entre legenda, cards de guia no calendário e cards dentro do drawer.