Skip to content

Conversation

@niko-exo
Copy link

@niko-exo niko-exo commented Jan 22, 2026

ref: https://app.clickup.com/t/86b883b71

86b883b71 - Add Numeric Validation for Quantities Fields

Changelog

  • Add MuiFormikQuantityField
  • Unit tests
  • Use new component on forms.

Links

86b883b71 - Add Numeric Validation for Quantities Fields

Evidence

Captura de pantalla de 2026-01-22 16-25-14 Captura de pantalla de 2026-01-22 16-24-34

Summary by CodeRabbit

  • New Features

    • Added a reusable numeric quantity input that accepts only numbers and filters invalid characters.
    • Replaced quantity fields across sponsor forms and inventory popups with the new numeric input for consistent behavior.
  • Improvements

    • Made the default quantity field required, enforcing validation and preventing empty submissions.
  • Tests

    • Added tests verifying numeric input acceptance, filtering of invalid characters, and correct form submission.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

Adds a new reusable MuiFormikQuantityField component that restricts non-numeric key input and enforces min=0, adds tests for its behavior, and replaces three existing quantity fields with this component in two sponsor-related form files.

Changes

Cohort / File(s) Summary
Component Definition
src/components/mui/formik-inputs/mui-formik-quantity-field.js
New default-exported component wrapping MuiFormikTextField, sets type="number", blocks keys ["e","E","+","-"] via onKeyDown, and applies inputProps (e.g., min: 0). Declares PropTypes name (required) and label.
Component Tests
src/components/mui/__tests__/mui-formik-quantity-field.test.js
New test file: renders the field within Formik, asserts numeric input submission (e.g., typing "12345") and filtering of invalid characters (typing "123eEe45" submits 12345).
Form Field Migrations
src/pages/sponsors-global/form-templates/sponsor-inventory-popup.js, src/pages/sponsors/sponsor-form-item-list-page/components/sponsor-form-item-form.js
Replaced three quantity-related fields (default_quantity, quantity_limit_per_sponsor, quantity_limit_per_show) from MuiFormikTextField to MuiFormikQuantityField; made default_quantity required in validation in sponsor form item file.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • smarcet

Poem

🐰 I hop in fields of numbers bright,
I guard against an "e" at night,
I nudge each digit to behave,
From zero up I gently save,
Hooray — clean counts, all set just right! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: introducing numeric validation for quantity fields across the codebase by adding a new component and replacing existing fields.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/mui/formik-inputs/mui-formik-quantity-field.js`:
- Around line 7-19: The onKeyDown filter in MuiFormikQuantityField prevents
blocked keys (BLOCKED_KEYS) but paste and drop can still inject
scientific-notation characters; update the MuiFormikQuantityField props passed
to MuiFormikTextField to add onPaste and onDrop handlers that inspect the
pasted/dropped string and if it contains any BLOCKED_KEYS characters or
scientific-notation patterns (e or E with optional sign) call preventDefault()
and stopImmediatePropagation(), otherwise allow the input; reference the
component name MuiFormikQuantityField, the child MuiFormikTextField and the
BLOCKED_KEYS constant when making the change.

In `@src/utils/yup.js`:
- Around line 56-61: The quantityValidation() schema currently uses
yup.number().positive() which rejects 0 and allows decimals, creating a mismatch
with the UI (min: 0) and other validators; replace its implementation to use the
shared positiveNumberValidation() helper (the same used by
quantity_limit_per_sponsor and quantity_limit_per_show) so it enforces integer
and min(0) semantics consistent with the UI and other validators; locate and
swap the body of quantityValidation to delegate to positiveNumberValidation() or
mirror its .integer().min(0) rules and reuse the existing translation keys for
error messages.
♻️ Duplicate comments (1)
src/pages/sponsors/sponsor-form-item-list-page/components/sponsor-form-item-form.js (1)

36-48: Use of quantityValidation inherits the validator semantics.

See the note on quantityValidation in src/utils/yup.js; the same 0/decimal vs integer concern applies here.

🧹 Nitpick comments (1)
src/pages/sponsors/sponsor-form-item-list-page/components/sponsor-form-item-form.js (1)

124-155: Avoid overriding MuiFormikQuantityField defaults.

Passing type and inputProps here overrides the component’s inputMode and duplicates its own defaults. Consider relying on the wrapper or explicitly merging inputProps.

♻️ Streamlined usage
               <MuiFormikQuantityField
                 name="quantity_limit_per_show"
                 label={T.translate(
                   "sponsor_form_item_list.edit_item.quantity_limit_per_show"
                 )}
                 fullWidth
-                type="number"
-                inputProps={{ min: 0 }}
               />
...
               <MuiFormikQuantityField
                 name="quantity_limit_per_sponsor"
                 label={T.translate(
                   "sponsor_form_item_list.edit_item.quantity_limit_per_sponsor"
                 )}
                 fullWidth
-                type="number"
-                inputProps={{ min: 0 }}
               />
...
               <MuiFormikQuantityField
                 name="default_quantity"
                 label={T.translate(
                   "sponsor_form_item_list.edit_item.default_quantity"
                 )}
                 fullWidth
-                type="number"
-                inputProps={{ min: 0 }}
                 required
               />

@fntechgit fntechgit deleted a comment from coderabbitai bot Jan 22, 2026
@fntechgit fntechgit deleted a comment from coderabbitai bot Jan 22, 2026
Copy link

@smarcet smarcet left a comment

Choose a reason for hiding this comment

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

@niko-exo please review comments

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/components/mui/formik-inputs/mui-formik-quantity-field.js`:
- Around line 16-21: The component currently spreads {...props} after passing
inputProps={{ min: 0, inputMode: "numeric" }}, which allows a consumer-provided
inputProps to fully overwrite those defaults; update the component to
destructure inputProps from props (e.g., const { inputProps: userInputProps,
...rest } = props) and merge them with the defaults (preserving min: 0 and
inputMode: "numeric") before spreading the rest of props and the merged
inputProps into the input; reference the existing inputProps usage and the props
spread in mui-formik-quantity-field.js to locate where to perform the merge.
🧹 Nitpick comments (2)
src/components/mui/formik-inputs/mui-formik-quantity-field.js (2)

