- feat(025): favoritos locais com FavoritesContext, HeartButton, PublicFavoritesPage
- feat(026): central de contatos admin (leads/contatos unificados)
- feat(027): configuração da página de contato via admin
- feat(028): trabalhe conosco - candidaturas com upload e admin
- feat(029): UX área do cliente - visitas, comparação, perfil
- feat(030): navbar UX - menu mobile, ThemeToggle, useFavorites
- feat(031): hero light/dark - imagens separadas por tema, upload, preview, seed
- feat(032): performance homepage - Promise.all parallel fetches, sessionStorage cache,
preload hero image, loading=lazy nos cards, useInView hook, will-change carrossel,
keyframes em index.css, AgentsCarousel e HomeScrollScene via props
- fix: light mode HomeScrollScene - gradiente, cores de texto, scroll hint
migrations: g1h2i3j4k5l6 (source em leads), h1i2j3k4l5m6 (contact_config),
i1j2k3l4m5n6 (job_applications), j2k3l4m5n6o7 (hero theme images)
14 KiB
Feature Specification: Revisão UX/UI — Área do Cliente
Feature Branch: 029-ux-area-do-cliente
Created: 2026-04-22
Status: Draft
User Scenarios & Testing (mandatory)
User Story 1 — Navegar direto para Favoritos ao acessar a Área do Cliente (Priority: P1)
O cliente autenticado digita ou clica no link da Área do Cliente e chega imediatamente à lista de imóveis favoritos, sem passar por uma tela de painel intermediária que não agrega valor.
Why this priority: Elimina um clique desnecessário presente hoje. É a mudança de maior impacto imediato na jornada do usuário e desbloqueio para todo o restante da área.
Independent Test: Acessar /area-do-cliente deve redirecionar para /area-do-cliente/favoritos. A página de Favoritos deve carregar de forma autônoma e ser completamente utilizável.
Acceptance Scenarios:
- Given um cliente autenticado, When ele acessa
/area-do-cliente, Then é redirecionado automaticamente para/area-do-cliente/favoritos. - Given um cliente autenticado, When ele acessa
/area-do-cliente/boletos, Then recebe uma resposta 404 (rota inexistente). - Given um cliente autenticado, When ele visualiza o menu lateral, Then os itens "Painel" e "Boletos" não estão presentes.
User Story 2 — Visualizar favoritos com imagem, preço e localização (Priority: P1)
O cliente vê seus imóveis favoritos exibidos em cards que mostram a thumbnail da propriedade, o preço e a cidade/bairro, permitindo identificar cada imóvel sem precisar clicar para abrir.
Why this priority: É a página mais acessada da área do cliente. Sem imagem e preço, o usuário não consegue distinguir os imóveis e a experiência é frustrante.
Independent Test: Com ao menos um favorito salvo, a página deve exibir cards com imagem (ou placeholder), preço formatado e localização.
Acceptance Scenarios:
- Given um cliente com favoritos salvos, When ele acessa
/area-do-cliente/favoritos, Then cada card exibe thumbnail da propriedade (ou placeholder se sem foto), título, preço e cidade/bairro. - Given um cliente sem favoritos, When ele acessa a página, Then vê um empty state informativo com link para
/imoveis. - Given um cliente visualizando favoritos, When ele clica em "Ver imóvel", Then é levado à página de detalhes do imóvel.
- Given um cliente visualizando favoritos, When ele remove um favorito, Then o card some da lista sem recarregar a página.
User Story 3 — Cancelar visita agendada (Priority: P2)
O cliente pode solicitar o cancelamento de uma visita com status pendente diretamente pela Área do Cliente, sem precisar entrar em contato por outro canal.
Why this priority: Resolve um ponto de atrito real: hoje o usuário não tem como cancelar uma visita pelo sistema, o que gera contato desnecessário via WhatsApp ou telefone.
Independent Test: Com uma visita no status "pendente", o botão "Cancelar" deve ser exibido e, ao clicar, alterar o status para "cancelado".
Acceptance Scenarios:
- Given uma visita com
status=pending, When o cliente acessa/area-do-cliente/visitas, Then o card exibe o botão "Cancelar". - Given o cliente clica em "Cancelar", When a ação é confirmada, Then o status do card muda para "cancelado" e o botão desaparece.
- Given uma visita com status diferente de
pending(ex: confirmada, cancelada), When o cliente visualiza o card, Then o botão "Cancelar" não está disponível. - Given uma falha de rede ao cancelar, When a requisição retorna erro, Then o cliente vê uma mensagem de erro e o status não muda.
User Story 4 — Editar perfil e trocar senha (Priority: P2)
O cliente pode acessar /area-do-cliente/conta, visualizar seus dados cadastrais, atualizar o nome e alterar a senha, tudo dentro da Área do Cliente.
Why this priority: Hoje não existe nenhuma forma do cliente atualizar seus dados pelo sistema. É uma funcionalidade básica esperada em qualquer área logada.
Independent Test: A página /area-do-cliente/conta deve existir com formulário funcional de atualização de nome e de troca de senha.
Acceptance Scenarios:
- Given o cliente acessa
/area-do-cliente/conta, When a página carrega, Then exibe o nome atual preenchido e o e-mail em campo somente leitura. - Given o cliente altera o nome e clica em "Salvar", When o nome é válido (não vazio), Then vê confirmação de sucesso e o nome atualizado no menu lateral.
- Given o cliente preenche "Senha atual", "Nova senha" e "Confirmar nova senha", When as senhas coincidem e têm pelo menos 8 caracteres, Then a senha é alterada e uma mensagem de sucesso é exibida.
- Given o cliente informa uma senha atual incorreta, When submete o form, Then vê mensagem de erro "Senha atual incorreta" sem alterar nada.
- Given "Nova senha" e "Confirmar nova senha" divergem, When o cliente tenta salvar, Then vê validação inline "As senhas não coincidem" antes de enviar ao servidor.
User Story 5 — Navegação com ícones consistentes e item "Minha conta" (Priority: P3)
O cliente vê o menu lateral (desktop) e a barra de navegação (mobile) com ícones vetoriais consistentes em qualquer sistema operacional, e um link "Minha conta" que leva à nova página de perfil.
Why this priority: Melhoria visual e de consistência; não bloqueia funcionalidades principais, mas impacta a percepção de qualidade do produto.
Independent Test: O menu deve renderizar 4 itens (Favoritos, Comparar, Visitas, Minha conta) com ícones SVG visíveis e corretos em temas claro e escuro.
Acceptance Scenarios:
- Given o cliente está na Área do Cliente, When visualiza o menu lateral ou a barra mobile, Then os 4 itens (Favoritos, Comparar, Visitas, Minha conta) estão presentes com ícones SVG.
- Given o cliente está em qualquer página da área do cliente, When observa o item de menu correspondente à página atual, Then o item está visualmente destacado (ativo).
- Given o cliente está em mobile, When acessa a barra de navegação, Then os 4 itens estão centralizados sem scroll horizontal desnecessário.
- Given o cliente clica em "Sair", When a ação é executada, Then o ícone do botão é o ícone de logout (seta saindo de uma porta), não uma seta genérica.
User Story 6 — Empty state explicativo no Comparar (Priority: P3)
O cliente que acessa a página de comparação sem imóveis selecionados recebe uma instrução clara sobre como adicionar imóveis à comparação.
Why this priority: Melhoria de usabilidade pontual; sem ela o usuário fica confuso, mas o impacto é menor que os itens anteriores.
Independent Test: Acessar /area-do-cliente/comparar sem imóveis selecionados deve exibir o empty state com a instrução de uso.
Acceptance Scenarios:
- Given o cliente não tem imóveis na comparação, When acessa
/area-do-cliente/comparar, Then vê uma mensagem explicando como adicionar imóveis (ex: "Acesse um imóvel e clique em 'Comparar' para adicioná-lo aqui"). - Given o cliente tem imóveis na comparação, When acessa a página, Then a tabela de comparação é exibida normalmente.
Edge Cases
- O que acontece se a foto de um imóvel favorito for removida após ser salvo? → O card exibe um placeholder de imagem.
- O que acontece se o cliente tentar cancelar uma visita já cancelada por outra aba? → O servidor retorna erro e o frontend exibe mensagem informativa.
- O que acontece se o cliente enviar o form de perfil com nome vazio? → Validação inline impede o envio antes de chegar ao servidor.
- O que acontece se o cliente sem favoritos tentar acessar diretamente
/area-do-cliente? → Redireciona para/area-do-cliente/favoritose exibe o empty state de favoritos. - O que acontece se a sessão expirar durante uso da área do cliente? → O cliente é redirecionado para a tela de login com mensagem de sessão expirada.
Requirements (mandatory)
Functional Requirements
Roteamento e Estrutura
- FR-001: O sistema DEVE redirecionar
/area-do-clientepara/area-do-cliente/favoritosde forma automática. - FR-002: A rota
/area-do-cliente/boletosDEVE ser removida; acessá-la DEVE retornar 404. - FR-003: O menu de navegação da Área do Cliente DEVE conter exatamente 4 itens: Favoritos, Comparar, Visitas e Minha conta.
- FR-004: Os ícones do menu DEVE ser SVG vetoriais (Heroicons 2.0 outline), sem uso de emoji ou caracteres Unicode.
Favoritos
- FR-005: Cada card de favorito DEVE exibir: thumbnail da propriedade (ou placeholder padronizado), título, preço formatado em reais e cidade/bairro.
- FR-006: A thumbnail DEVE ser obtida a partir dos dados da propriedade (campo
cover_photoou primeira foto da galeria). - FR-007: O card DEVE oferecer as ações "Ver imóvel" (navega para detalhe) e "Remover dos favoritos" (remove sem recarregar a página).
Visitas
- FR-008: O card de visita DEVE exibir: título do imóvel em destaque, data agendada/solicitada em destaque, badge de status alinhado à direita e mensagem como texto secundário.
- FR-009: Visitas com
status=pendingDEVE exibir botão "Cancelar". - FR-010: Ao confirmar o cancelamento, o sistema DEVE chamar
PATCH /me/visits/:id/cancele atualizar o status do card para "cancelado" sem recarregar a página. - FR-011: Visitas com status diferente de
pendingNÃO DEVEM exibir o botão "Cancelar".
Comparar
- FR-012: Quando não há imóveis selecionados para comparação, a página DEVE exibir um empty state com instrução clara de como adicionar imóveis à comparação.
Perfil / Minha conta
- FR-013: A rota
/area-do-cliente/contaDEVE ser criada e acessível pelo menu "Minha conta". - FR-014: A página de conta DEVE exibir o nome atual do cliente em campo editável e o e-mail em campo somente leitura.
- FR-015: O cliente DEVE poder atualizar o nome via
PATCH /me/profile; o campo nome é obrigatório. - FR-016: O cliente DEVE poder trocar a senha informando senha atual, nova senha e confirmação via
PATCH /me/password. - FR-017: A nova senha DEVE ter no mínimo 8 caracteres; a confirmação DEVE ser idêntica à nova senha; validações DEVEM ocorrer no frontend antes do envio.
- FR-018: Se a senha atual informada estiver incorreta, o servidor DEVE retornar erro e o frontend DEVE exibir "Senha atual incorreta".
Backend — Novos Endpoints
- FR-019:
PATCH /me/profile— atualiza o nome do cliente autenticado. Requer autenticação JWT. Retorna os dados atualizados. - FR-020:
PATCH /me/password— altera a senha do cliente autenticado. Valida senha atual antes de persistir. Requer autenticação JWT. - FR-021:
PATCH /me/visits/:id/cancel— cancela uma visita comstatus=pendingpertencente ao cliente autenticado. Retorna a visita atualizada. Requer autenticação JWT. - FR-022: Tentativa de cancelar visita com status diferente de
pendingDEVE retornar erro com mensagem descritiva. - FR-023: Tentativa de cancelar visita de outro cliente DEVE retornar 403 Forbidden.
Layout e Mobile
- FR-024: O botão "Sair" DEVE usar o ícone ArrowRightOnRectangle (Heroicons) no lugar do caractere
→. - FR-025: Em viewport mobile, a barra de navegação DEVE centralizar os 4 itens e indicar visualmente o item ativo.
Key Entities
- ClientUser: Usuário da área do cliente. Atributos relevantes:
id,name,email,password_hash. Possui coleções de favoritos e visitas. - SavedProperty (Favorito): Associação entre
ClientUsereProperty. Atributos relevantes:id,client_user_id,property_id,created_at. - VisitRequest (Visita): Solicitação de visita feita por um
ClientUserpara umaProperty. Atributos relevantes:id,client_user_id,property_id,scheduled_date,status(pending | confirmed | cancelled),message. - Property (Imóvel): Imóvel do catálogo. Atributos consumidos nesta feature:
id,title,price,city,neighborhood,cover_photo(ou galeria de fotos).
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: O cliente chega ao conteúdo real (Favoritos) com um clique a menos do que hoje — a página de painel não existe mais como etapa intermediária.
- SC-002: O cliente consegue identificar visualmente seus imóveis favoritos sem precisar abrir nenhum deles — cada card mostra imagem, preço e localização.
- SC-003: O cliente consegue cancelar uma visita pendente em menos de 3 cliques a partir da página de Visitas, sem sair da Área do Cliente.
- SC-004: O cliente consegue atualizar nome ou senha em uma única interação com o formulário de conta, sem precisar entrar em contato com suporte.
- SC-005: Os ícones do menu são renderizados de forma idêntica em Windows, macOS e Linux, tanto em tema claro quanto escuro.
- SC-006: A taxa de abandono da Área do Cliente (saída imediata) deve ser reduzida, dado que o primeiro conteúdo exibido passa a ser imediatamente útil.
- SC-007: Todos os 3 novos endpoints do backend respondem corretamente com autenticação válida e retornam erros descritivos para entradas inválidas.
Assumptions
- A tabela
client_usersjá existe no banco com as colunasid,name,emailepassword_hash; nenhuma migration de schema é necessária para os endpoints de perfil e senha. - A tabela
visit_requestsjá possui a colunastatuscom os valorespending,confirmedecancelled; o endpoint de cancelamento apenas atualiza este campo. - O backend de favoritos já expõe o
property_id; a foto do imóvel será obtida do campocover_photoda tabela de propriedades ou do primeiro item retornado pela API de fotos já existente. - O sistema de autenticação JWT para clientes já está operacional; os novos endpoints reutilizarão o mesmo middleware de autenticação.
- A remoção de
BoletosPageé apenas frontend e de rota; o model e os dados de boletos no banco são mantidos intactos para uso futuro pelo admin. - O componente de comparação já armazena os imóveis selecionados em estado local ou contexto; esta feature não altera o mecanismo de seleção, apenas o empty state.
- Não há requisito de confirmação por e-mail para troca de senha nesta fase (fluxo simplificado: validar senha atual → salvar nova senha).
- A feature não inclui upload de foto de perfil do cliente.