Skip to content

Fix club admin UI styling and add inline member editing#1257

Open
hut8 wants to merge 2 commits intomainfrom
fix/club-admin-ui
Open

Fix club admin UI styling and add inline member editing#1257
hut8 wants to merge 2 commits intomainfrom
fix/club-admin-ui

Conversation

@hut8
Copy link
Copy Markdown
Owner

@hut8 hut8 commented Mar 17, 2026

Summary

  • Fix transparent backgrounds in club admin pages (charges, fees, stripe) by replacing all variant-* Skeleton UI classes with correct preset-* equivalents
  • Fix modal styling — replace broken separate backdrop + absolute-positioned modal pattern with the working fixed inset-0 flex items-center justify-center bg-black/50 overlay pattern
  • Add edit member functionality directly on the Members tab with a PUT /pilots/{id} endpoint, removing the need for a separate admin/users page
  • Remove admin/users page — edit buttons are now shown inline on the members page for club admins only
  • Configure VAPID keys on staging so push notification subscription no longer returns 503

Test plan

  • Visit a club's Charges page → "Create Charge" modal should have a solid card background
  • Visit a club's Fees page → "Add Tier" / "Edit" / "Delete" modals should have solid backgrounds
  • Visit a club's Stripe page → buttons and alerts should be properly styled
  • As a club admin, visit the Members tab → edit (pencil) buttons should appear on each row
  • Click edit on a member → modal opens with pre-filled name and checkboxes, save works
  • Admin dropdown no longer shows "Users" link
  • On staging, "Notify me" button should successfully get VAPID key (no 503)

… add edit member

- Replace all variant-* Skeleton UI classes with correct preset-* equivalents
  across charges, fees, and stripe admin pages (fixes transparent backgrounds)
- Replace broken modal pattern (separate backdrop + absolute positioning) with
  working overlay pattern (fixed inset-0 flex center bg-black/50)
- Add edit member functionality to the members page with PUT /pilots/{id} endpoint
- Remove separate admin/users page; edit buttons shown inline for club admins
- Add UpdatePilotRequest type and update_pilot repo method for pilot qualifications
Copilot AI review requested due to automatic review settings March 17, 2026 14:45
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

This PR consolidates club member management by adding inline edit functionality to the Members tab, removing the separate admin/users page. It also fixes Skeleton UI styling across club admin pages by migrating from deprecated variant-* classes to preset-* equivalents and replacing a broken custom modal pattern with a consistent fixed inset-0 overlay approach.

Changes:

  • Add PUT /pilots/{id} backend endpoint with club admin authorization, and corresponding inline edit modal on the Members tab
  • Replace all variant-* Skeleton UI classes with preset-* equivalents and replace custom CSS modal pattern with accessible overlay pattern across charges, fees, and stripe pages
  • Remove the standalone admin/users page and its navigation link, restricting add/edit member actions to club admins only

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/users.rs Add UpdatePilotRequest struct with optional fields
src/users_repo.rs Add update_pilot repository method using Diesel
src/actions/users.rs Add update_pilot handler with club admin authorization
src/web.rs Register PUT /pilots/{id} route
web/src/routes/clubs/[id]/members/+page.svelte Add edit modal, restrict add/edit to club admins
web/src/routes/clubs/[id]/+layout.svelte Remove "Users" admin sub-item
web/src/routes/clubs/[id]/admin/users/+page.svelte Delete standalone users page
web/src/routes/clubs/[id]/admin/users/+page.ts Delete standalone users page loader
web/src/routes/clubs/[id]/admin/charges/+page.svelte Fix styling classes and modal pattern
web/src/routes/clubs/[id]/admin/fees/+page.svelte Fix styling classes and modal pattern
web/src/routes/clubs/[id]/admin/stripe/+page.svelte Fix styling classes

You can also share your feedback on Copilot code review. Take the survey.