5-5: Consider blocking the decimal point for integer quantities.

The current BLOCKED_KEYS prevents scientific notation and signs, but still allows . for decimal input. If quantities should be integers (which is typical for inventory counts), consider adding "." to the blocked keys.

🔧 Suggested change
-const BLOCKED_KEYS = ["e", "E", "+", "-"];
+const BLOCKED_KEYS = ["e", "E", "+", "-", "."];

10-14: Simplify to use synthetic event's preventDefault().

Using e.nativeEvent.preventDefault() and stopImmediatePropagation() is unconventional. For blocking key input, e.preventDefault() on the synthetic event is sufficient—stopImmediatePropagation() is unnecessary here.

♻️ Suggested simplification
     onKeyDown={(e) => {
       if (BLOCKED_KEYS.includes(e.key)) {
-        e.nativeEvent.preventDefault();
-        e.nativeEvent.stopImmediatePropagation();
+        e.preventDefault();
       }
     }}

Comment on lines +16 to +21
inputProps={{
min: 0,
inputMode: "numeric"
}}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Props spread can silently override inputProps, losing min and inputMode.

If a consumer passes inputProps={{ max: 100 }}, it will completely replace the component's inputProps, losing min: 0 and inputMode: "numeric". Consider destructuring inputProps and merging it.

🔧 Suggested fix
-const MuiFormikQuantityField = ({ ...props }) => (
+const MuiFormikQuantityField = ({ inputProps: customInputProps, ...props }) => (
   <MuiFormikTextField
     type="number"
     onKeyDown={(e) => {
       if (BLOCKED_KEYS.includes(e.key)) {
-        e.nativeEvent.preventDefault();
-        e.nativeEvent.stopImmediatePropagation();
+        e.preventDefault();
       }
     }}
     inputProps={{
       min: 0,
-      inputMode: "numeric"
+      inputMode: "numeric",
+      ...customInputProps
     }}
     // eslint-disable-next-line react/jsx-props-no-spreading
     {...props}
   />
 );
🤖 Prompt for AI Agents
In `@src/components/mui/formik-inputs/mui-formik-quantity-field.js` around lines
16 - 21, The component currently spreads {...props} after passing inputProps={{
min: 0, inputMode: "numeric" }}, which allows a consumer-provided inputProps to
fully overwrite those defaults; update the component to destructure inputProps
from props (e.g., const { inputProps: userInputProps, ...rest } = props) and
merge them with the defaults (preserving min: 0 and inputMode: "numeric") before
spreading the rest of props and the merged inputProps into the input; reference
the existing inputProps usage and the props spread in
mui-formik-quantity-field.js to locate where to perform the merge.

@niko-exo niko-exo requested review from romanetar and smarcet January 23, 2026 17:07
@niko-exo
Copy link
Author

Ready for review!

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.

4 participants