Skip to content

Comments

Added set current button and fixed validation issues on create campaign page#586

Merged
aunali8812 merged 3 commits intostagingfrom
fix/campaign-form-validation
Feb 19, 2026
Merged

Added set current button and fixed validation issues on create campaign page#586
aunali8812 merged 3 commits intostagingfrom
fix/campaign-form-validation

Conversation

@aunali8812
Copy link
Collaborator

@aunali8812 aunali8812 commented Feb 15, 2026

Summary by CodeRabbit

  • New Features

    • Added a "Set to current" button in campaign creation to quickly set the start date to the current time.
  • Bug Fixes / Improvements

    • Validation now accepts timestamps that are up to one minute in the past, avoiding false "past date" errors.
    • Validation errors in the campaign editor now list all field errors together for clearer feedback.
    • New campaigns can be submitted without requiring prior edits; submit/disable behavior refined for create vs update flows.

@aunali8812 aunali8812 requested a review from Ebube111 as a code owner February 15, 2026 13:24
@vercel
Copy link

vercel bot commented Feb 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
potlock-next-app Ready Ready Preview, Comment Feb 16, 2026 5:01pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 15, 2026

Walkthrough

The PR widens the futureTimestamp boundary by 60 seconds, adds a "Set to current" start-date action and aggregated error handling in the campaign editor, and relaxes the form hook's isDisabled check to allow new campaigns to submit even when not dirty.

Changes

Cohort / File(s) Summary
DateTime validation
src/common/lib/datetime.ts
Changed futureTimestamp boundary to accept timestamps up to 60 seconds in the past (widens non-past window).
Campaign editor (UI, validation, submit)
src/entities/campaign/components/editor.tsx
Added "Set to current" button + handleStartNow; mark start_ms/end_ms updates with shouldDirty: true; replaced single error flag with fieldErrorMessages array; switched to form.handleSubmit(...); adjusted submit-button disable logic and error summary rendering.
Campaign form hook
src/entities/campaign/hooks/forms.ts
Updated isDisabled computation to allow new campaigns to submit regardless of dirty state; added isNewCampaign to dependencies.

Sequence Diagram(s)

sequenceDiagram
    participant User as "User"
    participant Editor as "CampaignEditor"
    participant Hook as "useCampaignForm"
    participant DateUtil as "datetime.ts"
    participant Validator as "react-hook-form"

    User->>Editor: Click "Set to current"
    Editor->>DateUtil: request now + 1 minute
    DateUtil-->>Editor: timestamp
    Editor->>Hook: form.setValue('start_ms', timestamp, { shouldDirty: true })
    Hook->>Validator: trigger validation for start_ms
    Validator-->>Hook: validation result
    alt valid
      User->>Editor: Submit form
      Editor->>Validator: form.handleSubmit(values)
      Validator-->>Editor: validated values
      Editor->>Server: send payload (includes start_ms)
    else invalid
      Validator-->>Editor: fieldErrorMessages
      Editor-->>User: display aggregated errors
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • Ebube111
  • carina-akaia

Poem

🐰 I nudged the clock an extra beat so kind,
A button whispers "now" — no time left behind,
Errors gather in a neat little row,
Forms hop forward, ready to go! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (10 files):

⚔️ src/common/api/indexer/sync.ts (content)
⚔️ src/common/lib/datetime.ts (content)
⚔️ src/entities/campaign/components/editor.tsx (content)
⚔️ src/entities/campaign/hooks/forms.ts (content)
⚔️ src/entities/pot/hooks/forms.ts (content)
⚔️ src/features/donation/models/effects/index.ts (content)
⚔️ src/features/pot-application/hooks/forms.ts (content)
⚔️ src/features/pot-configuration/model/effects.ts (content)
⚔️ src/features/proportional-funding/model/effects.ts (content)
⚔️ src/pages/campaigns.tsx (content)

