Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/roadmap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SmartShooter Roadmap (Execution Snapshot)

Last updated: 2026-02-14
Last updated: 2026-02-15

## Current Goal
Ship a portfolio-grade analytics and training workflow with compact UX, stable role-gated dev tools, and clean PR-sized delivery.
Expand All @@ -18,6 +18,15 @@ Ship a portfolio-grade analytics and training workflow with compact UX, stable r
8. Milestone interaction update:
- recent badges visible under milestone area
- click milestone to open achieved milestones list
9. Mobile analytics compaction refinements:
- compact filter and KPI density for small screens
- default analytics period set to `90d`
- default streak window set to `365d` desktop and `90d` mobile
10. Navbar cleanup and consistency:
- removed obsolete top-level onboarding/help actions
- unified action button style
- mobile actions are icon-only
- orange neon treatment in dark mode

### In Progress
1. Product hardening around role assignment workflow and admin onboarding clarity
Expand All @@ -35,6 +44,7 @@ Ship a portfolio-grade analytics and training workflow with compact UX, stable r
- Add locked milestone previews
4. Regression safety
- Add targeted tests for attempts-vs-made, milestone modal, and filters
- Add targeted tests for streak responsive defaults and compact mobile navbar behavior
5. Docs closure
- Keep roadmap and ux-spec synchronized after each merged PR

Expand Down
190 changes: 72 additions & 118 deletions docs/ux-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,168 +13,122 @@
- Accessible by default (keyboard, contrast, labels, focus states).

## Current UX Problems
- `src/pages/Dashboard.jsx` mixes too many responsibilities and actions in one view.
- Session logging is powerful but cognitively heavy on first use.
- Analytics is dense and lacks a concise “what should I do next?” summary.
- Table-first log UI does not scale well on mobile.
- Visual and interaction patterns are inconsistent across components.
- `src/pages/Dashboard.jsx` historically carried too many responsibilities.
- Session logging can still feel heavy for first-time users.
- Analytics can become dense without strong hierarchy.
- Table-first log views do not scale to mobile without card patterns.
- UI consistency requires continuous enforcement as features expand.

## Target Experience

### 1) Dashboard Information Architecture
- Primary CTA: `Log Session`.
- Header row:
- Left: greeting + compact progress context.
- Right: primary CTA + secondary menu (`Export`, `Help`, `More`).
- Tabs remain `Log` and `Analytics`, but each tab has a clearer structure.
- Right: compact utility actions and account actions.
- Tabs remain `Log` and `Analytics`, with clear section boundaries.

### 2) Session Logging (Guided)
- Convert session editor to a 3-step flow:
- 3-step flow:
- `Setup`: date, training type, notes.
- `Rounds`: per-round direction/range and zone attempts/makes.
- `Review`: totals, validation summary, save.
- Validation:
- Inline field-level messages.
- Sticky summary on review step.
- Toasts reserved for final outcomes (save success/failure).
- Toasts reserved for final outcomes.

### 3) Analytics Hierarchy
- Top: KPI cards (`Accuracy`, `Volume`, `Best Zone`).
- Then: Insights Summary” card with simple text guidance.
- Then: heatmaps and charts.
- Then: `Insights Summary` for next-action guidance.
- Then: heatmaps/charts.
- Empty states:
- Clear copy when no data in selected filters.
- Suggested quick actions (`Try 30d`, `Clear filters`).
- Explicit no-data copy.
- Suggested recovery actions.

### 4) Log UX
- Desktop: keep table, improve controls grouping.
- Mobile: switch to list cards with key stats and row actions.
- Keep destructive actions behind clear confirmation.
- Desktop: keep table with grouped controls.
- Mobile: card list with key stats and row actions.
- Destructive actions remain confirm-gated.

### 5) Design System Foundations
- Introduce design tokens (color, spacing, radius, typography, shadows, focus ring).
- Standardize component variants:
- Buttons: `primary`, `secondary`, `ghost`, `destructive`.
- Inputs/selects with shared states and errors.
- Card wrappers and section headers.
- Shared tokens for spacing, radius, focus, and colors.
- Standardized components for buttons, inputs/selects, cards, and tabs.

### 6) Accessibility & Feedback
- Keyboard support for all core interactions.
- Consistent visible focus ring.
- ARIA labels for icon-only controls.
- Chart/heatmap alt-text summaries.
- Loading states that mirror final layout (avoid layout shift).
- Stable loading skeletons to avoid layout shift.

