Add Commerce admin page for jersey/subscription/contract visibility #226

Closed
opened 2026-04-06 19:51:44 +00:00 by forgejo_admin · 3 comments
Contributor

Type

Feature

Lineage

Downstream of forgejo_admin/westside-playground#50 (playground prototype). This ticket promotes the approved design to production Svelte.

Repo

forgejo_admin/westside-landing

User Story

As Marcus (admin)
I want a dedicated Commerce page in the admin nav
So that I can quickly see jersey orders, subscription status, and contract status without digging through individual player cards.

Maps to story:WS-S9 — "As an admin, I want to track payment status per player so that I know who owes what."

Context

The playground prototype (westside-playground#50, commerce.html) is approved with full @-comment spec defining exact columns, filters, summary counts, and DB field mappings for each tab. This ticket promotes that design to production Svelte.

Implementation contract: westside-playground#50 commerce.html @-comment spec defines:

  • 3 tabs (Jerseys, Subscriptions, Contracts)
  • Summary stat cards per tab with color-coded counts
  • Filter buttons per tab narrowing table rows by status
  • Full DB field coverage (jersey_option, jersey_size, jersey_number, jersey_order_status, subscription_status, monthly_fee, contract_status, contract_signed_at, contract_signed_by)

No new API endpoints needed. GET /admin/players already returns all commerce fields (added in basketball-api PR #250). Aggregate client-side with $derived. Consistent with how every other admin page works (adapter-static, onMount + apiFetch pattern).

Upstream gate: Board item #865 (playground spec) must be in done before this ticket moves to in_progress.

File Targets

Files the agent should modify or create:

  • src/routes/(app)/admin/commerce/+page.svelte — new Commerce page promoted from playground. Copy HTML body structure from commerce.html, replace mock data with onMount + apiFetch('/admin/players'), replace hardcoded counts with $derived aggregations, replace data-filter JS with Svelte reactive filtering.
  • src/routes/(app)/+layout.svelte lines 106-126 — insert Commerce nav item between CRM (line 114) and Teams (line 115): <a href="/admin/commerce" class:active={currentPath === '/admin/commerce'}><span class="nav-icon">&#36;</span>Commerce</a>

Files the agent should NOT touch:

  • src/routes/(app)/admin/players/+page.svelte — CRM page stays as-is
  • src/app.css — commerce CSS already exists in shared/style.css, copy it to app.css if not already present
  • Any backend/API code — no new endpoints needed

Acceptance Criteria

  • Admin nav shows: Dashboard | CRM | Commerce | Teams | Schedule
  • Commerce page has three tabs: Jerseys, Subscriptions, Contracts
  • Jerseys tab shows table with: player name, team, jersey option, size, number, order status. Summary counts computed from real data. Filterable by status (all, paid, pending, shipped, none).
  • Subscriptions tab shows table with: player name, team, monthly fee, subscription status, parent name, parent contact. Summary counts computed from real data. Filterable by status (all, active, past_due, canceled).
  • Contracts tab shows table with: player name, team, contract status, signed date, signed by, parent name. Summary counts computed from real data. Filterable by status (all, signed, offered, none).
  • Page uses existing apiFetch('/admin/players') — no new API calls
  • Aggregation done client-side with $derived state
  • Page renders correctly on mobile — verify 5th bottom-nav item (Commerce) spacing at 320px viewport

Test Expectations

  • No unit tests needed — frontend-only, adapter-static
  • Manual validation: log in as Marcus, navigate to Commerce, verify all three tabs render correct data matching real DB
  • Verify bottom nav doesn't overflow on narrow mobile (320px)
  • Run command: npm run build to verify no build errors

Constraints

  • Follow existing admin page patterns (onMount + apiFetch, no SSR)
  • Match existing admin CSS/styling — commerce CSS classes already in shared/style.css
  • Use $state and $derived (Svelte 5 runes) — consistent with other admin pages
  • No Tailwind — pure CSS vars + explicit styles per project convention
  • No scoped Svelte <style> blocks — all CSS stays in global app.css per SOP

Checklist

  • PR opened
  • Build passes
  • No unrelated changes
  • forgejo_admin/westside-playground#50 — upstream playground prototype with @-comment spec
  • sop-capacitor-mobile-lifecycle — playground-to-Svelte promotion SOP
  • project-westside-basketball — westside project page with user stories
### Type Feature ### Lineage Downstream of `forgejo_admin/westside-playground#50` (playground prototype). This ticket promotes the approved design to production Svelte. ### Repo `forgejo_admin/westside-landing` ### User Story As Marcus (admin) I want a dedicated Commerce page in the admin nav So that I can quickly see jersey orders, subscription status, and contract status without digging through individual player cards. Maps to `story:WS-S9` — "As an admin, I want to track payment status per player so that I know who owes what." ### Context The playground prototype (`westside-playground#50`, `commerce.html`) is approved with full @-comment spec defining exact columns, filters, summary counts, and DB field mappings for each tab. This ticket promotes that design to production Svelte. **Implementation contract:** `westside-playground#50` commerce.html @-comment spec defines: - 3 tabs (Jerseys, Subscriptions, Contracts) - Summary stat cards per tab with color-coded counts - Filter buttons per tab narrowing table rows by status - Full DB field coverage (jersey_option, jersey_size, jersey_number, jersey_order_status, subscription_status, monthly_fee, contract_status, contract_signed_at, contract_signed_by) No new API endpoints needed. `GET /admin/players` already returns all commerce fields (added in basketball-api PR #250). Aggregate client-side with `$derived`. Consistent with how every other admin page works (adapter-static, onMount + apiFetch pattern). **Upstream gate:** Board item #865 (playground spec) must be in `done` before this ticket moves to `in_progress`. ### File Targets Files the agent should modify or create: - `src/routes/(app)/admin/commerce/+page.svelte` — new Commerce page promoted from playground. Copy HTML body structure from commerce.html, replace mock data with `onMount` + `apiFetch('/admin/players')`, replace hardcoded counts with `$derived` aggregations, replace data-filter JS with Svelte reactive filtering. - `src/routes/(app)/+layout.svelte` lines 106-126 — insert Commerce nav item between CRM (line 114) and Teams (line 115): `<a href="/admin/commerce" class:active={currentPath === '/admin/commerce'}><span class="nav-icon">&#36;</span>Commerce</a>` Files the agent should NOT touch: - `src/routes/(app)/admin/players/+page.svelte` — CRM page stays as-is - `src/app.css` — commerce CSS already exists in shared/style.css, copy it to app.css if not already present - Any backend/API code — no new endpoints needed ### Acceptance Criteria - [ ] Admin nav shows: Dashboard | CRM | Commerce | Teams | Schedule - [ ] Commerce page has three tabs: Jerseys, Subscriptions, Contracts - [ ] Jerseys tab shows table with: player name, team, jersey option, size, number, order status. Summary counts computed from real data. Filterable by status (all, paid, pending, shipped, none). - [ ] Subscriptions tab shows table with: player name, team, monthly fee, subscription status, parent name, parent contact. Summary counts computed from real data. Filterable by status (all, active, past_due, canceled). - [ ] Contracts tab shows table with: player name, team, contract status, signed date, signed by, parent name. Summary counts computed from real data. Filterable by status (all, signed, offered, none). - [ ] Page uses existing `apiFetch('/admin/players')` — no new API calls - [ ] Aggregation done client-side with `$derived` state - [ ] Page renders correctly on mobile — verify 5th bottom-nav item (Commerce) spacing at 320px viewport ### Test Expectations - [ ] No unit tests needed — frontend-only, adapter-static - [ ] Manual validation: log in as Marcus, navigate to Commerce, verify all three tabs render correct data matching real DB - [ ] Verify bottom nav doesn't overflow on narrow mobile (320px) - Run command: `npm run build` to verify no build errors ### Constraints - Follow existing admin page patterns (onMount + apiFetch, no SSR) - Match existing admin CSS/styling — commerce CSS classes already in shared/style.css - Use `$state` and `$derived` (Svelte 5 runes) — consistent with other admin pages - No Tailwind — pure CSS vars + explicit styles per project convention - No scoped Svelte `<style>` blocks — all CSS stays in global app.css per SOP ### Checklist - [ ] PR opened - [ ] Build passes - [ ] No unrelated changes ### Related - `forgejo_admin/westside-playground#50` — upstream playground prototype with @-comment spec - `sop-capacitor-mobile-lifecycle` — playground-to-Svelte promotion SOP - `project-westside-basketball` — westside project page with user stories
Author
Contributor

Scope Review: NEEDS_REFINEMENT

Review note: review-863-2026-04-06

Template complete, traceability solid (story:WS-S9 verified), file targets confirmed. Three body fixes needed before dispatch:

  • Nav file path: Specify src/routes/(app)/+layout.svelte (lines 106-126) instead of "wherever the nav lives"
  • Playground spec reference: Add explicit link to westside-playground#50 commerce.html @-comment spec — the implementing agent needs the field-to-column mapping
  • 5-nav mobile consideration: Note that adding a 5th bottom-nav item needs mobile spacing verification (320px)
  • Upstream gate: Board item #865 (playground spec) is still in needs_approval — must pass before this ticket advances
  • [SCOPE] Architecture note arch-westside-app does not exist in pal-e-docs — needs creation
## Scope Review: NEEDS_REFINEMENT Review note: `review-863-2026-04-06` Template complete, traceability solid (story:WS-S9 verified), file targets confirmed. Three body fixes needed before dispatch: - **Nav file path**: Specify `src/routes/(app)/+layout.svelte` (lines 106-126) instead of "wherever the nav lives" - **Playground spec reference**: Add explicit link to `westside-playground#50` commerce.html @-comment spec — the implementing agent needs the field-to-column mapping - **5-nav mobile consideration**: Note that adding a 5th bottom-nav item needs mobile spacing verification (320px) - **Upstream gate**: Board item #865 (playground spec) is still in `needs_approval` — must pass before this ticket advances - **[SCOPE]** Architecture note `arch-westside-app` does not exist in pal-e-docs — needs creation
Author
Contributor

Scope refinement (review-863 feedback):

  1. Added exact nav path: src/routes/(app)/+layout.svelte lines 106-126, insert between CRM (line 114) and Teams (line 115)
  2. Added playground spec reference as implementation contract
  3. Added mobile constraint: verify 5th bottom-nav item spacing at 320px viewport
  4. Skipping arch note creation for arch-westside-app — systemic gap across 29 board items, not specific to this ticket
  5. Added upstream gate: board item #865 must be done before this moves to in_progress
**Scope refinement (review-863 feedback):** 1. Added exact nav path: `src/routes/(app)/+layout.svelte` lines 106-126, insert between CRM (line 114) and Teams (line 115) 2. Added playground spec reference as implementation contract 3. Added mobile constraint: verify 5th bottom-nav item spacing at 320px viewport 4. Skipping arch note creation for `arch-westside-app` — systemic gap across 29 board items, not specific to this ticket 5. Added upstream gate: board item #865 must be `done` before this moves to `in_progress`
Author
Contributor

Scope Review: APPROVED

Review note: review-863-2026-04-06
Re-review after refinement — all 5 prior items addressed. Scope is solid, file targets verified, traceability complete (arch note gap deferred as systemic). Ready for dispatch once upstream #865 reaches done.

Non-blocking nit: "commerce CSS already exists in shared/style.css" is inaccurate (no such file; app.css has no commerce classes). Agent will handle naturally.

## Scope Review: APPROVED Review note: `review-863-2026-04-06` Re-review after refinement — all 5 prior items addressed. Scope is solid, file targets verified, traceability complete (arch note gap deferred as systemic). Ready for dispatch once upstream #865 reaches done. **Non-blocking nit:** "commerce CSS already exists in shared/style.css" is inaccurate (no such file; app.css has no commerce classes). Agent will handle naturally.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/westside-app#226
No description provided.