OpenAthlete
AGPLv3 endurance training platform: EU-oriented hosting, transparent CTL/ATL/TSB logic in code, self-hosting, and full export. Built in Grenoble.
Classements, résultats, calendriers, buteurs et actualités de la Premier League, La Liga, Serie A, Bundesliga et Ligue 1.
Translation pending
Sports & fitnessTypeScript · CSSGitHub @LaFicelleCmoiOnlineOwner 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
Loading the full README. The saved excerpt is shown below.
Les 5 grands championnats européens réunis sur un seul site : Premier League (Angleterre), La Liga (Espagne), Serie A (Italie), Bundesliga (Allemagne) et Ligue 1 (France). • Chiffres clés : nombre de clubs, matchs et buts du jour, buts au total en saison régulière avec la moyenne par matchRead the full README ↗
Les 5 grands championnats européens réunis sur un seul site : Premier League (Angleterre), La Liga (Espagne), Serie A (Italie), Bundesliga (Allemagne) et Ligue 1 (France).
Leurs deuxièmes divisions ont aussi leurs pages : Championship (Angleterre), Segunda División (LaLiga Hypermotion, Espagne), Serie B (Italie), 2. Bundesliga (Allemagne) et Ligue 2 (BKT, France).
Pour chaque championnat :
Chiffres clés : nombre de clubs, matchs et buts du jour, buts au total en saison régulière avec la moyenne par match
Classement : points, bilan, buts, zones européennes et relégation
Matchs : scores en direct actualisés sans recharger la page, derniers résultats et calendrier des 14 prochains jours, avec les buteurs et les cartons rouges
Buteurs : meilleurs buteurs et passeurs décisifs
Actualités : derniers articles ESPN
La page d'accueil réunit les chiffres clés (dont le total de buts de la saison régulière des 5 championnats et la moyenne par match), le badge 3D « Pass supporter », les raccourcis vers chaque championnat, le bandeau des 96 clubs, les matchs du jour et le top 5 de chaque classement.
Deuxièmes divisions (/deuxiemes-divisions) : un espace à part, pour ne pas les confondre avec les 5 grands. Le sélecteur « D1 | D2 » de l'en-tête passe d'un espace à l'autre, et la barre de logos ne montre que les championnats de l'espace affiché ; un bandeau sombre en bas de l'accueil et une colonne du pied de page y mènent aussi. Leurs pages portent la mention « 2e division » et un lien de retour vers leur accueil, construite sur le même modèle (LeaguesHome) : chiffres clés, raccourcis, bandeau des clubs, matchs du jour et top 5 des classements. Chacune a les mêmes onglets qu'un grand championnat (classement, matchs, buteurs, actualités) ; le classement montre les zones de montée directe, de barrage de promotion et de relégation. Leurs clubs ont leur palmarès. La recherche de club ne propose que les clubs de l'espace affiché, et chaque espace a son propre club favori (pass supporter, « Mon club », étoile dans les classements) : un parmi les 5 grands, un autre parmi les deuxièmes divisions. Le Direct et les cartes de match mettent en avant les deux.
Forme d'un club : un clic sur un club, dans le bandeau ou dans les classements, ouvre ses 5 derniers matchs officiels (toutes compétitions), avec victoire / nul / défaite, score, adversaire, lieu et compétition.
Thème clair ou sombre : un bouton dans l'en-tête (et une ligne dans le menu mobile) fait le tour des trois réglages — système, clair, sombre. Le choix est mémorisé dans le navigateur et appliqué avant la première peinture : une page réglée en sombre ne s'affiche jamais en clair au chargement. Sans choix explicite, le site suit le réglage de l'appareil.
Club favori : chaque visiteur peut choisir son club (mémorisé dans le navigateur, sans compte). Il a droit à un traitement spécial : section « Mon club » sur l'accueil (place au classement, forme, match du jour en direct ou prochain match), logo sur le badge 3D, étoile dorée et ligne ambrée dans les classements, cadre doré sur ses matchs, célébration quand il marque en direct et fiche « Votre club » dorée.
Trackers des coupes d'Europe 2026-2027 : sur l'accueil, un carrousel à trois bannières — Ligue des champions, Ligue Europa et Ligue Conférence — mène chacune au tracker de la compétition sur ldc-2026-2027.vercel.app (projet indépendant, ouvert dans un nouvel onglet). Chaque bannière porte le logo de sa coupe, posé directement dessus : les logos officiels sont noirs, donc fournis en version blanche à fond transparent (l'orange d'Europa et le vert de la Conférence sont conservés), sans quoi ils se perdraient sur le fond sombre. Le défilement est celui du navigateur (doigt, molette, clavier), avec des pastilles pour choisir une coupe et des flèches sur grand écran ; pas de lecture automatique. La pastille « LDC » de l'en-tête et les adresses courtes /ldc et /ligue-des-champions mènent au tracker de la Ligue des champions.
Onglet Coupes nationales (activable) : un interrupteur « Coupes » dans l'en-tête affiche un onglet dédié à la FA Cup, la Copa del Rey, la Coppa Italia, la DFB-Pokal et la Coupe de France. Chaque coupe a sa page (/coupes/[coupe]) : frise des tours, prochains matchs et résultats par tour (aller-retour, tirs au but), exploits des petits poucets face aux clubs de première division, et dernière finale quand l'édition suivante n'est pas encore programmée.
Calendrier officiel des coupes 2026-27 : ESPN ne publie un tour qu'une fois tiré et ignore les qualifications (la FA Cup et la Coupe de France 2026-27 n'y figurent pas encore). Le calendrier des fédérations (FA, FFF, RFEF, Lega Serie A, DFB), relevé via Wikipédia et recoupé avec ESPN, OpenLigaDB et TheSportsDB, complète la frise et un tableau détaillé : dates, tirages, nombre de matchs, clubs en lice, entrées en lice, dotations de la FA Cup et stades des finales. Les jours réels des matchs publiés par ESPN remplacent les dates prévues. La page /coupes ajoute les prochaines échéances et le compte à rebours des finales.
Compte à rebours avant le coup d'envoi : dans les 3 jours qui précèdent un match (championnat, coupe nationale ou coupe d'Europe), un compte à rebours à la seconde apparaît sur les cartes de match, dans la fiche du club (prochain match, affiche européenne comprise), dans la section « Mon club » et sur les cartes des coupes. Il passe à l'ambre dans les dernières 24 h, au rouge dans la dernière heure, puis annonce un coup d'envoi imminent jusqu'au passage en direct. Une seule horloge partagée, calée sur la seconde, en pause quand l'onglet est masqué.
Synchronisation avec le direct : les scores en direct et les fiches des clubs ne passent plus par le Data Cache de Next.js (qui renvoyait encore l'ancienne version pendant sa mise à jour, soit un rafraîchissement de retard) mais par une copie en mémoire de quelques secondes et le CDN. Les matchs de la veille restent suivis après minuit, et un match resté « à venir » est interrogé jusqu'à ce qu'ESPN le lance. Une page servie depuis le cache recharge ses données dès qu'elle a plus de 90 s. Les coupes nationales ont leurs scores en direct, et la fiche du club comme « Mon club » affichent le match en cours avec son score, relu toutes les 30 s.
Calendrier stocké dans le site, direct ESPN : l'organisation du site (quels matchs, dates, stades, tours des coupes) vient de src/data/calendrier/, relevé chaque nuit chez ESPN par scripts/sync-calendar.mts (GitHub Action calendrier.yml, un commit par fichier modifié). Les pages s'affichent donc même si ESPN ne répond pas ; ESPN n'apporte que l'état des matchs : score, minute, buts, cartons jaunes et rouges. Lancer le relevé à la main : npm run calendrier.
Détails du match : bouton sur chaque carte de match, avec tout ce qu'ESPN fournit, en français — chronologie complète (buts et passeurs, penaltys marqués, manqués ou arrêtés, contre-son-camp, cartons et motifs, remplacements, VAR, arrêts de jeu, périodes), 28 statistiques comparées, compositions (schéma, titulaires, remplaçants, entrées et sorties), arbitres, stade, affluence, diffuseurs et commentaire minute par minute (en anglais). Relu toutes les 30 s pendant le match.
Interface adaptée au calendrier : les jours sans match (trêve, milieu de semaine), les chiffres du jour laissent la place à la prochaine journée (jours restants, nombre de matchs sur la journée) et aux points du leader, et l'accueil montre les prochains matchs au lieu d'un encadré vide. La page Matchs est en grilles pleine largeur et reprend la dernière journée jouée quand rien n'a eu lieu depuis 7 jours. Les réglages (onglet Coupes, thème) sont regroupés dans un menu, le badge 3D est réservé aux grands écrans et le pied de page donne accès à toutes les rubriques.
Direct toutes compétitions (/direct) : tous les matchs d'une journée — Ligue des champions, Ligue Europa, Ligue Conférence, les 5 championnats, les 5 coupes nationales, puis les deuxièmes divisions — groupés par compétition, avec le direct, des filtres (en direct, à venir, terminés, mon club) et la navigation hier / aujourd'hui / demain.
Avant-match : dans « Détails du match », la forme des deux équipes (5 derniers matchs, toutes compétitions) et les confrontations directes avec leur bilan.
Application installable (PWA) : manifeste, icônes et service worker. Le site s'installe sur l'écran d'accueil et s'ouvre en plein écran ; hors connexion, une page dédiée s'affiche. Aucune donnée n'est mise en cache : les scores viennent toujours du réseau.
Images sans coût Vercel : l'optimisation d'images de Vercel est désactivée ; logos et photos d'actualité sont redimensionnés par ESPN lui-même (service « combiner »), au double de leur taille d'affichage. Un logo pèse quelques kilo-octets au lieu de 25 Ko, et aucune transformation n'est facturée.
Recherche de club : une barre de recherche dans l'en-tête (raccourci clavier /, insensible aux accents, navigation au clavier) mène à la page d'un club : bilan de la saison, prochain match, palmarès complet (nombre de titres par trophée, première et dernière année) et déroulé de la saison en cours, mois par mois, toutes compétitions — championnat, coupes nationales et coupes d'Europe.
Palmarès : relevé sur Wikidata (chaque saison de compétition y désigne son vainqueur) par scripts/sync-palmares.mts, une fois par semaine (GitHub Action palmares.yml). Les anciens noms d'une même compétition sont regroupés (« First Division » et « Premier League » comptent ensemble) et le titre de deuxième division compte parmi les titres nationaux. En Angleterre, l'année tranche le niveau : la « First Division » est la deuxième division de 1993 à 2004, la « Second Division » l'était jusqu'en 1992. Les clubs promus ou relégués sont cherchés dans tous les championnats de leur pays, les sections football allemandes ramenées à leur club, et les équipes réserve écartées. Divisions inférieures et coupes régionales apparaissent sous « Autres trophées ». Lancer le relevé à la main : npm run palmares.
| Rôle | Outil |
|---|---|
| Framework | Next.js 15 (App Router, Server Components) |
| Langage | TypeScript |
| Style | Tailwind CSS 4 |
| Icônes | Lucide React |
| Animations | React Bits + motion, three.js / React Three Fiber pour le badge 3D |
| Données | API publique ESPN |
| Hébergement | Vercel |
src/
├── app/
│ ├── page.tsx Accueil (5 grands championnats)
│ ├── deuxiemes-divisions/ Accueil des deuxièmes divisions
│ ├── icon.svg, apple-icon.png Favicon et icône iOS
│ ├── api/live/[league]/ Scores en direct (JSON) pour le navigateur
│ ├── api/teams/[league]/[team] 5 derniers matchs d'un club (JSON)
│ ├── coupes/ Onglet Coupes nationales : /coupes et /coupes/[coupe]
│ └── [league]/ premier-league, la-liga, serie-a, bundesliga, ligue-1,
│ championship, segunda-division, serie-b, 2-bundesliga, ligue-2
│ ├── layout.tsx En-tête du championnat + onglets
│ ├── page.tsx Classement
│ ├── matchs/page.tsx Direct, résultats, calendrier
│ ├── buteurs/page.tsx Buteurs et passeurs
│ └── actualites/page.tsx Actualités
├── components/
│ ├── reactbits/ Composants React Bits adaptés au projet
│ ├── LiveMatches.tsx Actualisation des scores en direct
│ ├── ClubsLoop.tsx Bandeau des clubs cliquable
│ ├── ClubDialog.tsx Fenêtre « 5 derniers matchs »
│ ├── ClubDialogProvider.tsx Fenêtre partagée, ouvrable depuis n'importe quel club
│ ├── HeroBadge.tsx Badge 3D (chargement différé, version fixe de secours)
│ └── … Tableaux, cartes de match, logos, navigation
└── lib/
├── leagues.ts Configuration des 5 championnats et de leurs deuxièmes divisions
├── cups.ts Configuration des 5 coupes nationales (tours et dates en français)
├── cup-calendar.ts Calendrier officiel 2026-27 des coupes, fusionné avec les données ESPN
├── cups-tab.ts Interrupteur de l'onglet Coupes, mémorisé dans le navigateur
├── calendar.ts Calendrier stocké dans le site (matchs, dates, stades, tours)
├── clubs.ts Index des clubs de tous les championnats (barre de recherche)
├── palmares.ts Palmarès des clubs relevé sur Wikidata
├── countdown.ts Horloge partagée des comptes à rebours avant le coup d'envoi
├── team-form.ts Fiche d'un club côté navigateur, relue toutes les 30 s pendant ses matchs
├── live.ts Règles du suivi en direct (quels matchs, quand)
├── favorite-club.ts Club favori mémorisé dans le navigateur
├── theme.ts Thème clair / sombre mémorisé dans le navigateur
├── favorite-card.ts Recto du badge dessiné avec le club favori
├── standings-style.ts Couleurs partagées des classements
├── types.ts Modèles normalisés utilisés par l'interface
├── format.ts Dates en français (heure de Paris)
└── espn/
├── client.ts fetch serveur + cache Next.js (server-only)
├── types.ts Typage des réponses JSON d'ESPN
└── api.ts Normalisation : JSON ESPN → modèles de l'app
public/
├── coupes-europe/ Logos des trois coupes d'Europe, pour le carrousel de l'accueil
└── lanyard/ Modèle 3D du badge, recto, verso et sangle
Les appels à ESPN sont faits uniquement côté serveur (import "server-only"). Le navigateur ne reçoit que du HTML ou le JSON de nos propres routes : l'URL de l'API n'apparaît jamais côté client.
Chaque requête passe par le Data Cache de Next.js, et chaque page est régénérée en ISR. ESPN n'est donc interrogé qu'une fois par période, quel que soit le nombre de visiteurs :
| Donnée | Cache |
|---|---|
Scores en direct (/api/live/[league]) | 15 s + 10 s sur le CDN Vercel |
| Pages matchs / accueil | 60 s |
| Classements | 5 min |
5 derniers matchs d'un club (/api/teams/…) | 10 min + 5 min sur le CDN Vercel |
| Buteurs, actualités | 15 min |
Si ESPN ne répond pas, une page d'erreur propose de réessayer. Sur l'accueil, une ligue indisponible n'empêche pas l'affichage des autres.
/api/live/[league] toutes les 20 secondes. Seuls les championnats concernés sont interrogés.Huit composants de React Bits (licence MIT + Commons Clause) sont copiés dans src/components/reactbits/, en variante TypeScript + Tailwind. Chaque fichier indique en en-tête ce qui a été adapté ("use client", respect du réglage « réduire les animations », corrections, etc.).
| Composant | Utilisation |
|---|---|
| Lanyard | Badge 3D « Pass supporter » accroché à sa sangle, personnalisable avec le club favori |
| PixelCard | Raccourcis vers les championnats, pixels aux couleurs de chaque ligue |
| SplitFlapText | Panneau d'affichage des championnats sur les deux accueils |
| CountUp | Chiffres clés de l'accueil |
| LogoLoop | Bandeau défilant des clubs (clic pour la forme du club) |
| SpotlightCard | Halo aux couleurs de la ligue sur les cartes top 5 |
| StarBorder | Bordure animée de la bannière Ligue des champions |
| ShinyText | Minute de jeu des matchs en direct |
Le badge 3D (three.js et moteur physique Rapier) n'est téléchargé que lorsqu'il approche de la zone visible. Son modèle public/lanyard/card.glb a été allégé (texture intégrée remplacée par un aplat, de 2,4 Mo à 177 Ko) : le recto, le verso et la sangle sont des images séparées, et le recto du club favori est dessiné dans le navigateur.
Pour ajouter un championnat, il suffit d'ajouter une entrée dans src/lib/leagues.ts (code ESPN, par exemple ned.1 pour l'Eredivisie).
Le fichier .mcp.json déclare le serveur MCP de shadcn pour Claude Code. Il permet de chercher et d'ajouter des composants des registres shadcn, dont React Bits (@react-bits). Claude Code demande de l'approuver au premier lancement dans le projet.
Il est épinglé sur shadcn 3.8.5 : les versions 4.x exigent Node.js 20.18 ou plus récent. Après une mise à jour de Node, on peut revenir à shadcn@latest (commande d'origine : npx shadcn@latest mcp init --client claude).
Node.js 18.18 ou plus récent est requis.
npm install
npm run dev
Le site est alors disponible sur http://localhost:3000.
npm run build # build de production (vérifie aussi les types et le lint)
npm run start # sert le build de production
Site non officiel, sans lien avec les ligues ni les clubs. Données fournies par ESPN.