These conflicts must be resolved before merging into staging.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: introducing a 'Set to current' button for campaign creation and fixing validation issues on the create campaign form.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/campaign-form-validation
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch fix/campaign-form-validation
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@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/entities/campaign/components/editor.tsx`:
- Around line 885-889: The submit Button currently sets disabled based on
isUpdate ? isDisabled : form.formState.isSubmitting which bypasses the shared
isDisabled hook in create mode; change the Button's disabled prop to always use
isDisabled (remove the ternary) so both create and update flows respect the
isDisabled logic (which already considers isValid, isSubmitting, token loading,
etc.) — update the Button element in editor.tsx (the one with props
variant="brand-filled" and type="submit") to use disabled={isDisabled}.
🧹 Nitpick comments (1)
src/common/lib/datetime.ts (1)

101-104: Reasonable grace window, but document the rationale.

The 60-second tolerance aligns with the editor's +1 minute buffer in handleStartNow / handleStartDateChange, preventing race conditions where a few seconds elapse between user selection and server-side validation. Consider adding a brief inline comment explaining why 60 seconds was chosen (e.g., to match the UI's 1-minute buffer), so future maintainers don't tighten or widen this arbitrarily.

Copy link
Contributor

@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/entities/campaign/components/editor.tsx`:
- Around line 156-160: handleStartNow currently updates only "start_ms" which
can leave "end_ms" stale and un-validated; after calling
form.setValue("start_ms", ...), also trigger re-validation of the end date (for
example call form.trigger("end_ms") or otherwise validate the "end_ms" field) so
any end-before-start errors surface immediately; update the handleStartNow
function to set start_ms as it does and then call form.trigger("end_ms") (or
trigger full form validation) to ensure the end date is re-checked.
🧹 Nitpick comments (1)
src/entities/campaign/components/editor.tsx (1)

96-102: Minor: correctedTime duplicates minTime.

Both compute Temporal.Now.instant().add({ minutes: 1 }).epochMilliseconds. You can reuse minTime directly.

Suggested diff
     if (selectedTime < minTime) {
-      // Auto-correct to minimum valid time (silently)
-      const correctedTime = Temporal.Now.instant().add({ minutes: 1 }).epochMilliseconds;
-      form.setValue("start_ms", correctedTime, { shouldValidate, shouldDirty: true });
+      form.setValue("start_ms", minTime, { shouldValidate, shouldDirty: true });
     } else {

Comment on lines +156 to +160
// "Set to current" — sets start date to right now
const handleStartNow = () => {
const startEpoch = Temporal.Now.instant().add({ minutes: 1 }).epochMilliseconds;
form.setValue("start_ms", startEpoch, { shouldDirty: true, shouldValidate: true });
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

handleStartNow doesn't trigger re-validation of end_ms.

If the user has already picked an end date and then clicks "Set to current", the new start_ms could land after end_ms. Since only start_ms is set here, end_ms won't be re-validated, potentially leaving the form in an inconsistent state with no visible error.

Consider triggering end_ms validation as well:

Suggested addition
  const handleStartNow = () => {
    const startEpoch = Temporal.Now.instant().add({ minutes: 1 }).epochMilliseconds;
    form.setValue("start_ms", startEpoch, { shouldDirty: true, shouldValidate: true });
+   // Re-validate end date in case it's now before the new start
+   const endMs = form.getValues("end_ms");
+   if (endMs !== undefined) {
+     form.trigger("end_ms");
+   }
  };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// "Set to current" — sets start date to right now
const handleStartNow = () => {
const startEpoch = Temporal.Now.instant().add({ minutes: 1 }).epochMilliseconds;
form.setValue("start_ms", startEpoch, { shouldDirty: true, shouldValidate: true });
};
// "Set to current" — sets start date to right now
const handleStartNow = () => {
const startEpoch = Temporal.Now.instant().add({ minutes: 1 }).epochMilliseconds;
form.setValue("start_ms", startEpoch, { shouldDirty: true, shouldValidate: true });
// Re-validate end date in case it's now before the new start
const endMs = form.getValues("end_ms");
if (endMs !== undefined) {
form.trigger("end_ms");
}
};
🤖 Prompt for AI Agents
In `@src/entities/campaign/components/editor.tsx` around lines 156 - 160,
handleStartNow currently updates only "start_ms" which can leave "end_ms" stale
and un-validated; after calling form.setValue("start_ms", ...), also trigger
re-validation of the end date (for example call form.trigger("end_ms") or
otherwise validate the "end_ms" field) so any end-before-start errors surface
immediately; update the handleStartNow function to set start_ms as it does and
then call form.trigger("end_ms") (or trigger full form validation) to ensure the
end date is re-checked.

@aunali8812 aunali8812 merged commit 4a2d403 into staging Feb 19, 2026
3 of 4 checks passed
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