Speel individueel mee bij onze sessies, of meld je aan als duo voor onze toernooien.
Translation pending
Sports & fitnessGitHub @OxMarcKOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
event pages
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Live poulefase + knock-out/placement bracket companion for padelsocial.nl events.
Built from padel-social-event-companion-spec.md and the Claude Design project
Padel Social event companion app.
homepage/ — static marketing siteThis repo also holds the static marketing homepage for www.padelsocial.nl,
in homepage/. It's a plain HTML/CSS/JS site — no Next.js, no
build step, no database — kept fully separate from the event app above (which
runs on event.padelsocial.nl). It isn't deployed through this app's build or
hosting; it's uploaded by hand via FTP straight from homepage/.
homepage/
index.html
css/styles.css
js/main.js -- mobile nav, toggle groups, contact form → mailto: link
assets/ -- logos, photos, og-image.jpg
The contact form has no backend — it builds a mailto: link client-side in
main.js and hands off to the visitor's own mail client.
To preview locally: cd homepage && python3 -m http.server 8765, then open
http://localhost:8765.
npm install
npm run dev
Open http://localhost:3000. No Supabase project is required to try the app —
without NEXT_PUBLIC_SUPABASE_URL set, every page runs against an in-memory demo
data store (lib/data/mock-repo.ts) that lives for the life of the dev server
process. Create an event at /admin (any email logs you in instantly in this
mode — magic links aren't real yet), bulk-add teams, and run the whole flow.
There is no public sign-up page — the organizer enters everything directly in
/admin/e/[id] before the event starts:
draft ("Opzetten").Team naam | Speler 1 | Speler 2 lines, one per
team).resolveTop8 in lib/bracket-engine.ts).draft to
poulefase — no "open for registration" step in between.Teams have no status field (pending/paid/no-show) — anything the admin enters is a confirmed team by definition, since there's no external self-signup flow to reconcile against.
Run the test suite (the two pure logic modules — poule scheduling and bracket propagation):
npm run test
The app is written against a repository interface (lib/data/repo.ts) with two
implementations — mock-repo.ts (above) and supabase-repo.ts — selected
automatically by lib/data/index.ts based on whether Supabase env vars are set.
Switching is not a code change:
supabase/migrations/0001_init.sql (no CLI
needed — this repo doesn't include the Supabase CLI as a dependency)..env.local.example to .env.local and fill in the project URL, anon
(publishable) key, and service-role (secret) key from Project Settings →
API Keys, plus NEXT_PUBLIC_SITE_URL (http://localhost:3000 locally).
Supabase never displays the full secret key on screen — only a masked
preview and a "Copy" button — so paste it directly into the file yourself
rather than through a chat/clipboard round-trip; a wrapped copy-paste can
silently split the key across two lines and break .env parsing.http://localhost:3000/auth/callback (and your real domain's
equivalent once deployed). Without this, Supabase silently ignores the
app's requested redirect and sends every magic link back to the bare Site
URL instead, so login never reaches /auth/callback to establish a
session./admin/login → "Stuur
inloglink") once the user exists — either sends a real session-establishing
link through /auth/callback. The dashboard's "Send invitation" flow
uses a different, implicit-grant redirect that this app doesn't have a
client-side handler for, so an invite email won't actually log you in;
create the user via invite if you like, but then sign in via the app's own
magic-link form rather than clicking the invite email's link. There's no
self-serve admin signup by design (spec: "only 1–2 admins exist").npm run dev — Next only reads .env.local at startup.supabase/seed.sql is not included — reuse the admin bulk-add flow (supports
pasted Team naam | Speler 1 | Speler 2 lines) to seed real data instead.
The spec's prose describes "5 rounds of 20 minutes" for the poulefase, but its
own required test list ("4 unique matches per team... all 5 courts used every
round") is only satisfiable with 6 rounds for 3 poules on 5 courts: 3
poules × 5 teams is 30 total matches, and 5 courts × 5 rounds is only 25
court-slots — every team getting all 4 of their matches genuinely needs 5
courts × 6 rounds = 30. lib/poule-scheduler.ts implements the correct,
fully-tested round packing for any number of poules/courts (see its doc
comment for the derivation), and the app's phase-timing (lib/schedule.ts)
derives the real poulefase duration from whatever that comes out to, so the
displayed schedule stays internally consistent regardless of how many poules
an event has. This shifts the real event's clock for the 3-poule/5-court
case specifically — worth flagging to the organizer: poulefase would run
10:30–12:40 (6 rounds × 20 min play + 5 × 2 min changeover between rounds)
rather than 10:30–12:10 (the spec's naive 5-round, no-changeover assumption at
20 min/round) if run as a genuinely complete round robin on 5 courts.
lib/poule-scheduler.ts (circle-method round
robin + court packing, generic across poule/court counts) and lib/bracket- engine.ts (rank-based top-8 seeding — standard 1v8/4v5/2v7/3v6 bracket
pairing, poule-count-agnostic — full winner/loser propagation through every
round, the 7-team-and-up placement gauntlet). 22 tests, zero framework
imports, exactly as the spec requires.teams.status column, dropped —
see "How an event gets set up"), implemented for both the mock store and
real Postgres (supabase/migrations/0001_init.sql), including the
players-table privacy boundary (public pages never see email/phone; see
the public_team_players view and its RLS policies)./), adaptive event page (/[slug]
— live scoreboard / prijsuitreiking / results depending on status), TV mode
(/[slug]/tv), team lookup (/[slug]/teams), a team detail + share
page (/[slug]/teams/[teamId] — added beyond the spec's route list since
the spec's own "tap a team, share the card" requirement needs a stable
per-team URL), and standings (/[slug]/standen, poule tables + bracket
tabs)./admin, /admin/e/[id]): magic-link login, event
creation, bulk team add, manual/random poule draw (poule count is just
however many groups of 5 you tell it to make), poule-schedule
preview+publish, fast score entry (court picker + big steppers, matching
the design's admin screens), phase advancement with an inline "here's what
happens next" confirmation (spec §8), top-8 seeding preview with a manual
override control for cross-poule tie-breaks, and video URL attachment per
match.next/font, the padel-court
visual motif (components/court-card.tsx), and the animated standings list
(components/standings-list.tsx) with the lime rank-climb flash, respecting
prefers-reduced-motion.Not built (explicitly Phase 2+ per spec §2.4/§7): player accounts, /p/[id]
player pages, ratings, payment integration, auto phase-timers, multi-organizer
support.
next/postcss itself, fixable only by a Next 14+/16 major bump, which
would need a Node upgrade first.lib/bracket-engine.ts runs a documented best-effort gauntlet rather than a
full round robin.bracket- engine.ts won't guess a winner from an equal score; the admin re-enters a
decisive score (verified live during this build: HF2 briefly landed on 4–4
and downstream rounds correctly showed "TBD" until corrected).