From bed0fb8e340ac2331a8c78c9148c8f1af744d3a0 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Mon, 5 Oct 2026 12:45:23 +0700 Subject: [PATCH] Deck calculator polish: collapse quote fields, duplicate rows, tax-aware hand-off - The Client quote fields (15+ inputs) are now a collapsed
, so the always-visible Margins card stays short; the chevron rotates on open. - CalcSection buttons set aria-expanded. - Every equipment/material/process/packaging row gains a duplicate (Copy) action. - The sticky summary chip shows the order total when quantity > 1 and uses the setup-inclusive cost. - "List a deck at this price" passes a buyer-inclusive unit price (tax added on top unless tax is marked inclusive). --- AGENTS.md | 9 ++++- src/components/DeckCostCalculator.tsx | 54 ++++++++++++++++++++------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c067384..40ad329 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -853,7 +853,14 @@ session with **no other memory of this project**. So: the prices use them. All four round-trip through CSV, and the state is merged over `DEFAULT_CALC` on read (old sheets/presets can't produce NaN — `clampPct` is NaN-safe too). Currency switching also converts `targetMonthlyProfit`, - `batchSetupCost` and process `rate`. **Currency + `batchSetupCost` and process `rate`. + **Polish (2026-10-05, part 2):** the client-quote fields are a collapsed + `
` ("Client quote details") so the always-visible Margins card stays + short; `CalcSection` sets `aria-expanded`; every table row gains a **duplicate** + (Copy) action beside delete; the sticky summary chip shows the **order total** + when `quantity > 1` (and uses the setup-inclusive cost); and the marketplace + hand-off passes a **buyer-inclusive** unit price (tax added on top when tax + isn't marked inclusive). **Currency (2026-10-05):** a **searchable currency selector** (Popover + search) covering **sats + BTC** (both Bitcoin units) and every **fiat** Coinbase reports (crypto is filtered out via `FIAT_CODES`), and switching **converts every money field** diff --git a/src/components/DeckCostCalculator.tsx b/src/components/DeckCostCalculator.tsx index 1e1280d..7827df9 100644 --- a/src/components/DeckCostCalculator.tsx +++ b/src/components/DeckCostCalculator.tsx @@ -5,7 +5,7 @@ import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Button } from '@/components/ui/button'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { Plus, Trash2, RotateCcw, Search, ChevronDown, ChevronRight, Check, Save, FolderOpen, Download, Upload, AtSign, AlertTriangle, LayoutTemplate, SlidersHorizontal } from 'lucide-react'; +import { Plus, Trash2, RotateCcw, Search, ChevronDown, ChevronRight, Check, Save, FolderOpen, Download, Upload, AtSign, AlertTriangle, LayoutTemplate, SlidersHorizontal, Copy } from 'lucide-react'; import { useLocalStorage } from '@/hooks/useLocalStorage'; import { useBtcRates } from '@/hooks/useExchangeRate'; import { useToast } from '@/hooks/useToast'; @@ -292,7 +292,7 @@ function CalcSection({ title, subtotal, defaultOpen = false, children }: { title const [open, setOpen] = useState(defaultOpen); return (
- + +
+ + +
+ ))} @@ -1341,7 +1349,12 @@ export function DeckCostCalculator() { {numInput(m.orderMin, (n) => up({ orderMin: n }))} {numInput(m.unloadMin, (n) => up({ unloadMin: n }))} {fmt(per)} - + +
+ + +
+ ); })} @@ -1372,7 +1385,12 @@ export function DeckCostCalculator() { {advanced && {numInput(p.rate, (n) => up({ rate: n }))}} {advanced && {numInput(p.scrapPct, (n) => up({ scrapPct: Math.min(99, n) }))}} {fmt(per)} - + +
+ + +
+ ); })} @@ -1400,7 +1418,12 @@ export function DeckCostCalculator() { {numInput(p.minutesPerBoard, (n) => up({ minutesPerBoard: n }))} {numInput(p.materialsPerBoard, (n) => up({ materialsPerBoard: n }))} {fmt(per)} - + +
+ + +
+ ); })} @@ -1497,10 +1520,14 @@ export function DeckCostCalculator() { )}

Does not include shipping to the buyer.

- {/* Quote details — your identity on the client PDF. */} -
-
-

Quote details (for the client PDF)

+ {/* Quote details — your identity on the client PDF (collapsed by default). */} +
+ + Client quote details (for the PDF) + + +
+