Skip to content

fix(coach): the consent screen and the intake questions in the app's language - #415

Open
kurktchiev wants to merge 4 commits into
DuarteSantos8:mainfrom
kurktchiev:gh/consent-strings-i18n
Open

kurktchiev wants to merge 4 commits into
DuarteSantos8:mainfrom
kurktchiev:gh/consent-strings-i18n

Conversation

@kurktchiev

@kurktchiev kurktchiev commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

The consent screen lists five data categories, a title and a line under each, from CATEGORY_TEXT in frontend/src/lib/coach.js. CoachIntake.jsx and CoachSetup.jsx ("What leaves this phone") rendered them with t(title) and t(sub). check-source-strings.mjs collects only literal t('…') calls, so it never saw these ten strings, and eight of them are in no locale pack. "Your plan" and "Body weight" were translated only because other screens use them. In German the list read "Dein Plan", "Körpergewicht" and eight lines of English.

Each CATEGORY_TEXT entry is now a function that returns literal t() calls. The checker sees all ten keys, and the text follows a language picked after coach.js loaded. Both screens call the function and render what it returns. A category the app has no text for still shows its key; it no longer goes through t(), which only mattered if a pack had that exact word.

The eight strings are translated in all 16 packs, right after the consent paragraph ("It designs your plan…"). Each pack's register and terms come from its own consent screen and intake questions. Three choices a native speaker may want to check:

  • fr.js mixes tu and vous on this screen. The paragraph above the list says tu, the fine print under it says vous, and the first row is "Votre plan". The seven new French lines that address the user say tu (fourth commit), because fix(i18n): the French pack says tu to the user throughout #413 moves the whole pack to tu, "Votre plan" included. Until that PR lands, "Votre plan" sits over a line that says tu.
  • pt-BR overrides all eight (você, registrar, configurações). "A few preferences" is "Algumas preferências" in both, and is pinned as an override so the five rows are reviewed together. The pt-BR inheritance fingerprint does not change.
  • de says "Gewichtseinheit" for the unit, because the pack uses "Einheit" for a training session.

ko, zh and th say "progression settings" with each pack's own word for Progression (점진적 증가 설정, 进阶设置, การตั้งค่าการเพิ่มระดับ).

uk.js: the two sign-in-hold strings ('Waiting for your answer about this device’s workouts' and 'Nothing syncs until you say whether this device’s workouts go into your profile. Tap to answer.') said "ви" and "торкніться". They say "ти" now, and «Натисни, щоб відповісти.», like the "Not synced yet" banner that shows in the same place.

The second commit fixes the same bug on the intake questions. CoachIntake.jsx renders the goal and experience choices from GOALS and EXPERIENCE with t(label) and t(sub), and the eight lines under the choices ('Heavier lifts, lower reps.', 'You know the movements; the numbers need rebuilding.' and the rest) are in no pack. In German the goal screen offered "Stärker werden" over "Heavier lifts, lower reps." Each choice's text is now a function of literal t() calls, like CATEGORY_TEXT, and the eight lines are translated in all 16 packs, right after 'Training regularly'. The lines were translated by Claude and no native speaker has checked them. Choices a native speaker may want to check:

  • fr.js mixes tu and vous on this screen too ("Quel est votre objectif ?" over "Choisis-en une pour continuer."). The fourth commit puts two of the French lines in tu: "Tu connais les mouvements ; les charges sont à remonter." and "Garder ta force en t’affinant." ('Keep strength while leaning out.'). The other six use no pronoun, as in English.
  • "The numbers need rebuilding" is translated as the loads or the strength coming back up in most packs ("die Kraft muss erst wieder aufgebaut werden", "i carichi vanno recuperati"), because "numbers" word for word reads oddly there. ru, uk, tr and ar keep "the numbers".
  • pt-BR overrides all eight. The gym line says academia and the returning-lifter line says você; the other six are the pt-PT wording, pinned as overrides so the fingerprint does not change.

I wrote the 16 zh-TW lines during the rebase. @nauish, since you added the pack in #368, could you check them?

CoachSetup.jsx's three progress lines ('Loading the exercise catalogue…', 'Checking the endpoint…', 'Ready') also went through t(s) over a list. Every pack has them, so the screen does not change; they are literal calls now, so the checker notices if one goes missing.

