Registre
Inscrit
2026-09-29
Premier commit
2026-09-30

Séance

App · entraînement · installable, hors ligne

Un manuel d’entraînement qui marche hors ligne et se souvient de tout, sur l’appareil seul.

Un programme au poids du corps dessiné comme un manuel de gymnastique, une planche par mouvement. Il guide une séance de trente minutes, tient un journal et trace les courbes de progrès — installable, hors ligne, avec des rappels, et chaque chiffre gardé sur l’appareil.

  • TypeScript
  • React
  • PWA
  • Workbox
  • IndexedDB
  • Vitest
Ouvrir en ligne (s’ouvre dans un nouvel onglet)Code source (s’ouvre dans un nouvel onglet)
Livré29 · IX · 2026
Dessin : un téléphone affichant une planche de mouvement d’une séance, marquée hors ligne et enregistrée sur cet appareilPLANCHE · MOUVEMENTPompesSérieReposEXERCICE SUIVANTHORS LIGNEchaque route répondSUR L’APPAREILchaque chiffre, rien qu’iciJOINTURES, PAS TRACÉS37 figures, chaînéesdepuis la hanche
Dessiné pour ce registre, pas une capture
Inscrit
2026-09-29Livré
Premier commit
2026-09-30Séance, a bodyweight training PWA drawn as a gymnastics manual
Commits
4sur main, lus le 2026-10-02
Couverture
14 %lignes exécutées par les tests unitaires de l’app, lues le 2026-10-02
Paquets maison
10 sur 11installés depuis npm

Ce qui est livré

  1. Installable et entièrement hors ligne : un service worker Workbox écrit à la main met toute l’app en cache, et chaque route répond réseau coupé, séance en cours comprise.
  2. Des rappels sans serveur : une horloge dans l’app, les Notification Triggers là où ils existent, et le Periodic Background Sync qui lit le planning dans IndexedDB depuis le worker — et l’écran de réglages dit franchement ce que ce navigateur sait faire.
  3. Des graphiques de progression dessinés à la main en SVG et HTML : régularité comptée en semaines, volume par semaine, tour de taille et poids jamais sur un même axe, chacun parcourable par un input range natif invisible et doublé d’un tableau.
  4. Chaque chiffre reste sur l’appareil : une sauvegarde JSON le transporte ailleurs, et un profil spécimen généré à graine montre les graphiques pleins sans jamais toucher aux données du lecteur.
  5. Trente-sept figures animées dessinées à partir d’articulations, pas de tracés : l’interpolation est polaire et chaînée depuis la hanche, pour qu’aucun os ne s’étire en plein mouvement.

Comment ça marche

zéro serveur, tout en cache sur l’appareil

Schéma : dans l’appareil, la coque de l’app est précachée par un service worker et chaque chiffre vit dans IndexedDB ; le réseau est coupé et il n’y a pas de serveurCet appareilCoque de l’appprécachéeService workerWorkbox · rappelsIndexedDBchaque chiffreSans serveurréseau coupéSauvegarde JSONla seule sortie

Tel que le compilateur le lit

Mis en page comme dans un éditeur : une ligne ondulée est un build qui refuse, une ligne violette est ce que le compilateur déduit tout seul.

  1. reminder-schedule.ts
    Compile0 erreur
    export const isReminderOwed = ({
      lastSessionDay, lastShownDay, now, schedule, today
    }) =>
      schedule.isEnabled &&
      schedule.days.some((day) => day === now.getDay()) &&
      now.getTime() >= reminderOn(now, schedule.time).getTime() &&
      lastShownDay !== today &&
      lastSessionDay !== today
    

Historique

Tiré du git log, abrégé, et laissé dans sa langue : 4 commits sur 4, du plus récent au plus ancien.

  1. Deploy the public demo from CI on every push to main
  2. Deploy the public demo to Cloudflare Pages from a clean clone
  3. Deploy the private build to Netlify on push to main, drop Cloudflare Pages
  4. Séance, a bodyweight training PWA drawn as a gymnastics manualPremier commit

Installe

10 des 11 paquets maison, depuis npm, jusqu’aux réglages du compilateur et du linter.

Votre équipe, 2026

Je cherche mon prochain poste. Écrivez-moi, ou prenez le CV : un mis en page, et un sobre pour les logiciels de recrutement.