Problem
The campaign budget step's validation doesn't catch NaN, letting a broken budget value silently reach the final review screen.
components/campaigns/new/steps/step-budget.tsx:
<input type="number" min={0} value={data.totalBudget || ""}
onChange={(e) => update({ totalBudget: Number(e.target.value) })} .../>
components/dashboard/business/campaign-wizard-modal.tsx:
if (state.budget.totalBudget <= 0) errors.totalBudget = "Budget must be greater than 0.";
Typing a lone - (or any non-numeric string) into the budget field yields Number("-") === NaN. Since NaN <= 0 evaluates to false in JavaScript, this validation is silently bypassed. The input visually clears (NaN || "" renders empty), so it looks like nothing happened — but state.budget.totalBudget is now NaN, and clicking "Next Step" proceeds past step 3 with no error shown.
Concrete failure scenario
- User types
- into "Total Campaign Budget." The field looks empty.
- Validation passes (
NaN <= 0 is false), so "Next Step" advances normally.
- The Review step (
step-review-fund.tsx) renders total.toLocaleString() — showing "NaN" / "≈ $NaN USD" as the amount to lock in escrow, an unmistakably broken value on the last screen before a funding action.
Expected behaviour
Validate with Number.isFinite(state.budget.totalBudget) && state.budget.totalBudget > 0 instead of a bare <= 0 comparison, so non-numeric input is caught with a clear inline error instead of silently passing through as NaN.
Files
components/dashboard/business/campaign-wizard-modal.tsx — validateStep
components/campaigns/new/steps/step-budget.tsx — input handling
Acceptance criteria
Problem
The campaign budget step's validation doesn't catch
NaN, letting a broken budget value silently reach the final review screen.components/campaigns/new/steps/step-budget.tsx:components/dashboard/business/campaign-wizard-modal.tsx:Typing a lone
-(or any non-numeric string) into the budget field yieldsNumber("-") === NaN. SinceNaN <= 0evaluates tofalsein JavaScript, this validation is silently bypassed. The input visually clears (NaN || ""renders empty), so it looks like nothing happened — butstate.budget.totalBudgetis nowNaN, and clicking "Next Step" proceeds past step 3 with no error shown.Concrete failure scenario
-into "Total Campaign Budget." The field looks empty.NaN <= 0isfalse), so "Next Step" advances normally.step-review-fund.tsx) renderstotal.toLocaleString()— showing "NaN" / "≈ $NaN USD" as the amount to lock in escrow, an unmistakably broken value on the last screen before a funding action.Expected behaviour
Validate with
Number.isFinite(state.budget.totalBudget) && state.budget.totalBudget > 0instead of a bare<= 0comparison, so non-numeric input is caught with a clear inline error instead of silently passing through asNaN.Files
components/dashboard/business/campaign-wizard-modal.tsx—validateStepcomponents/campaigns/new/steps/step-budget.tsx— input handlingAcceptance criteria
-) into the budget field produces a visible validation error, not a silent pass-throughNaNtotalBudget