aria-labelledby="create-charge-heading"
tabindex="-1"
>
<h3 class="mb-4 h3">Create Charge</h3>
Comment thread src/users_repo.rs Outdated
Comment on lines +576 to +594
diesel::update(users::table.filter(users::id.eq(user_id)))
.set((
users::first_name.eq(request_clone.first_name.unwrap_or(current.first_name)),
users::last_name.eq(request_clone.last_name.unwrap_or(current.last_name)),
users::is_licensed.eq(request_clone.is_licensed.unwrap_or(current.is_licensed)),
users::is_instructor
.eq(request_clone.is_instructor.unwrap_or(current.is_instructor)),
users::is_tow_pilot
.eq(request_clone.is_tow_pilot.unwrap_or(current.is_tow_pilot)),
users::is_examiner.eq(request_clone.is_examiner.unwrap_or(current.is_examiner)),
users::updated_at.eq(now),
))
.execute(&mut conn)?;

let updated = users::table
.filter(users::id.eq(user_id))
.first::<UserRecord>(&mut conn)
.optional()?;
Ok(updated.map(|r| r.into()))
- Add missing id="create-charge-heading" on the charge modal heading
  so aria-labelledby resolves correctly for screen readers
- Use get_result on the diesel update call in update_pilot to combine
  UPDATE + SELECT into one round-trip instead of three separate queries
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

This PR updates the club admin experience by fixing Skeleton UI styling issues (variants → presets), standardizing modal overlays, and adding inline member editing on the club Members tab via a new PUT /pilots/{id} endpoint (removing the legacy admin/users page).

Changes:

  • Replace broken variant-* Skeleton classes with preset-* equivalents across club admin pages.
  • Replace the legacy backdrop/modal pattern with a fixed full-screen overlay modal pattern for charges/fees (and add an edit modal on members).
  • Add backend + frontend support for inline member editing and remove the /admin/users route and nav item.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
web/src/routes/clubs/[id]/members/+page.svelte Adds inline edit UI + modal and restricts add/edit actions to club admins.
web/src/routes/clubs/[id]/admin/users/+page.ts Removes legacy users admin page load guard.
web/src/routes/clubs/[id]/admin/users/+page.svelte Removes legacy users admin page UI (superseded by inline edit on Members tab).
web/src/routes/clubs/[id]/admin/stripe/+page.svelte Updates styling classes to preset-* variants.
web/src/routes/clubs/[id]/admin/fees/+page.svelte Updates styling classes and replaces modal implementation with overlay pattern.
web/src/routes/clubs/[id]/admin/charges/+page.svelte Updates styling classes and replaces modal implementation with overlay pattern.
web/src/routes/clubs/[id]/+layout.svelte Removes “Users” link from the admin submenu.
src/web.rs Registers PUT /pilots/{id} route.
src/users_repo.rs Adds UsersRepository::update_pilot DB update method.
src/users.rs Adds UpdatePilotRequest payload type.
src/actions/users.rs Adds update_pilot handler with club-admin/site-admin authorization checks.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/users_repo.rs
Comment on lines +576 to +588
let updated = diesel::update(users::table.filter(users::id.eq(user_id)))
.set((
users::first_name.eq(request_clone.first_name.unwrap_or(current.first_name)),
users::last_name.eq(request_clone.last_name.unwrap_or(current.last_name)),
users::is_licensed.eq(request_clone.is_licensed.unwrap_or(current.is_licensed)),
users::is_instructor
.eq(request_clone.is_instructor.unwrap_or(current.is_instructor)),
users::is_tow_pilot
.eq(request_clone.is_tow_pilot.unwrap_or(current.is_tow_pilot)),
users::is_examiner.eq(request_clone.is_examiner.unwrap_or(current.is_examiner)),
users::updated_at.eq(now),
))
.get_result::<UserRecord>(&mut conn)?;
<button
onclick={() => openEditModal(member)}
class="preset-tonal-surface-500 btn btn-sm"
title="Edit member"
Comment on lines +479 to +482
onclick={closeEditModal}
role="button"
tabindex="0"
onkeydown={(e) => e.key === 'Escape' && closeEditModal()}
<div
class="m-4 w-full max-w-md card p-6"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
Comment thread src/users.rs
Comment on lines +125 to +129
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdatePilotRequest {
pub first_name: Option<String>,
pub last_name: Option<String>,
<button
onclick={() => openEditModal(member)}
class="preset-tonal-surface-500 btn btn-sm"
title="Edit member"
<div
class="m-4 w-full max-w-md space-y-4 card p-6"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
<div
class="m-4 w-full max-w-md card p-6"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
<div
class="m-4 w-full max-w-md card p-6"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
<div
class="m-4 w-full max-w-md card p-6"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
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