Skip to content

Update Products page and Stock Movements pages#4

Merged
lexmarcos merged 32 commits into
mainfrom
indexdb
Jun 18, 2026
Merged

Update Products page and Stock Movements pages#4
lexmarcos merged 32 commits into
mainfrom
indexdb

Conversation

@lexmarcos

Copy link
Copy Markdown
Owner

No description provided.

lexmarcos and others added 30 commits June 9, 2026 20:52
…sc errors

- Make scannedExistingProduct prop optional in ProductFormProps
- Fix !== null to != null in ExistingProductFoundModal guard
- Recipe A: cast NormalizedOptions in HTTPError constructors
- Recipe B: add error/isValidating to SWR mock returns
- Recipe C: use vi.mocked() for mockClear on plain function types
- Recipe D: narrow Zod safeParse results before helper calls
- Recipe E: add missing view-prop mocks (onNewTransfer, as const, ProductSearchOption)
- Recipe F: align test signatures with current function signatures
- Add 'typecheck' script to package.json
- Add Typecheck step to CI quality workflow
Replace base64 dataUrl strings with native Blob objects in the
InlineProductImageData interface. IndexedDB stores Blobs natively via
structured clone, so the base64 round-trip was unnecessary and cost ~33%
size inflation plus main-thread encode/decode on every draft write.

- Change InlineProductImageData.dataUrl (string) to .blob (Blob)
- Make fileToInlineProductImage synchronous (File IS a Blob)
- Simplify inlineProductImageToFile to wrap blob in File constructor
- Bump STOCK_MOVEMENT_DRAFT_SCHEMA_VERSION 2→3 (old drafts discarded)
- Update Zod schema to validate blob with z.instanceof(Blob)
- Remove window.atob and FileReader usage
- Update all test fixtures and mocks
- Add regression test for malformed blob draft rejection
When scanning a barcode that returns 404 from the product lookup API,
check if the barcode already exists in a pending inline product within
the movement draft before opening the 'missing product' modal.

Previously the scanner only queried the remote API and ignored locally
created inline products, causing a false 'product not found' dialog
even when the product had just been created inline.
Translate English terms to pt-BR across all modules:
- 'batch' -> 'lote' in success/error messages
- 'warehouse/armazém' -> 'estoque' in user-facing messages
- 'Warehouse created/deleted' -> 'Estoque criado/deletado'

Use toast.warning instead of toast.error for non-blocking validation:
- missing warehouse selection
- incomplete custom attributes
- image still processing
- empty cart on checkout
- unsupported browser share
Apply dark brutalist theme to toast notifications:
- Surface #171717 with neutral-800 borders and 4px radius
- Success: emerald #059669 with white text
- Error: rose #E11D48 with white text
- Warning: amber #F59E0B with black text
- Info: blue #2563EB with white text
- Position: top-center
- No box-shadow (consistent with design system)
- Add nuqs ^2.8.9 dependency for URL-based state management
- Wrap RootLayout with NuqsAdapter (Next.js App Router adapter)
- Split ProductFilters into URL-persisted searchQuery (nuqs) and local tableFilters (useState)
- Replace single setFilters with a composed setFilters that routes searchQuery to the URL
- Update direct filter mutations (pagination, sort, KPI clicks) to use setTableFilters
- Reset search query via setSearchQuery in clear/reset handlers
- Wrap test renderHook with NuqsTestingAdapter for test compatibility

Co-Authored-By: Claude <noreply@anthropic.com>
- Add X icon button visible when search query is non-empty
- Add pr-10 right padding on input to accommodate the clear button
- Sets search query to empty string on click

Co-Authored-By: Claude <noreply@anthropic.com>
Replace transient toast notifications with a persistent bottom drawer when a
scanned barcode collides with an inline (new) product already in the movement.

- Add InlineDuplicateWarningDrawer shared component with amber styling
- Add findScannedInlineProductDuplicateWarning guard function + tests
- Replace toast.warning with drawer state in useStockMovementScanner
- Wire inlineDuplicateWarning/onInlineDuplicateWarningOpenChange through
  create-stock-movement model, types, and view
- Use drawer + new guard in useNewProductInlineModel barcode scan handler
- Add guard-on-submit check rejecting duplicate inline barcode on save
- Render InlineDuplicateWarningDrawer in ProductFormShell overlays
- Update tests to assert drawer state instead of toast calls

Co-Authored-By: Claude <noreply@anthropic.com>
Add 'Testes' nav item with ClipboardCheck icon linking to /exploratory-tests.

