# 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**: 1. **Given** um cliente autenticado, **When** ele acessa `/area-do-cliente`, **Then** é redirecionado automaticamente para `/area-do-cliente/favoritos`. 2. **Given** um cliente autenticado, **When** ele acessa `/area-do-cliente/boletos`, **Then** recebe uma resposta 404 (rota inexistente). 3. **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**: 1. **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. 2. **Given** um cliente sem favoritos, **When** ele acessa a página, **Then** vê um empty state informativo com link para `/imoveis`. 3. **Given** um cliente visualizando favoritos, **When** ele clica em "Ver imóvel", **Then** é levado à página de detalhes do imóvel. 4. **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**: 1. **Given** uma visita com `status=pending`, **When** o cliente acessa `/area-do-cliente/visitas`, **Then** o card exibe o botão "Cancelar". 2. **Given** o cliente clica em "Cancelar", **When** a ação é confirmada, **Then** o status do card muda para "cancelado" e o botão desaparece. 3. **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. 4. **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**: 1. **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. 2. **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. 3. **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. 4. **Given** o cliente informa uma senha atual incorreta, **When** submete o form, **Then** vê mensagem de erro "Senha atual incorreta" sem alterar nada. 5. **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**: 1. **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. 2. **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). 3. **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. 4. **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**: 1. **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"). 2. **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/favoritos` e 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-cliente` para `/area-do-cliente/favoritos` de forma automática. - **FR-002**: A rota `/area-do-cliente/boletos` DEVE 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_photo` ou 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=pending` DEVE exibir botão "Cancelar". - **FR-010**: Ao confirmar o cancelamento, o sistema DEVE chamar `PATCH /me/visits/:id/cancel` e atualizar o status do card para "cancelado" sem recarregar a página. - **FR-011**: Visitas com status diferente de `pending` NÃ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/conta` DEVE 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 com `status=pending` pertencente ao cliente autenticado. Retorna a visita atualizada. Requer autenticação JWT. - **FR-022**: Tentativa de cancelar visita com status diferente de `pending` DEVE 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 `ClientUser` e `Property`. Atributos relevantes: `id`, `client_user_id`, `property_id`, `created_at`. - **VisitRequest (Visita)**: Solicitação de visita feita por um `ClientUser` para uma `Property`. 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_users` já existe no banco com as colunas `id`, `name`, `email` e `password_hash`; nenhuma migration de schema é necessária para os endpoints de perfil e senha. - A tabela `visit_requests` já possui a coluna `status` com os valores `pending`, `confirmed` e `cancelled`; 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 campo `cover_photo` da 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.