Range Officer management system for NROI
- Frontend: Vite + React (static SPA, hosted on GitHub Pages)
- Storage: localStorage (current) → Supabase Postgres (migration target)
- Auth: localStorage sessions (current) → Supabase Auth (migration target)
src/
lib/
constants.js ← CERT_LEVELS, DQ_REASONS, MATCH_LEVEL_POINTS, THEMES, etc.
helpers.js ← certColor(), roleColor(), fmtDate(), inp/btnS/btnP styles, etc.
seedData.js ← seedUsers, seedMatches, seedSeminars, seedClubs, seedDocs
supabase.js ← Supabase client singleton (no-op if env vars not set)
components/
ui.jsx ← Badge, Modal, Field, StatCard, UserPicker, RegionSelect, contexts
pages/
AuthScreen.jsx
Dashboard.jsx
MyProfile.jsx
UserDatabase.jsx
ROPage.jsx
MatchesPage.jsx
ClubsPage.jsx
DocsPage.jsx
PointsPage.jsx
SeminarsPage.jsx
App.jsx ← Shell: nav, sidebar, routing, theme, localStorage persistence
main.jsx ← ReactDOM.createRoot entry point
npm install
npm run dev- Add
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYas GitHub Actions secrets. - Push to
main— the workflow in.github/workflows/deploy.ymlbuilds and deploys automatically.
Without Supabase credentials, the app runs entirely on localStorage (good for local dev and testing).
The app currently uses localStorage for all data. The planned migration order:
- Supabase Auth — replace plaintext passwords immediately
profilestable — users persist across devicesmatches+ro_participation— core business data, replaces_pointsToDistributeReact flag with a DB trigger- Points trigger — atomic point distribution on match completion
seminars+clubs— secondary data- RLS policies — added per table as each is created
See src/lib/supabase.js for the client setup.