## Current UX Baseline (Implemented)
- Dashboard is compact-first for desktop (`1920x1080`) and optimized for mobile density.
- Analytics controls are grouped as `Period`, `Drills`, and `Metrics`.
- Default analytics period is `90d`.
- Calendar streak defaults are responsive:
- Desktop: `365d` (`year-to-date`)
- Mobile: `90d`
- Main analytics body prioritizes:
- Court heatmap
- Zones + insights
- Accuracy trend / Attempts vs Made
- Best zone KPI is compacted for mobile readability (abbreviated labels).
- Milestones now include:
- recent badge strip
- click-to-open achieved milestones modal
- Dev mode visibility is role-gated (`admin` only).
- Navbar has been simplified:
- obsolete top-level onboarding/help actions removed
- unified action button style
- icon-only actions on mobile, text labels on larger screens

## Execution Plan (PR-Sized)

### PR 1: UX Foundation Tokens + Controls
- Files (new):
- `src/styles/tokens.css`
- `src/components/ui/Button.jsx`
- `src/components/ui/FormField.jsx`
- `src/components/ui/Card.jsx`
- Files (update):
- `src/main.jsx` or `src/index.css` (import tokens)
- small initial adoptions in `src/pages/Dashboard.jsx`, `src/components/SessionForm.jsx`
- Acceptance:
- No behavior changes.
- Existing functionality remains intact.
- Status: complete.

### PR 2: Dashboard IA Cleanup
- Files:
- `src/pages/Dashboard.jsx`
- `src/components/Navbar.jsx`
- Changes:
- Clear primary CTA and secondary actions menu.
- Better grouping/order of sections.
- Cleaner empty/loading states.
- Acceptance:
- Core actions remain discoverable.
- No regression in save/edit/delete/session load.
- Status: complete.

### PR 3: Session Form Stepper
- Files:
- `src/components/SessionForm.jsx`
- `src/lib/models.js` (only if helper extraction is needed)
- Changes:
- Introduce stepper layout and inline validation UX.
- Preserve same payload contract on submit.
- Acceptance:
- Submitted payload unchanged shape.
- Existing tests pass + add form behavior tests if feasible.
- Status: complete.

### PR 4: Analytics Readability + Insights
- Files:
- `src/pages/Dashboard.jsx`
- `src/components/KpiTiles.jsx`
- `src/components/AnalyticsFilters.jsx`
- `src/components/HeatmapCourt.jsx`
- `src/components/HeatmapCourtImage.jsx`
- Changes:
- Add insights summary card.
- Better hierarchy and filter disclosure.
- Data-empty guidance.
- Acceptance:
- KPIs/charts/heatmaps unchanged numerically.
- Status: complete.

### PR 5: Mobile Log Cards
- Files:
- `src/pages/Dashboard.jsx`
- optional new `src/components/log/LogCardList.jsx`
- Changes:
- Mobile list card mode replacing dense table under small breakpoints.
- Acceptance:
- Edit/delete/export remains reachable on mobile.
- Status: complete.

### PR 6: Accessibility + Polish
- Files:
- Targeted updates across `src/components/*` and `src/pages/*`
- Changes:
- Focus management, ARIA, keyboard flows, chart textual summary.
- Standardized feedback/loading patterns.
- Acceptance:
- Keyboard-only walkthrough works for login, create session, analytics filters.
- Status: complete, with ongoing hardening.

### PR 7: Frontend Bundle Optimization
- Status: complete (route/chart/firebase splitting and lighter chart rendering).

## Next UX Backlog
1. Achievements depth
- Category grouping (`accuracy`, `volume`, `streak`).
- Locked milestone previews.
2. Analytics comparators
- Add period-over-period KPI deltas.
3. Empty-state quality
- Standardize no-data copy and add one-click reset actions.
4. Accessibility hardening
- Audit milestone modal and compact navbar keyboard/focus behavior.
5. Regression safety
- Add focused tests for filters, streak defaults, and chart fallback states.

## Validation Checklist Per PR
- Run: `npm run test`
- Run: `npm run build`
- Run: `npm run lint` (track existing baseline lint issues separately from new regressions)
- Run: `npm run lint`
- Manual smoke:
- Login/logout
- Create/edit/delete session
- Filter analytics by date/type/direction/range
- Verify mobile layout at narrow viewport

## Non-Goals (for this UX phase)
- No backend/data model rewrites.
- No AI feature introduction.
- No major analytics logic changes without failing tests.

## Current UX Baseline (Implemented)
- Dashboard analytics is now compact-first for desktop (`1920x1080`) with tighter vertical density.
- Header keeps primary actions and milestone context visible at all times.
- Analytics controls are grouped (`Period`, `Drills`, `Metrics`) and optimized for quick scanning.
- Calendar streak is year-to-date and rendered as a primary context block.
- Main analytics body prioritizes:
- Court heatmap
- Zones + insights
- Accuracy trend / Attempts vs Made
- Range filter is constrained to a single default range (`midrange`) to avoid misleading mixed-range percentages.
- Milestone area supports recent-badge visibility and a click-through list of achieved milestones.
- Dev mode visibility is role-gated (`admin` only).

