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
| Arquivo | Responsabilidade |
|---|---|
features/catalog/components/view-mode-modal/view-mode-modal.catalog.tsx | Modal de escolha entre os cinco modos de exibição |
features/catalog/catalog.constants.ts | BADGES_PRODUCTS_CATALOG, um dos mapas de badge usados no catálogo |
features/catalog/components/product-details-modal/product-details-modal.catalog.tsx | Modal de detalhes do produto, ações rápidas, seletor de unidade |
features/catalog/components/select-unit-modal/select-unit-modal.catalog.tsx | Seletor 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.