fix(frontend): make mobile navigation and filters fully usable - #92
fix(frontend): make mobile navigation and filters fully usable#92Francespo wants to merge 19 commits into
Conversation
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
…gement instructions and workflow
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) ---------
|
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 |
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.
No description provided.