Skip to content

fix(frontend): make mobile navigation and filters fully usable - #92

Open
Francespo wants to merge 19 commits into
devfrom
copilot/mobile-usability-fix
Open

fix(frontend): make mobile navigation and filters fully usable#92
Francespo wants to merge 19 commits into
devfrom
copilot/mobile-usability-fix

Conversation

@Francespo

Copy link
Copy Markdown
Owner

No description provided.

@m3tacron-dev-prod

m3tacron-dev-prod Bot commented Mar 30, 2026

Copy link
Copy Markdown

The preview deployment for francespo/m3tacron:dev is ready. 🟢

Open backend | Open frontend | Open Build Logs | Open Application Logs

Last updated at: 2026-03-30 17:07:15 CET

@m3tacron-dev-prod

m3tacron-dev-prod Bot commented Mar 30, 2026

Copy link
Copy Markdown

The preview deployment for francespo/m3tacron:dev is ready. 🟢

Open backend | Open frontend | Open Build Logs | Open Application Logs

Last updated at: 2026-03-31 09:22:10 CET

@m3tacron-dev-prod

m3tacron-dev-prod Bot commented Mar 31, 2026

Copy link
Copy Markdown

The preview deployment for francespo/m3tacron:dev is ready. 🟢

Open backend | Open frontend | Open Build Logs | Open Application Logs

Last updated at: 2026-03-31 09:36:13 CET

@m3tacron-dev-prod

m3tacron-dev-prod Bot commented Mar 31, 2026

Copy link
Copy Markdown

The preview deployment for francespo/m3tacron:dev is ready. 🟢

Open backend | Open frontend | Open Build Logs | Open Application Logs

Last updated at: 2026-03-31 10:09:44 CET

@m3tacron-dev-prod

m3tacron-dev-prod Bot commented Mar 31, 2026

Copy link
Copy Markdown

The preview deployment for francespo/m3tacron:dev is ready. 🟢

Open backend | Open frontend | Open Build Logs | Open Application Logs

Last updated at: 2026-05-24 15:35:30 CET

GitHub Copilot and others added 13 commits May 24, 2026 15:30
Fixes #97.

Removes the forced left-column scrolling on the Support page by keeping
the desktop layout within the viewport and moving scrollbar styling to a
shared `.custom-scrollbar` rule. Mobile stays in the single-column flow.
## Summary

Make faction presentation consistent in the dashboard by showing full
faction names in the Faction Performance tooltip and rendering faction
badges through the shared glyph helpers so Resistance displays reliably.

Fixes #95

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…#108)

This PR adds a **SQLite wrapper** for offline scraper testing, improves
the Longshanks and Rollbetter scrapers, fixes the missing `winner_id` in
match records, and updates the GitHub Action to support a SQLite-only
run mode.

- **`backend/scripts/scrape_tournaments_sqlite.py`** — wrapper that sets
`DATABASE_URL` to a local SQLite file before importing the main scraper.
Enables offline testing without Postgres. Usage:
  ```bash
  python -m backend.scripts.scrape_tournaments_sqlite \
    --sqlite-path scraped.db \
    --platform longshanks+rollbetter \
    --time-range 7
  ```

- **`scrape_tournaments.py`** — added `--tournament-url` flag for
scraping individual URLs directly (supports Rollbetter, Longshanks, and
ListFortress). Added `--tournament-url` support for benchmark
validation.
- **`rollbetter_scraper.py`** — scoped match table selection to the
active tab panel and added a `wait_for_selector` before reading round
data. This fixes several rounds that previously reported "No match table
found".
- **`longshanks_scraper.py`** — replaced jQuery `trigger(change)` with
the sites own `load_games()` helper (which is how the page actually
loads match data). Scoped `.results` lookups to the `#games` container.
Fixed date parsing to use the start date from Longshanks date ranges.

- **`save_tournament_data`** — `winner_id` was never set when converting
match dicts to `Match` objects. Now resolves `winner_name_temp` against
the player name map to populate the foreign key. **All 20 matches in the
validation scrape now have a non-null `winner_id`** (previously 0).

- **`scrape_tournaments.yml`** — added `none` as an environment option
(SQLite-only, no Postgres). Exposed `upload_sqlite_artifact` as an input
toggle. Postgres writes only occur for `prod`/`dev`. When `environment:
none`, uses the SQLite wrapper.

