feat(catalog): filtro de preço e seletor de pauta
- Catálogo só mostra produtos com preço preenchido (vl_preco1 > 0) por default - Novo endpoint GET /catalog/pautas — retorna as 6 pautas do representante logado - GET /catalog?idPauta=N — usa preço da pauta selecionada (vw_pauta_produtos) - CatalogPage: dropdown "Selecionar pauta de preços" com as pautas do rep - product.contract: adiciona PautaSchema e idPauta no ProdutoListQuerySchema Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { useState } from 'react';
|
||||
import { Table, Input, Typography, Tag } from 'antd';
|
||||
import { Table, Input, Select, Space, Typography, Tag } from 'antd';
|
||||
import type { TableColumnsType } from 'antd';
|
||||
import type { ProdutoSummary } from '@sar/api-interface';
|
||||
import { useCatalog } from '../../lib/queries/catalog';
|
||||
import { useCatalog, usePautas } from '../../lib/queries/catalog';
|
||||
|
||||
const { Title } = Typography;
|
||||
const { Search } = Input;
|
||||
@@ -45,9 +45,13 @@ const columns: TableColumnsType<ProdutoSummary> = [
|
||||
{
|
||||
title: 'Preço',
|
||||
dataIndex: 'vlPreco1',
|
||||
width: 110,
|
||||
width: 120,
|
||||
align: 'right',
|
||||
render: (v: string) => fmtPrice(v),
|
||||
render: (v: string) => (
|
||||
<span style={{ fontWeight: 600, color: Number(v) > 0 ? '#389e0d' : '#999' }}>
|
||||
{fmtPrice(v)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Estoque',
|
||||
@@ -66,10 +70,12 @@ const columns: TableColumnsType<ProdutoSummary> = [
|
||||
|
||||
export function CatalogPage() {
|
||||
const [q, setQ] = useState('');
|
||||
const [idPauta, setIdPauta] = useState<number | undefined>();
|
||||
const [page, setPage] = useState(1);
|
||||
const limit = 50;
|
||||
|
||||
const { data, isLoading } = useCatalog({ q: q || undefined, page, limit });
|
||||
const { data: pautas, isLoading: pautasLoading } = usePautas();
|
||||
const { data, isLoading } = useCatalog({ q: q || undefined, idPauta, page, limit });
|
||||
|
||||
return (
|
||||
<div style={{ padding: 24 }}>
|
||||
@@ -77,21 +83,37 @@ export function CatalogPage() {
|
||||
Catálogo de Produtos
|
||||
</Title>
|
||||
|
||||
<Search
|
||||
placeholder="Buscar por código ou descrição..."
|
||||
allowClear
|
||||
style={{ width: 320, marginBottom: 16 }}
|
||||
onSearch={(v) => {
|
||||
setQ(v);
|
||||
setPage(1);
|
||||
}}
|
||||
onChange={(e) => {
|
||||
if (!e.target.value) {
|
||||
setQ('');
|
||||
<Space style={{ marginBottom: 16 }} wrap>
|
||||
<Search
|
||||
placeholder="Buscar por código ou descrição..."
|
||||
allowClear
|
||||
style={{ width: 300 }}
|
||||
onSearch={(v) => {
|
||||
setQ(v);
|
||||
setPage(1);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
}}
|
||||
onChange={(e) => {
|
||||
if (!e.target.value) {
|
||||
setQ('');
|
||||
setPage(1);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
placeholder="Selecionar pauta de preços"
|
||||
allowClear
|
||||
loading={pautasLoading}
|
||||
style={{ width: 340 }}
|
||||
onChange={(v) => {
|
||||
setIdPauta(v as number | undefined);
|
||||
setPage(1);
|
||||
}}
|
||||
options={pautas?.map((p) => ({
|
||||
value: p.idPauta,
|
||||
label: `${p.codigo} — ${p.descricao}`,
|
||||
}))}
|
||||
/>
|
||||
</Space>
|
||||
|
||||
<Table<ProdutoSummary>
|
||||
rowKey="idErp"
|
||||
|
||||
Reference in New Issue
Block a user