From 634cf4db48260b5086242c2f1953b19d6b3359a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Thu, 9 Jul 2026 13:23:25 -0300 Subject: [PATCH] Simplify cutting controls --- src/pages/Cutting.tsx | 336 ++++++++++++++++++++++-------------------- vite.config.ts | 4 +- 2 files changed, 178 insertions(+), 162 deletions(-) diff --git a/src/pages/Cutting.tsx b/src/pages/Cutting.tsx index cfd0ca0..8c117d8 100644 --- a/src/pages/Cutting.tsx +++ b/src/pages/Cutting.tsx @@ -14,6 +14,7 @@ type CutSort = 'need_desc' | 'need_asc' | 'demand_desc' | 'stock_asc' | 'sold_de type SaveStatus = 'idle' | 'saving' | 'saved' | 'error'; type CutProductIssue = Exclude; type CorrectionIssueFilter = CutProductIssue | 'all'; +type SettingsSection = 'rules' | 'corrections'; const SETTINGS_STORAGE_KEY = 'nexstar_cutting_settings'; const coverageTargetOptions = [7, 15, 30, 60]; @@ -124,6 +125,7 @@ const Cutting = () => { const [cutFilter, setCutFilter] = useState('need'); const [sortBy, setSortBy] = useState('need_desc'); const [isSettingsOpen, setIsSettingsOpen] = useState(false); + const [settingsSection, setSettingsSection] = useState('rules'); const [cuttingSettings, setCuttingSettings] = useState(loadCuttingSettings); const [saveStatus, setSaveStatus] = useState('idle'); const [hasUnsavedSettings, setHasUnsavedSettings] = useState(false); @@ -261,10 +263,6 @@ const Cutting = () => { const configuredYieldCount = CUT_FAMILY_RULES.filter(rule => cuttingSettings.familyYields[rule.key]).length; const productOverrideCount = Object.keys(cuttingSettings.productOverrides).length; - useEffect(() => { - setCorrectionPage(1); - }, [correctionIssueFilter, dateRange, targetCoverageDays]); - useEffect(() => { if (!isSettingsOpen) return undefined; @@ -350,6 +348,11 @@ const Cutting = () => { setSaveStatus('idle'); }; + const openSettingsSection = (section: SettingsSection) => { + setSettingsSection(section); + setIsSettingsOpen(true); + }; + const exportRows = () => { exportToCSV(filteredRows.map(row => ({ 'ID Produto': row.id, @@ -408,6 +411,7 @@ const Cutting = () => { onChange={(range) => { setDateRange(range); setCurrentPage(1); + setCorrectionPage(1); }} /> @@ -423,9 +427,9 @@ const Cutting = () => { + -
-
-
-

Correções de produto

-

- Use quando o nome do SKU não deixa claro família, cor ou tamanho para montar o corte. -

-
-
- - {formatNumber(correctionRows.length)} produtos - - -
+ {settingsSection === 'rules' && ( +
+ {CUT_FAMILY_RULES.map(rule => ( + + ))}
+ )} - {correctionRows.length ? ( - <> -
-
-
- ID - Produto - Família - Cor - Tamanho - Ações -
-
- {paginatedCorrectionRows.map(row => { - const override = cuttingSettings.productOverrides[row.id] || {}; - return ( -
- #{row.id} -
-
{row.name}
-
- {row.issues.filter(issue => issue !== 'missing_yield_rule').map(issue => ( - - {issueLabels[issue]} - + {settingsSection === 'corrections' && ( +
+
+
+

Correções de produto

+

+ Use quando o nome do SKU não deixa claro família, cor ou tamanho para montar o corte. +

+
+
+ + {formatNumber(correctionRows.length)} produtos + + +
+
+ + {correctionRows.length ? ( + <> +
+
+
+ ID + Produto + Família + Cor + Tamanho + Ações +
+
+ {paginatedCorrectionRows.map(row => { + const override = cuttingSettings.productOverrides[row.id] || {}; + return ( +
+ #{row.id} +
+
{row.name}
+
+ {row.issues.filter(issue => issue !== 'missing_yield_rule').map(issue => ( + + {issueLabels[issue]} + + ))} +
+
+ + updateProductOverride(row.id, { color: event.target.value })} + placeholder={row.color || 'Cor'} + className="h-9 rounded-lg border border-dark-border bg-dark-input px-2 text-xs font-bold text-dark-text outline-none focus:border-brand-primary" + /> + updateProductOverride(row.id, { size: event.target.value })} + placeholder={row.size || 'Tam.'} + className="h-9 rounded-lg border border-dark-border bg-dark-input px-2 text-xs font-bold text-dark-text outline-none focus:border-brand-primary" + /> +
+
- - updateProductOverride(row.id, { color: event.target.value })} - placeholder={row.color || 'Cor'} - className="h-9 rounded-lg border border-dark-border bg-dark-input px-2 text-xs font-bold text-dark-text outline-none focus:border-brand-primary" - /> - updateProductOverride(row.id, { size: event.target.value })} - placeholder={row.size || 'Tam.'} - className="h-9 rounded-lg border border-dark-border bg-dark-input px-2 text-xs font-bold text-dark-text outline-none focus:border-brand-primary" - /> -
- -
-
- ); - })} + ); + })} +
-
- setCorrectionPage(1)} - className="border-t border-dark-border px-4 py-3" - /> - - ) : ( -
-

Nenhuma correção de produto pendente.

-

Os dados restantes, se existirem, são de rendimento por família.

-
- )} -
+ setCorrectionPage(1)} + className="border-t border-dark-border px-4 py-3" + /> + + ) : ( +
+

Nenhuma correção de produto pendente.

+

Os dados restantes, se existirem, são de rendimento por família.

+
+ )} +
+ )}
)} @@ -706,7 +733,11 @@ const Cutting = () => {
{issueSummaries.map(summary => ( - +
))}
@@ -752,15 +773,9 @@ const Cutting = () => {
{cutPlan.familySummaries.map(summary => ( - +
))} @@ -801,6 +816,7 @@ const Cutting = () => { onChange={(event) => { setTargetCoverageDays(Number(event.target.value)); setCurrentPage(1); + setCorrectionPage(1); }} className="h-11 rounded-xl border border-dark-border bg-dark-input px-3 text-sm font-semibold text-dark-text focus:border-brand-primary focus:outline-none cursor-pointer" aria-label="Dias de cobertura alvo" diff --git a/vite.config.ts b/vite.config.ts index 4a992ef..5082c04 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -25,7 +25,7 @@ export default defineConfig(({ command }) => ({ tailwindcss() ], server: { - port: 3001, + port: 3002, proxy: { '/api': { target: 'http://localhost:3004', @@ -34,7 +34,7 @@ export default defineConfig(({ command }) => ({ } }, preview: { - port: 3000, + port: 3002, proxy: { '/api': { target: 'http://localhost:3004',