- ✅ Local SQLite scrape of 10 benchmark tournaments matches expected
counts (Rollbetter events match exactly; Longshanks now captures
**more** matches thanks to the `load_games()` fix — previously missed
rounds)
- ✅ GH Action ran successfully against **dev** Postgres (8 new
tournaments from Apr 15–30, grew DB from 604 → 612)
- ✅ GH Action correctly uses `DEV_DATABASE_URL` secret when
environment=dev
- ✅ SQLite artifact uploaded as expected
- ✅ `winner_id` now correctly populated in all match records
- ✅ Local scrape of Apr 1–7 produced 5 tournaments, 26 players, 36
matches across both platforms

Closes # (no issue linked)

---------
@m3tacron-dev-prod

m3tacron-dev-prod Bot commented May 24, 2026

Copy link
Copy Markdown

The preview deployment for francespo/m3tacron:dev is ready. 🟢

Open backend | Open frontend | Open Build Logs | Open Application Logs

Last updated at: 2026-05-24 15:51:24 CET

Franc3s-bot added a commit to Franc3s-bot/m3tacron that referenced this pull request Jul 31, 2026
Replaces PR Francespo#92's partial fix with a from-scratch mobile shell, a
centralized filter URL-sync layer, and a stack of targeted perf and
responsiveness fixes. The 5 filterable routes no longer maintain
their own URL-building logic; the store owns it.

Mobile shell (new components):
- MobileTopBar: sticky top chrome for <md viewports (hamburger + brand)
- MobileNavDrawer: left-edge nav drawer, focus-trapped, ARIA dialog,
  sourced from Sidebar.NAV_LINKS module export
- MobileFilterDrawer: right-edge filter sheet accepting a children +
  optional footer snippet
- MobileFilterTrigger: FAB with active-filter count badge, <lg only
- DebouncedTextInput: 250ms-debounced search input

Filter system (filters.svelte.ts):
- toSearchParams(routeId): per-route whitelist serializer with
  deterministic key order (round-trip identity for the echo guard)
- applyFromSearchParams(params): URL -> store, partial-update only
- selectedFactions / sortBy / sortDirection: moved from route-local
  state into the store
- activeChips:  (was a getter that re-ran per access)

URL sync (lib/sync/urlSync.svelte.ts):
- scheduleSync(delayMs?, overlay?): debounced goto() with echo guard,
  URL-key round-trip identity, replaceState + keepFocus + noScroll
- clearPendingSync(): called by onNavigate in +layout.svelte so
  fast route switches do not corrupt the destination URL

Route rewrites (cards, lists, ships, squadrons, tournaments):
- Per-field URL-building  (20-64 lines each) replaced with
  5-10 line thin effect using filters.toSearchParams + scheduleSync
- route-local selectedFactions / sortBy / sortDirection removed
- echo-guard logic lives in urlSync, not in each route
- ~200 lines of duplicated URL plumbing deleted across 5 files

Per-route perf + responsive fixes:
- ships: 5 inline style attributes per card collapsed to 1 (with
  CSS custom properties); font-size: 10rem -> clamp(3rem, 18vw, 8rem)
- squadron/[signature]: 6-col pilot table collapses to stacked
  card layout on <sm
- ship/[xws]: right-edge gradient fade hints at horizontal scroll
  on <sm
- cards: dynamic import('$app/navigation') -> static goto import
  in tab handlers
- +page.svelte (dashboard): chartAction uses chart.update(newConfig)
  instead of destroy/recreate; chart.js auto-import hoisted to module
- TournamentFilters: $derived(() => fn()) misuse -> $derived.by

Misc:
- Sidebar: NAV_LINKS exported as the single source of truth for
  nav entries (consumed by both desktop sidebar and mobile drawer)
- FilterPanel: rewritten to desktop-only with a children snippet;
  routes pass the same snippet to MobileFilterDrawer for mobile
- MobileFilterDrawer / MobileNavDrawer: migrated from deprecated
  $app/stores to $app/state
- +layout.svelte: client-only $effect calls
  filters.applyFromSearchParams on mount, onNavigate cancels
  pending syncs

Touch targets: hamburger, nav links, FAB, sort direction button,
content-source toggle, drawer close buttons all >= 44x44. Active
filter count visible on the FAB badge and the drawer header.

Behavior: empty filters.sortBy / sortDirection produce empty URL
params which the backend fills with its own Query() defaults
(cards/ships/squadrons/lists: 'Popularity' or 'Games'; tournaments:
'Date'), so first-visit sort order is preserved.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant