Conversation
…can and allow adding batch
… search, scanner, and helper functions
…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>
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>
There was a problem hiding this comment.
💡 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)]", |
There was a problem hiding this comment.
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 👍 / 👎.
No description provided.