Co-Authored-By: Claude <noreply@anthropic.com>
…oll logic

Three pages (stock-movement create, new-transfer, product-form) had
identical scroll-driven footer visibility logic duplicated inline.

- Add shouldShowFooter pure function with tests
- Add useFooterVisibility hook (wraps scroll listener + shouldShowFooter)
- Replace inline useState/useRef/useEffect in create-stock-movement,
  new-transfer, and product-form models with the shared hook
- Remove dead shouldShowStockMovementFooter and shouldShowTransferFooter
  exports and their tests
- Add transition-transform + motion-reduce:transition-none to all
  sticky footer bars for smooth show/hide
- Add pointer-events-none when footer is hidden so invisible footer
  doesn't block clicks on content behind it
- Add onInvalidSubmit prop to ProductFormProps (wired later by
  scroll-to-error feature)

Co-Authored-By: Claude <noreply@anthropic.com>
…error

- Extract customAttributeFieldId and findCustomAttributeError from inline
  model into custom-attribute-validation module + tests
- Extract scrollToFieldById and scrollToFirstInvalidField into
  scroll-to-first-invalid-field module + tests
- Replace inline custom attribute validation in useNewProductInlineModel
  with findCustomAttributeError + scrollToFieldById
- Add handleInvalidSubmit callback that scrolls to the first
  react-hook-form invalid field on submit failure (deferred via rAF)
- Wire onInvalidSubmit through product-form via the prop added earlier
- findCustomAttributeError returns structured error {index, field, message}
  instead of raw toast calls, enabling targeted scroll behavior

Co-Authored-By: Claude <noreply@anthropic.com>
Add devOnly flag to NavItem type. Filter out items with devOnly: true
when NODE_ENV is not 'development'. Mark 'Testes' link as devOnly so
the exploratory-tests page is only visible in local dev.

Co-Authored-By: Claude <noreply@anthropic.com>
Collapse the three duplicated cents->BRL formatters (products, sales, batches-detail) into a single lib/currency helper. formatCentsToBRL takes a configurable fallback label ("-" by default, "Sem preco" in products). sales.types and batches-detail re-export it so existing imports stay stable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lib/category-color derives a stable dark (lightness 30%) hex color from a category name for badges, with colocated unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d batch price

The mobile list renders a compact card per product showing its photo (fetched per-product when the warehouse list omits imageUrl), a colored category badge and the latest priced batch's selling price next to stock. Latest-price selection skips price-less batches and guards against invalid createdAt values; warehouse batches no longer revalidate on focus.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dev-only page (404s outside development) tracking manual exploratory test progress in IndexedDB, with an in-memory fallback when IndexedDB is unavailable and per-category grouping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lexmarcos and others added 2 commits June 18, 2026 00:15
Sonner v2 injects [data-sonner-toast][data-styled=true] at runtime, which ties
at specificity 0,2,0 with .toaster .toast-{type}. Since sonner's CSS is injected
later, it wins and backgrounds stay dark.

Prepend [data-sonner-toast] to the type selectors raising specificity to 0,3,0.

Co-Authored-By: Claude <noreply@anthropic.com>
…yle builder

Switch categoryNameToHexColor from dark (lightness 30%) to vibrant (lightness 65%)
colors that read well as text on dark surfaces. Add hexToRgba helper and a new
buildCategoryBadgeStyle() that derives translucent bg/border and solid text from
the same hue, so the badge stays legible without white-on-color guesswork.

Update ProductCardImage to use buildCategoryBadgeStyle instead of inline color.

Co-Authored-By: Claude <noreply@anthropic.com>
@lexmarcos lexmarcos merged commit a4d0908 into main Jun 18, 2026
1 check passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c98c976804

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<div
className={cn(
"fixed bottom-0 left-0 right-0 z-40 border-t border-neutral-800 bg-[#0A0A0A]/95 p-4 backdrop-blur-sm md:ml-[var(--sidebar-width)]",
"fixed bottom-0 left-0 right-0 z-40 border-t border-neutral-800 bg-[#0A0A0A]/95 p-4 backdrop-blur-sm transition-transform duration-200 ease-in-out motion-reduce:transition-none md:ml-[var(--sidebar-width)]",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove animated footer transitions

The repo-level AGENTS.md design system explicitly requires “No animations (instant hover changes)”. Adding transition-transform duration-200 ease-in-out makes this fixed footer animate every time useFooterVisibility hides or shows it while the user scrolls; the same new pattern is also used on the stock-movement and transfer submit bars. Please keep these visibility changes instant to match the documented interaction behavior.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant