Pular para o conteúdo principal

Modos de Visualização e Detalhes do Produto

Última atualização: 15 de julho de 2026

Visão Geral

O catálogo oferece cinco modos de exibição para a lista de produtos, badges de status sobre cada card, e um modal de detalhes com informações completas de um produto. Esta seção também é onde aparecem os pontos menos maduros da feature: um seletor de unidade que não funciona, uma ação rápida que só loga no console, e código morto duplicado em torno da própria persistência do modo de visualização.

Arquivos-chave

ArquivoResponsabilidade
features/catalog/components/view-mode-modal/view-mode-modal.catalog.tsxModal de escolha entre os cinco modos de exibição
features/catalog/catalog.constants.tsBADGES_PRODUCTS_CATALOG, um dos mapas de badge usados no catálogo
features/catalog/components/product-details-modal/product-details-modal.catalog.tsxModal de detalhes do produto, ações rápidas, seletor de unidade
features/catalog/components/select-unit-modal/select-unit-modal.catalog.tsxSeletor de unidade de medida, hoje sem dados

Os cinco modos de exibição

Os modos são "Super Compacto", "Compacto", "Expandido", "Super Expandido" e "Catálogo" (com foco em imagem, pensado para mostrar ao cliente), com a mesma ideia dos modos de visualização de produtos da tela de nova venda:

// view-mode-modal.catalog.tsx
const VIEW_MODE_OPTIONS = [
{ label: "Super Compacto", value: "super-compact", accentLabel: "Mais produtos por tela", icon: "view-sequential" },
{ label: "Compacto", value: "compact", accentLabel: "Informações básicas", icon: "view-agenda-outline" },
{ label: "Expandido", value: "expanded", accentLabel: "Mais detalhes visíveis", icon: "view-day-outline" },
{ label: "Super Expandido", value: "super-expanded", accentLabel: "Máximo de informações", icon: "view-dashboard-outline" },
{ label: "Catálogo", value: "catalog", accentLabel: "Visual ideal para apresentar ao cliente", icon: "view-grid-outline" },
];

O modo atual é lido e gravado através do serviço genérico de settings, sob a chave catalogProductViewMode, com "compact" como padrão:

// view-mode-modal.catalog.tsx
const currentViewMode = (settings.get?.("catalogProductViewMode") ?? "compact") as ViewModeValue;
// ...
settings?.update("catalogProductViewMode", option.value);

Existe um segundo mecanismo de persistência para o mesmo conceito, e ele não é usado

storage/catalog-preferences.storage.ts define um par próprio de funções para isso, getProductViewModeCatalog/setProductViewModeCatalog, com sua própria chave (catalog:productViewMode) e seu próprio valor padrão ("catalog", diferente do "compact" usado pelo modal). Nenhuma dessas duas funções é chamada em lugar nenhum do app fora do próprio arquivo onde são definidas. O modo de visualização realmente usado pela tela é o gravado via settings, não esse par de funções dedicado.

Badges de status: três mapas de cores diferentes para os mesmos rótulos

O catálogo tem seu próprio mapa de badges, parecido em forma com o de nova venda, mas não é o mesmo objeto:

// catalog.constants.ts
export const BADGES_PRODUCTS_CATALOG = {
promocao: { letter: "$", color: "#FF0606" },
comEstoque: { letter: "E", color: "#73A960" },
semEstoque: { letter: "E", color: "#F15959" },
suspenso: { letter: "S", color: "#ffa60d" },
descontinuado: { letter: "D", color: "#191919" },
// ...
};

E o próprio modal de detalhes do produto usa um terceiro mapa, badgesExpandedAvaliable, definido inline no componente, com cores diferentes para algumas das mesmas chaves (por exemplo, suspenso é #ffa60d em BADGES_PRODUCTS_CATALOG mas #9500A6 no modal de detalhes). Some a esses dois o mapa de badges de nova venda, documentado em Validação Comercial, e são três definições independentes da mesma linguagem visual de badges convivendo no app. Ajustar a cor de um badge num lugar não muda o mesmo badge nos outros dois.

O modal de detalhes do produto

O modal de detalhes reúne imagem, preço, estoque, badges, e duas ações rápidas: atualizar estoque e uma consulta de desconto/acréscimo.

// product-details-modal.catalog.tsx
const quickActionOptions = [
{ label: "Atualizar Estoque", value: "refresh" },
{ label: "Consulta Desc. e Acres.", value: "discount-query" },
];

const handleQuickAction = (value: string) => {
if (value === "refresh") {
controller.onPressRefreshProducts();
return;
}
if (value === "discount-query") {
console.log("Consulta Desc. e Acres.");
}
};

"Atualizar Estoque" é real, chama a mesma função que recarrega a lista de produtos do catálogo. "Consulta Desc. e Acres." ainda não faz nada além de logar no console.

Produtos similares reaproveita um componente de nova venda

A seção de produtos similares no modal de detalhes não reimplementa nada, ela importa e reaproveita ProductSimilar diretamente de features/new-sale/new-sale-products/components/product-similar/product-similar, o mesmo componente usado dentro do fluxo de venda:

import { ProductSimilar } from "@/features/new-sale/new-sale-products/components/product-similar/product-similar";

Essa seção só aparece quando o produto atual tem similarProducts preenchido:

{!!controller?.productDetails?.similarProducts?.length && (
<Accordion title="Produtos Similares">
<ProductSimilar product={controller?.productDetails} controllerCatalog={controller} />
</Accordion>
)}

Existe também, um pouco mais acima no mesmo arquivo, um bloco de JSX comentado chamado "Produtos similares" (em minúsculas) que usava dados de productsMock diretamente. Esse bloco é código morto deixado de lado depois que a versão real, com ProductSimilar e dados de fato do produto, foi implementada. Da mesma forma, um accordion de "Últimas Vendas" também está comentado, referenciando um lastSalesMock que nunca chegou a ser substituído por dados reais.

O seletor de unidade de medida não tem dados

Ao abrir o seletor de unidade de medida, seja pelo card do produto ou pelo modal de detalhes, a tabela que deveria listar as unidades disponíveis (unidade, quantidade, valor unitário, valor total) está com os dados vazios, e a seleção não faz nada:

// select-unit-modal.catalog.tsx
<Table
selectable
rowKey="cod"
onSelect={(row) => controller.setProductCodVol(row.cod, controller?.productDetails?.id)}
columns={[/* Unid., Qtd., Vlr. Unit., V.Total */]}
data={
[
// { cod: "UN", quantity: "1", vlrUnit: "22,50", vlrTot: "22,50" },
// { cod: "CX", quantity: "10", vlrUnit: "22,50", vlrTot: "225,00" },
// { cod: "KG", quantity: "8", vlrUnit: "22,50", vlrTot: "180,00" }
]
}
selectedKey={(e) => {
console.log("selectedKey");
}}
/>

onSelect já chama controller.setProductCodVol, uma função real que existe no controller, mas como data é sempre um array vazio, não há nenhuma linha para o usuário tocar. O prop selectedKey, que provavelmente deveria refletir a unidade atualmente selecionada, também é só um console.log. Escolher uma unidade de medida diferente pelo catálogo não é possível hoje.

Armadilhas conhecidas

Antes de "corrigir" o modo de visualização ou o mapa de badges, confirme qual das implementações paralelas está de fato conectada à UI, não assuma que a que parece mais bem nomeada é a usada. E não estenda o seletor de unidade de medida sem primeiro decidir de onde os dados de unidade viriam, hoje não existe nenhuma consulta real alimentando aquela tabela.