Two variable calls stay on the intake: the weekday buttons (t(DAYN[d])) and the equipment chips (t(e)). Both lists come from shared modules (lib/format.js and the exercise library) that other screens translate the same way, and every pack has all their entries.

The third commit removes 'e.g. “swap the squats for split squats, and Mondays are short”' from every pack. git grep finds the key only in the locale packs, so no screen shows it. pt-BR overrode it, so the inheritance fingerprint does not move. The fourth moves the new French lines to tu, as described above.

Tests:

  • CoachIntake.test.jsx: +2. The first renders the consent screen in German and expects each row to be de.js's line. It fails with the old packs, and it fails if CATEGORY_TEXT is translated once when the module loads. The second renders the goal and experience screens in German and expects each title and line to be de.js's. It fails when a line is missing from de.js.
  • CoachSetup.flow.test.jsx reads the titles through the new function, and its check of the three progress lines passes unchanged.
  • Also run and passing with all four commits: CoachSetup.test.jsx, CoachSetup.cleartext.test.jsx, coach.test.js, pt-br-locale.test.js, locale-coverage.test.js, i18n-core.test.js, scripts/check-locales.test.mjs.
  • The whole frontend suite passes with all four commits on 39bc71e.
  • check-source-strings.mjs --strict: 1581 strings, all in the packs. It counts 1555 on main: the first commit adds the eight consent lines, the second the eight intake lines, the eight choice titles and two of the progress lines, none of which it could see before. check-locales.mjs: 17 locales, 1994 keys each.

Overlap: #352 changed the training line in the same CATEGORY_TEXT and landed in v1.3.10. This PR uses #352's wording ("…and your session notes") and translates it in every pack. The third commit conflicts in one place in fr.js with #413, which changes the three lines above the example line this PR deletes. The resolution keeps that PR's three lines and drops the example line. Every other open PR that touches these files merges with this one as cleanly as it merges with main (checked with git merge-tree). This branch merges cleanly with #414.

🤖 Generated with Claude Code

kurktchiev and others added 4 commits October 7, 2026 12:42
The consent screen lists five data categories from CATEGORY_TEXT in
lib/coach.js. CoachIntake.jsx and CoachSetup.jsx passed them to t() as
variables, which check-source-strings.mjs cannot see, and eight of the
ten lines had no translation in any pack. Each entry is now a function
of literal t() calls, and the eight lines are translated in all 16
packs, with pt-BR overrides.

uk.js: the two sign-in-hold lines said ви; they say ти now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
CoachIntake.jsx rendered the goal and experience choices from GOALS and
EXPERIENCE through t(label) and t(sub). check-source-strings.mjs cannot
see variables, and the eight lines under the choices ('Heavier lifts,
lower reps.' and the rest) had no translation in any pack. Each choice's
text is now a function of literal t() calls, as CATEGORY_TEXT is after
the previous commit, and the eight lines are translated in all 16 packs,
with pt-BR overrides.

CoachSetup.jsx's three progress lines were a list passed to t(s). They
are literal calls now; every pack already had them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
'e.g. “swap the squats for split squats, and Mondays are short”' is
translated in every pack, and nothing in src/ asks for it: git grep
finds the key in the locale packs only. The line is removed from every
pack.

pt-BR overrode it, so its inheritance fingerprint does not move.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The first two commits wrote the French consent rows in vous, to match
«Votre plan» above them, and the intake lines without a pronoun,
because fr.js mixed tu and vous on both screens. The French pack is
moving to tu throughout in a separate PR, which makes the first row
«Ton plan». The lines say tu now: «ton planning hebdomadaire et tes
réglages de progression», «Ton entraînement enregistré», «Les séries
que tu as enregistrées…», «Ce que tu dis au Coach». 'You know the
movements; the numbers need rebuilding.' is «Tu connais les
mouvements ; les charges sont à remonter.», and 'Keep strength while
leaning out.' is «Garder ta force en t’affinant.» Only the register
changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@kurktchiev
kurktchiev force-pushed the gh/consent-strings-i18n branch from 9c22c76 to 8671d8e Compare October 7, 2026 17:25

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant