BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2 或任何藍牙控制器,搭配 MyWhoosh、Rouvy、Zwift 等。iOS、Android、Windows、macOS 均可免費試用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗This project is a very simple football app that stores player data in a local SQLite database.
Install dependencies:
npm install
Start the app:
npm start
Open:
http://localhost:3000
server.js - Express server and SQLite database setuppublic/index.html - frontend pagepublic/app.js - frontend logicpublic/styles.css - stylingdata/football.db - database file created automaticallyThe design is documented in docs/SOLUTION_DESIGN.md (Solution Design Document) and docs/SYSTEM_SPEC.md (functional specification). Both include the versioning policy. Current release: 4.0. The version is shown at the bottom of the front page.
Every file in supabase/ grants the page access to its tables. Supabase no longer does this automatically for tables created from 30 October 2026, so any new table needs the same grant line.
index.html in the project root is the football organisation page. It is published with GitHub Pages and saves its data to Supabase.
The page can write the weekly WhatsApp message for you.
Before the game, open Availability message on Run game (tap Show). Choose Monday or Thursday, check the date, time and venue, then Copy for WhatsApp or Open WhatsApp. WhatsApp doesn't let a link create a poll, so add the poll in the group yourself (📎 → Poll).
After you build a squad on Run game, a WhatsApp message card appears under it. It also shows on the confirmation screen.
Set the date, time and venue, and tick Pitch has been booked if you've booked it. The message preview updates as you move players around.
The message lists the day, date, time, venue, player count and squad, followed by any reserves.
Copy for WhatsApp copies the message so you can paste it into the group. Open WhatsApp opens WhatsApp with the message filled in.
In the game log, each game has a WhatsApp update button that writes the same message for that game.
The time and venue are remembered separately for Monday, Thursday and ad hoc games, and the pitch-booked tick is remembered too. These settings are saved on your device only, not in the database.
The Money tab tracks payments, the pitch cost and the kitty. Organisers see everything. Players (View) see only Your balance: what they owe, who to pay, and any credit, for the name picked on their phone.
Each player pays £8.50 and the pitch costs £80. Anything collected over the pitch cost is the surplus: 10% of it goes to admin and the rest to the kitty. If too few pay to cover the pitch, the shortfall comes out of the kitty. These amounts can be changed on the Money tab, and changes apply to games booked after that.
The money is held by Neal, Kev or Gav. A new game's money isn't tracked until you're ready: on the Money tab, press Track money on the game. The organiser chosen on Run game is used by default; that person collects the money and pays for the pitch, and the price and pitch cost are taken from the settings at that moment. Once a game is tracked you can change its organiser, tick who has paid, or mark everyone as paid.
The kitty is one total, and the Money tab also shows how much of it each organiser holds. Next to it, Still owed shows money players haven't paid yet and what the kitty will be once it's collected, and each organiser's card shows what's still owed to them. The 10% admin share is taken off each game but not displayed. The How each game is split settings are hidden until you press Show. Enter what each of them held before the app under Starting balances. These are hidden until you press Show starting balances, and each device remembers whether they're shown.
Record kitty spends (dinner, drinks, football) with who paid them. The Kitty ledger lists every pound in and out with a running balance.
The Games list only shows games that still need something: money still owed, or a recent game whose money isn't tracked yet. Once everyone in a game has paid it drops off the list; Show paid games shows every game so you can look back or untick a payment. A game with fewer than 10 playing is cancelled, so it isn't chased for money: it's kept behind Show paid and cancelled games, with Track anyway in case it went ahead. The Kitty ledger shows the latest 15 rows (Show full ledger for the rest). Paid games still count in every total. The History game log also shows the latest 5 games with a Show older games button.
A game only counts towards the kitty and Still owed once its money is tracked. Games added by hand can be tracked straight away by choosing an organiser in the add-game form.
Outstanding Payments and Credit are two buttons at the top of the Money tab.
Setup (once): run supabase/credit.sql in the Supabase SQL Editor for the credit list. Until then, credit is saved only on the device where it was entered.
Setup (once): run supabase/money.sql in the Supabase SQL Editor to create the money tables. Until then, money is saved only on the device where it was entered, and the Money tab shows a notice.
Teams are picked on the Teams tab, separately from the squad, so you can wait until closer to kick-off.
A game with fewer than 10 is off. The app handles that in three places:
A cancelled game stays in the Game Log with a Game cancelled badge, but doesn't count towards games played, attendance, the league or late arrivals, and nobody pays for it. Its reserves keep their place for the next game. Undo cancel puts it back and tells everyone it's back on. Players see "✕ Thursday's game is off" on the front page.
Setup (once, for 4.0): run supabase/cancel.sql in the SQL Editor, then redeploy the notify function with the new supabase/functions/notify/index.ts (Verify JWT off).
Mark anyone who turned up late with the ⏰ Late button next to their name in the History game log, or the ⏰ on their name on the Teams tab. The game log shows how many were late.
The next time a squad is picked that they're available for, late players are picked after everyone else who isn't guaranteed. So if the game is full, they're the first to become reserves. Run game marks them Late last time and says who was moved down. Players on the guaranteed list, and last game's reserves who were promised a place, still get in. Once a later game includes them, as playing or reserve, the penalty is cleared.
Setup (once): run supabase/late.sql in the Supabase SQL Editor. Until then, late arrivals are saved only on the device where they were marked.
The Ratings tab is where organisers score each player from 1 to 10 on Attack, Defence, Fitness and Goalkeeping. Tap a player to change their scores. Overall is the average of Attack, Defence and Fitness. The position (Defender, Striker or Anywhere) is worked out from Attack and Defence unless you choose one. Everyone has a Goalkeeping score in case there aren't enough keepers; switch on Regular keeper for your keepers. Players who haven't been scored yet start from their old 1–5 star rating: each skill is the stars × 2, Goalkeeping starts at 7 for keepers and 5 for everyone else, and new players start at 6. Team rules keep two players apart or always put them on the same team. Ratings only change when an organiser changes them. The tab isn't shown in View mode, but like the rest of the data, the ratings aren't truly private.
After a game, open it in the History game log and enter the score under the teams. The game log then shows the score, or Score needed for a played game with no score yet. The winning team is marked Won. The Player Stats tab lists every player's games played, won, drawn and lost, with their win percentage, most games first. It only counts games with confirmed teams and a score. The Attendance tab, for organisers only, shows each player's appearances Before 2026, in 2026 and in Total, plus how many times they've been a reserve. Appearances from before the app come from the old spreadsheet (stored in the page as LEGACY_APPS) and are added to the games recorded in the app. They're matched by name, so a player from the old spreadsheet who isn't in the app yet shows their numbers as soon as they're added with the same name. Below the table, Legacy Player Data (closed until you tap Show) lists every name from the old spreadsheet with their figures and a ✓ for those already in the app. The Game log (CSV) export includes both teams, who wore the bibs and the score, ready for further analysis.
Setup (once): run supabase/teams.sql and supabase/skills.sql in the Supabase SQL Editor. They create the tables for ratings, skill scores, team rules, and each game's teams and score. Until then, these are saved only on the device where they were entered, and the Teams and Ratings tabs show a notice.
The page can be installed on a phone as Brent Football, with its own icon on the home screen.
In the browser, the front page shows a Welcome card with these steps and an Install app button (Chrome on Android) until you install it or tap Continue in the browser. The Notifications page also has an Install the app section until it's installed.
It opens full screen with no address bar, and shows the last data even with no signal. It's the same site, so every update reaches the app automatically. The icon files are in icons/, and manifest.webmanifest and sw.js make it installable.
Players can get notifications on their phone from the installed app. They're told when they're picked or are a reserve, which team they're on, and when they owe money.
Setup (once): until this is done, the Notifications page and options don't appear.
supabase/push.sql in the Supabase SQL Editor.notify, paste the whole of supabase/functions/notify/index.ts, and press Deploy.supabase/push-cron.sql in the SQL Editor for the automatic daily reminders. If it says the extensions can't be created, turn on pg_cron and pg_net under Database → Extensions, then run it again.If the Notifications page doesn't appear, the 🔔 line at the top of Setup says why. If a test says "Received on this phone" but no banner pops up, the phone is showing them silently: on Samsung, long-press the notification in the panel, tap Settings, then choose Alert and Show as pop-up.
There's no key to create or paste: the function makes its own notification keys the first time it runs. The phones and keys are kept in tables the page can't read. As with the rest of the app, there's no sign-in, so anyone could pick another name under "Who are you?".
Players can say whether they're in for the next game in the app. At closing time the squad is picked automatically with the usual Run game rules. It's switched off until an organiser turns it on.
Setup (once):
supabase/availability.sql in the SQL Editor.notify function. Open its Code tab, paste the whole of the new supabase/functions/notify/index.ts, and press Deploy. Keep Verify JWT off. The function has its own copy of the squad rules from selection.js, so if a rule ever changes, both files must change.supabase/schedule-3.8.sql. It runs the automatic check only from 8am to 10:45pm UK time (so opening and closing times must be in that window) and clears old schedule history each night. The app also checks for new answers less often when no round is open, which keeps Supabase traffic low.Once a phone has picked its name, the front page says Hi {name} with what matters to them: playing or reserve, whether they've said in, and what they owe. Not you? changes the name. Organisers start on the Dashboard, which greets them too and shows the next game (live availability counts or the saved squad), a to-do list with a button for each job, money, who's on the app, turnout over the last 12 games (just the numbers), a league table for the year (3 points a win, 1 a draw), and this season's most games and best win %. On a phone the organisers' bar is Dashboard, Run game, Teams and Payments, with More for the other pages, including Game Log. On a computer the pages are a row of tabs along the top. In View mode only Game Log, Player Stats and Payments are shown, plus Notifications once they are set up.
The Payments tab (called Money before) holds Outstanding Payments, credit, the kitty, games and the ledger.
The page opens on a front page showing the next game (date, time, venue, organiser and squad) and the kitty, with two buttons:
The password is checked inside the page, so this stops accidental changes but isn't real security: the site's code and database key are public.
Behind the front page there is no database sign-in: the database itself still accepts changes from anyone with the link. If saving stops working because the database has stricter rules, run supabase/policies.sql in the Supabase SQL Editor to open the tables back up.
Each save sends only the players and games that changed since the last successful save. A device with an out-of-date copy can't delete rows it never saw. If two organisers edit the same player or game, the later save wins for that row.
This is a basic example for learning. For a real app, you would usually add: