BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
Find football matches near you in Bergen, or host your own and fill the team in minutes.
Sports & fitnessTypeScript · PLpgSQLGitHub @agustinsoaresOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
A modern platform to organize and manage amateur 7-a-side football leagues. It lets teams register, schedules matches automatically, shows results and stats, and includes tools for league admins. Built as a real-world style project to practice and showcase web development skills.
Taken from the repository README
Loading the full README.
Read the full README ↗Aalto Football is a web app for pick-up football in Bergen, Norway. Hosts create matches (pitch, time, format, level and spots) and players find them and join. Think Playtomic, but for 5-, 7-, 9- and 11-a-side football.
The site is in English by default, with Norwegian (bokmål) available through the language switcher. It can be installed on a phone's home screen as a PWA.
Status: in development. Players can sign up, find matches, join or leave (with a waitlist), and hosts can create, edit, cancel and share matches. Online payments are disabled for now (see Roadmap).
/privacy, /terms)/admin, admins only): community stats, website traffic (Vercel Web Analytics), choose who else is admin, manage the pitchesapps/websupabase/.
├─ apps/web/ # Next.js app (deployed to Vercel)
│ ├─ public/ # Hero image, PWA icons, service worker (sw.js)
│ └─ src/
│ ├─ app/[lang]/ # Localised routes: /en/… and /nb/…
│ ├─ app/manifest.ts # PWA manifest
│ ├─ components/ # Header, Footer, MatchCard, LanguageSwitcher…
│ ├─ i18n/ # Language config and dictionaries (en, nb)
│ ├─ lib/supabase/ # Supabase clients and database types
│ └─ proxy.ts # Redirects / to /en or /nb (cookie, then browser language)
├─ supabase/
│ ├─ migrations/ # Schema, RLS policies, join/leave functions
│ ├─ seed.sql # Bergen sample data (users, pitches, matches)
│ └─ tests/ # Local Supabase stub + RLS tests
└─ docs/ # Brand guide
Requirements: Node.js 20+ and, for a local database, Docker.
git clone https://github.com/agustinsoares/futbol-7.git
cd futbol-7
# Local Supabase (Postgres + Auth + API) with the migrations and Bergen seed data
npx supabase start # prints the local API URL and publishable key
cd apps/web
cp ../../.env.example .env.local # paste the local URL and publishable key
npm install
npm run dev # http://localhost:3000
Seed users get a random password. To log in locally, set one:
psql postgresql://postgres:[email protected]:54322/postgres \
-c "update auth.users set encrypted_password = extensions.crypt('local-pass-123', extensions.gen_salt('bf')) where email like '%@aaltofootball.test'"
Without Supabase variables the site still runs and shows sample matches.
Useful commands (from apps/web):
npm run lint # ESLint
npm run typecheck # TypeScript
npm run format # Prettier
npm test # unit tests (Vitest)
npm run build # production build
npm run test:e2e # end-to-end tests (Playwright) against a running app + local Supabase
CI runs all of the above, plus the migrations against Postgres and the end-to-end suite against a local Supabase.
Project: yqtxllyhmmwgvvirlput (organisation Aalto Football). Migrations and sample data are already applied.
To set up a new project:
supabase/migrations/ in order (SQL editor or supabase db push).supabase/seed.sql for Bergen sample data. It creates [email protected] (admin),
[email protected] (regular user) and 20 more players, 7 pitches and 12 matches.
Users get a random password: set one from Authentication → Users to log in with them.apps/web/.env.production (public values) and in .env.local for development.Security model:
get_match().join_match / leave_match, which lock the match row so the last spot can't be taken twice, and move the first waitlisted player up when someone drops out.https://<your-domain>/** and https://*-<your-vercel-team>.vercel.app/** (for previews).NEXT_PUBLIC_AUTH_GOOGLE_ENABLED=true.supabase/templates/ (used automatically by
local Supabase). In production, paste them in Authentication → Emails → Templates:
confirmation.html → Confirm sign up and magic_link.html → Magic link. Their links use token_hash, so
they work even when opened on a different device or browser than the one used to sign up.
Also recovery.html → Reset password (subject Reset your Aalto Football password).vercel.json schedules /api/cron/daily once a day (06:00 UTC). It marks finished matches as played and emails
confirmed players whose match starts in the next 26 hours. Set these environment variables in Vercel:
CRON_SECRET: any long random string (Vercel sends it to the cron route).SUPABASE_SECRET_KEY: the project's secret key (Project Settings → API keys). Server-only.RESEND_API_KEY and EMAIL_FROM (e.g. Aalto Football <hello@your-domain>): without them, nothing is sent and
reminders stay pending.<Analytics /> script, which only loads when running on Vercel./admin shows visitors, page views, top pages, countries, referrers and devices for the
last 30 days when VERCEL_ANALYTICS_TOKEN, VERCEL_ANALYTICS_PROJECT_ID and VERCEL_ANALYTICS_TEAM_ID are set in
Vercel (token from vercel.com/account/tokens, stored as Sensitive). Without them, the panel links to the
Vercel dashboard. The community numbers (players, matches, fill rate…) come from Supabase and need nothing.apps/webapps/web/.env.production.
Set NEXT_PUBLIC_SITE_URL only if you use a custom domain.Logo, colours, typography and tone (Spanish): docs/marca.md.
MIT.