Skip to content

feat(wave-admin): UI for managing waves; split current/upcoming display#1909

Open
efstajas wants to merge 1 commit into
mainfrom
admin/manage-waves-ui
Open

feat(wave-admin): UI for managing waves; split current/upcoming display#1909
efstajas wants to merge 1 commit into
mainfrom
admin/manage-waves-ui

Conversation

@efstajas
Copy link
Copy Markdown
Contributor

Summary

Front-end for the new wave-admin endpoints (see matching wave PR: drips-network/wave#624), plus a small fix to the public wave program page so a current wave and an upcoming wave can both show at the same time.

Admin

  • New "Waves" card on /wave/admin (gated on manageWaves).
  • /wave/admin/waves — lists wave programs with a "Manage Waves" link each.
  • /wave/admin/waves/[waveProgramId] — lists scheduled waves with status badges and per-row actions:
    • Schedule wave (header action) opens a modal with start/end dates and a budget input pre-filled from the program's preset.
    • Edit (upcoming) opens the edit modal with all fields editable.
    • Extend (active) reuses the edit modal but locks start date + budget; end-date picker is clamped via `min` to the current end and validates inline.
    • Delete (upcoming only) — destructive variant, behind a confirmation modal + standard error-modal wrapper.
    • Ended waves are read-only — no actions.
  • New API client helpers in `wavePrograms.ts`: `manualCreateWave`, `updateWave`, `deleteWave`.

Public wave program page

  • Previously: `upcomingWave ?? activeWave` collapsed both into one slot, so a program with both an active wave and an upcoming wave showed only the upcoming one.
  • Now: separate "Current Wave" and "Upcoming Waves" sections.
  • Upcoming section is hidden when there's a current wave but nothing scheduled (matches the user's preference — no noisy "nothing here" card alongside the live wave).
  • The existing newsletter/Discord empty state is preserved for the no-active + no-upcoming case.

Test plan

  • As a user with the `manageWaves` permission, open `/wave/admin` and confirm the new "Waves" card appears.
  • As a user without it, confirm the card does not appear and `/wave/admin/waves` redirects to `/wave/admin`.
  • Schedule a new wave — confirm 201 and that it appears in the list with status "upcoming".
  • Edit an upcoming wave — change start date, end date, budget independently.
  • Try to edit an active wave — confirm start + budget are disabled, end-date picker cannot select a date earlier than the current end.
  • Try to edit an ended wave — confirm no edit button shows.
  • Delete an upcoming wave — confirmation, success toast, list refresh.
  • Confirm no delete button on active / ended waves.
  • Public page: navigate to a wave program with an active wave but no upcoming → only "Current Wave" shows.
  • Public page: with active and upcoming → both sections show, current on top.
  • Public page: with no active or upcoming → the newsletter/Discord empty state still renders.

…ve display

- Admin dashboard: new "Waves" card (gated on manageWaves) linking to
  /wave/admin/waves, listing all wave programs.
- Per-program admin page: list scheduled waves with status badges, schedule
  new waves, edit upcoming ones, extend active ones (start/budget locked),
  and delete upcoming waves (with confirmation). Ended waves are read-only.
- Wave program public page: split into separate "Current Wave" and
  "Upcoming Waves" sections so a current+upcoming combo renders both;
  upcoming section hides entirely when there's a current wave but nothing
  scheduled, and keeps the newsletter/Discord empty state when neither
  exists.
- API client: add manualCreateWave, updateWave, and deleteWave helpers.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds wave administration UI (new admin routes + modals) backed by new wavePrograms client helpers, and updates the public wave program page to display current and upcoming waves simultaneously.

Changes:

  • Added /wave/admin/waves and /wave/admin/waves/[waveProgramId] pages for listing wave programs and managing scheduled waves (create/edit/extend/delete).
  • Introduced create/edit wave modals and new wavePrograms.ts helpers (manualCreateWave, updateWave, deleteWave).
  • Updated public wave program page to render separate “Current Wave” and “Upcoming Waves” sections (instead of collapsing to one).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/routes/(pages)/wave/(base-layout)/admin/waves/+page.ts Loads wave programs for the new admin waves list route with permission gating.
src/routes/(pages)/wave/(base-layout)/admin/waves/+page.svelte Renders wave program list UI and refresh action.
src/routes/(pages)/wave/(base-layout)/admin/waves/[waveProgramId]/+page.ts Loads a specific wave program + waves list with permission gating and sorting.
src/routes/(pages)/wave/(base-layout)/admin/waves/[waveProgramId]/+page.svelte Renders waves table with status, edit/extend actions, and delete flow.
src/routes/(pages)/wave/(base-layout)/admin/waves/[waveProgramId]/components/create-wave-modal.svelte Modal UI/validation for scheduling a new wave.
src/routes/(pages)/wave/(base-layout)/admin/waves/[waveProgramId]/components/edit-wave-modal.svelte Modal UI/validation for editing upcoming waves and extending active waves.
src/routes/(pages)/wave/(base-layout)/admin/+page.svelte Adds the new “Waves” admin card gated by manageWaves.
src/routes/(pages)/wave/(base-layout)/[waveProgramSlug]/+page.svelte Splits public display into separate current/upcoming/past wave sections.
src/lib/utils/wave/wavePrograms.ts Adds client helpers for manual create, update, and delete wave endpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +248 to +252
export async function deleteWave(f = fetch, waveProgramId: string, waveId: string) {
await authenticatedCall(f, `/api/wave-programs/${waveProgramId}/waves/${waveId}`, {
method: 'DELETE',
});
}
Comment on lines +34 to +40
const budgetValidationState = $derived.by(() => {
if (budgetUSD.length === 0) return undefined;
if (!BUDGET_PATTERN.test(budgetUSD)) {
return { type: 'invalid' as const, message: 'Must be a decimal number, e.g. "50000.00".' };
}
return { type: 'valid' as const };
});
Comment on lines +69 to +75
const budgetValidationState = $derived.by(() => {
if (budgetUSD.length === 0) return undefined;
if (!BUDGET_PATTERN.test(budgetUSD)) {
return { type: 'invalid' as const, message: 'Must be a decimal number, e.g. "50000.00".' };
}
return { type: 'valid' as const };
});
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.

2 participants