## Next UX Backlog (Post-Compact Pass)
1. Milestones UX polish
- Add clearer badge progression states (locked vs unlocked tiers).
- Add optional quick filter for achievements by category (`accuracy`, `volume`, `streak`).
2. Analytics comparators
- Add compare window (`current period` vs `previous period`) for KPI deltas.
- Keep charts compact without re-introducing vertical overflow.
3. Logs efficiency
- Improve row density and sticky actions for faster editing in large logs.
- Preserve mobile cards behavior and parity with desktop actions.
4. Accessibility hardening
- Run keyboard-only walkthrough for all analytics controls and modal states.
- Add/verify ARIA labels and focus traps for milestone/achievement dialogs.
5. Empty-state quality
- Standardize no-data copy and add one-click “reset filters” action in each analytics tab.
- login/logout
- create/edit/delete session
- analytics filter changes
- desktop/mobile layout checks

## Non-Goals (This UX Phase)
- No backend/data-model rewrites.
- No AI feature scope expansion.
- No analytics logic rewrites without test-backed justification.
6 changes: 3 additions & 3 deletions src/components/AnalyticsFilters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function AnalyticsFilters({ value, onChange }) {
}

const inputBase =
'w-full border rounded-lg px-7 py-1.5 text-sm bg-white border-gray-200 text-gray-900 ' +
'w-full min-w-0 max-w-full border rounded-lg px-7 py-1.5 text-sm bg-white border-gray-200 text-gray-900 ' +
'focus:outline-none focus:ring-2 focus:ring-black/10 focus:border-transparent ' +
'dark:bg-neutral-800 dark:border-neutral-700 dark:text-neutral-100 dark:focus:ring-white/10'

Expand All @@ -52,7 +52,7 @@ export default function AnalyticsFilters({ value, onChange }) {
const directionValue = normDir(direction) || 'all'

return (
<div className="space-y-1.5">
<div className="space-y-1.5 min-w-0">
<div className="space-y-1.5">
<div className="text-[11px] uppercase tracking-wide opacity-70">Period</div>
<div className="flex items-center gap-1.5 overflow-x-auto pb-0.5 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
Expand All @@ -71,7 +71,7 @@ export default function AnalyticsFilters({ value, onChange }) {
</div>
</div>

<div className="grid grid-cols-2 gap-1.5">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-1.5 min-w-0">
<div className="relative min-w-0">
<Calendar size={13} strokeWidth={1.75} className="absolute left-2 top-1/2 -translate-y-1/2 opacity-60" />
<input
Expand Down
32 changes: 17 additions & 15 deletions src/pages/dashboard/DashboardHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,23 @@ export default function DashboardHeader({ userEmail, totalXP, userUid, onCreateC
</button>
</div>

<div className="mt-2 flex justify-end">
<div className="flex items-center gap-1.5" aria-label="Recent badges">
{(recentBadges.length ? recentBadges : Array.from({ length: 5 })).map((a, i) => (
<button
key={a?.id || `placeholder-${i}`}
type="button"
onClick={() => setOpenMilestones(true)}
title={a?.name || 'Locked badge'}
className="h-8 w-8 rounded-full border dark:border-neutral-700 grid place-items-center text-sm bg-white/70 dark:bg-neutral-900/70 hover:bg-black/5 dark:hover:bg-white/5"
>
{a?.icon || '•'}
</button>
))}
{recentBadges.length > 0 && (
<div className="mt-2 flex justify-end">
<div className="flex items-center gap-1.5" aria-label="Recent badges">
{recentBadges.map((a) => (
<button
key={a?.id}
type="button"
onClick={() => setOpenMilestones(true)}
title={a?.name || 'Badge'}
className="h-8 w-8 rounded-full border dark:border-neutral-700 grid place-items-center text-sm bg-white/70 dark:bg-neutral-900/70 hover:bg-black/5 dark:hover:bg-white/5"
>
{a?.icon || '*'}
</button>
))}
</div>
</div>
</div>
)}

{openMilestones && (
<div
Expand Down Expand Up @@ -109,7 +111,7 @@ export default function DashboardHeader({ userEmail, totalXP, userUid, onCreateC
key={a.id}
className="rounded-xl border dark:border-neutral-700 p-3 flex items-start gap-3"
>
<div className="text-xl leading-none">{a.icon || '🏅'}</div>
<div className="text-xl leading-none">{a.icon || '*'}</div>
<div className="min-w-0">
<p className="font-semibold text-sm">{a.name || 'Achievement'}</p>
<p className="text-sm text-neutral-700 dark:text-neutral-300">
Expand Down