From c1911e71e34144e23f219c7552f4172c3a188d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 23 Oct 2026 10:46:54 +0200 Subject: [PATCH] Revert "feat(topics): add the Topics preview area, its navigation entry and its switch" This reverts commit c68e833dcc80c8092c8a1b331ffbf5052335e6b9. --- bundle-budget.json | 2 - eslint.config.mjs | 1 - messages/de.json | 185 +--------------- messages/en.json | 185 +--------------- messages/es.json | 185 +--------------- messages/fr.json | 185 +--------------- messages/it.json | 185 +--------------- messages/ko.json | 185 +--------------- messages/nl.json | 185 +--------------- messages/pl.json | 185 +--------------- messages/pt-BR.json | 185 +--------------- src/__tests__/baselines/test-as-never.json | 5 +- .../baselines/version-stamp-comments.json | 4 +- src/__tests__/settings-copy-tense.test.ts | 5 +- src/__tests__/settings-legacy-routes.test.ts | 2 - src/app/topics/[topic]/page.tsx | 24 --- src/app/topics/page.tsx | 14 -- src/components/charts/chart-runtime.ts | 1 - .../__tests__/build-index.test.ts | 11 - src/components/command-palette/build-index.ts | 4 - .../command-palette/use-palette-index.ts | 4 - src/components/labs/lab-trend-card.tsx | 43 +++- src/components/labs/lab-trend-lines.ts | 60 ------ .../__tests__/nav-model-shared-record.test.ts | 20 +- .../layout/__tests__/nav-model.test.ts | 36 ---- src/components/layout/bottom-nav.tsx | 114 ++++------ src/components/layout/global-shortcuts.tsx | 14 +- src/components/layout/nav-model.ts | 61 +----- src/components/layout/sidebar-nav.tsx | 126 ++++++++--- src/components/layout/sidebar-rail.tsx | 114 ---------- .../__tests__/preview-section.test.tsx | 60 ------ .../__tests__/settings-shell.test.tsx | 12 +- src/components/settings/preview-section.tsx | 116 ---------- .../settings/settings-section-loader.tsx | 5 - src/components/settings/settings-shell.tsx | 7 - .../topics/__tests__/topic-messages.test.ts | 62 ------ .../topics/__tests__/topic-tile.test.tsx | 85 -------- src/components/topics/preview-badge.tsx | 29 --- src/components/topics/preview-note.tsx | 22 -- src/components/topics/topic-blocks.tsx | 145 ------------- src/components/topics/topic-detail.tsx | 119 ----------- src/components/topics/topic-labs-card.tsx | 126 ----------- src/components/topics/topic-links-card.tsx | 132 ------------ src/components/topics/topic-meta.ts | 74 ------- .../topics/topic-relationships-card.tsx | 200 ------------------ .../topics/topic-side-by-side-card.tsx | 86 -------- .../topics/topic-side-by-side-chart.tsx | 153 -------------- src/components/topics/topic-summary.tsx | 98 --------- src/components/topics/topic-tile.tsx | 100 --------- src/components/topics/topic-today-card.tsx | 119 ----------- src/components/topics/topic-trends-card.tsx | 79 ------- src/components/topics/topics-overview.tsx | 104 --------- src/components/topics/topics-preview-gate.tsx | 31 --- src/components/topics/use-signal-format.ts | 146 ------------- src/components/topics/use-topics.ts | 37 ---- src/hooks/use-preview-features.ts | 14 -- src/lib/navigation/shared-record.ts | 2 - src/lib/query-keys/index.ts | 9 - src/lib/query-keys/settings.ts | 3 - src/lib/query-keys/topics.ts | 11 - src/lib/record-settings/classification.ts | 1 - src/lib/settings/section-slugs.ts | 8 +- 62 files changed, 212 insertions(+), 4313 deletions(-) delete mode 100644 src/app/topics/[topic]/page.tsx delete mode 100644 src/app/topics/page.tsx delete mode 100644 src/components/labs/lab-trend-lines.ts delete mode 100644 src/components/layout/sidebar-rail.tsx delete mode 100644 src/components/settings/__tests__/preview-section.test.tsx delete mode 100644 src/components/settings/preview-section.tsx delete mode 100644 src/components/topics/__tests__/topic-messages.test.ts delete mode 100644 src/components/topics/__tests__/topic-tile.test.tsx delete mode 100644 src/components/topics/preview-badge.tsx delete mode 100644 src/components/topics/preview-note.tsx delete mode 100644 src/components/topics/topic-blocks.tsx delete mode 100644 src/components/topics/topic-detail.tsx delete mode 100644 src/components/topics/topic-labs-card.tsx delete mode 100644 src/components/topics/topic-links-card.tsx delete mode 100644 src/components/topics/topic-meta.ts delete mode 100644 src/components/topics/topic-relationships-card.tsx delete mode 100644 src/components/topics/topic-side-by-side-card.tsx delete mode 100644 src/components/topics/topic-side-by-side-chart.tsx delete mode 100644 src/components/topics/topic-summary.tsx delete mode 100644 src/components/topics/topic-tile.tsx delete mode 100644 src/components/topics/topic-today-card.tsx delete mode 100644 src/components/topics/topic-trends-card.tsx delete mode 100644 src/components/topics/topics-overview.tsx delete mode 100644 src/components/topics/topics-preview-gate.tsx delete mode 100644 src/components/topics/use-signal-format.ts delete mode 100644 src/components/topics/use-topics.ts delete mode 100644 src/hooks/use-preview-features.ts delete mode 100644 src/lib/query-keys/topics.ts diff --git a/bundle-budget.json b/bundle-budget.json index 8ba5c61d7..0553bb199 100644 --- a/bundle-budget.json +++ b/bundle-budget.json @@ -116,8 +116,6 @@ "/settings/modules/[module]/page": 374, "/settings/page": 282, "/timeline/page": 331, - "/topics/[topic]/page": 298, - "/topics/page": 293, "/vaccinations/page": 327 } } diff --git a/eslint.config.mjs b/eslint.config.mjs index 5c0002e77..ce53edc99 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -236,7 +236,6 @@ const eslintConfig = defineConfig([ "src/components/charts/workout-elevation-chart.tsx", "src/components/insights/coach-panel/result-chart.tsx", "src/components/insights/derived/score-trend-chart.tsx", - "src/components/topics/topic-side-by-side-chart.tsx", ], rules: { "no-restricted-imports": [ diff --git a/messages/de.json b/messages/de.json index 9ef5e789e..ae2bbef23 100644 --- a/messages/de.json +++ b/messages/de.json @@ -510,9 +510,7 @@ "documents": "Dokumente", "vaccinations": "Impfungen", "mentalWellbeing": "Seelisches Wohlbefinden", - "timeline": "Zeitleiste", - "topics": "Themen", - "previewBadge": "Beta" + "timeline": "Zeitleiste" }, "auth": { "login": "Anmelden", @@ -6145,10 +6143,6 @@ "access": { "title": "Geteilter Zugriff", "subtitle": "Wer deine Gesundheitsakte öffnen kann und wessen Akte du öffnen kannst." - }, - "preview": { - "title": "Vorschau-Funktionen", - "subtitle": "Probier aus, was noch nicht fertig ist. Alles hier bleibt aus, bis du es einschaltest." } }, "profile": "Profil", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Passkey entfernt.", "integrationDisconnected": "{provider} getrennt.", "integrationDisconnectFailed": "{provider} konnte nicht getrennt werden.", - "preview": { - "topics": { - "title": "Themen", - "description": "Fügt einen Bereich Themen hinzu, der zusammengehörige Werte bündelt, neben deinen Insights-Seiten.", - "detail": "Acht Themen, von Herz bis Zyklus, zeigen deine Werte nebeneinander, wie sie zusammenhängen, und führen in die Einzelseiten, die du schon kennst. Deine Insights-Seiten, die Navigation und alle Links bleiben genau, wie sie sind. Alles wird aus deinen eigenen Werten berechnet, ohne KI. Ausschalten entfernt den Eintrag und löscht nichts.", - "savedOn": "Themen-Vorschau eingeschaltet.", - "savedOff": "Themen-Vorschau ausgeschaltet.", - "open": "Themen öffnen" - }, - "loadError": "Deine Vorschau-Einstellungen konnten nicht geladen werden." - }, "timezoneSaved": "Zeitzone gespeichert.", "moduleState": { "on": "An", @@ -13782,171 +13765,5 @@ "startsOn": "Beginn", "endsOn": "Ende" } - }, - "topics": { - "overview": { - "title": "Themen", - "description": "Zusammengehörige Werte, aus deinen eigenen Daten gebündelt; öffne ein Thema, um sie nebeneinander zu sehen.", - "emptyTitle": "Noch nichts zum Bündeln", - "emptyDescription": "Themen erscheinen, sobald es Werte dafür gibt: von einem Gerät, aus einem Import oder von dir eingetragen.", - "notRecorded": "Noch keine Werte für: {topics}.", - "hiddenByModule": "Ausgeblendet, weil das Modul aus ist: {topics}.", - "modulesLink": "Module in den Einstellungen ändern" - }, - "detail": { - "back": "Alle Themen" - }, - "loadError": "Die Themen konnten nicht geladen werden.", - "previewNote": "Das ist eine Vorschau. Sie kann sich zwischen Versionen ändern, und deine Einzelseiten bleiben, wie sie sind.", - "recorded": "Erfasste Werte: {count} von {total}", - "tone": { - "steady": "Stabil", - "watch": "Einen Blick wert", - "learning": "Lernt noch" - }, - "summary": { - "outsideAbove": "{signal} liegt über deinem üblichen Bereich.", - "outsideBelow": "{signal} liegt unter deinem üblichen Bereich.", - "labs": "{count} von {total} Laborwerten liegen im Referenzbereich.", - "cycleDay": "Zyklustag {day}.", - "steadyAll": "Alles Erfasste liegt in deinem üblichen Bereich.", - "steadySome": "{count} von {total} Werten liegen in deinem üblichen Bereich; für die übrigen lernt HealthLog noch.", - "learning": "Dein üblicher Bereich wird noch gelernt. Eine Woche mit Werten reicht.", - "empty": "Noch nichts erfasst." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "im Bereich", - "cycleDay": "Tag {day}" - }, - "signals": { - "mood": "Stimmung" - }, - "units": { - "moodScale": "von 5" - }, - "names": { - "heart": { - "title": "Herz", - "description": "Ruhepuls, Herzfrequenzvariabilität und Fitness, mit dem Schlaf und Training, die sie bewegen." - }, - "body": { - "title": "Körper", - "description": "Gewicht und Körperzusammensetzung im Verlauf." - }, - "bloodPressure": { - "title": "Blutdruck", - "description": "Systolisch, diastolisch und Puls, mit Schlaf und Aktivität drumherum." - }, - "sleep": { - "title": "Schlaf", - "description": "Schlafdauer und die Werte, die nachts gemessen werden." - }, - "activity": { - "title": "Aktivität & Training", - "description": "Schritte, Trainingsminuten, aktive Energie und Trainingslast." - }, - "metabolism": { - "title": "Stoffwechsel & Labor", - "description": "Blutzucker und deine Laborwerte, mit dem Trend jedes Markers." - }, - "mind": { - "title": "Psyche", - "description": "Stimmung und Fragebögen neben Schlaf und Aktivität." - }, - "cycle": { - "title": "Zyklus", - "description": "Dein Zyklus mit der Temperatur und dem Ruhepuls, die ihm folgen." - } - }, - "sources": { - "heart": "Diese Werte kommen von einer Uhr, einem Ring oder Brustgurt, aus Apple Health oder Health Connect oder von dir eingetragen.", - "body": "Diese Werte kommen von einer Waage, aus einem Import oder von dir eingetragen.", - "bloodPressure": "Diese Werte kommen von einem Blutdruckmessgerät, aus einem Import oder von dir eingetragen.", - "sleep": "Diese Werte kommen von einer Uhr oder einem Ring, aus Apple Health oder Health Connect oder von dir eingetragen.", - "activity": "Diese Werte kommen von Handy, Uhr oder Ring oder aus Apple Health oder Health Connect.", - "metabolism": "Blutzucker kommt von einem Messgerät, aus einem Sensor-Import oder von dir; Laborwerte aus einem Laborbericht oder von dir eingetragen.", - "mind": "Diese Werte kommen aus deinen Stimmungseinträgen und den Fragebögen auf der Seite Seelisches Wohlbefinden.", - "cycle": "Diese Werte kommen aus deinem Zyklusprotokoll und einem Temperatursensor am Handgelenk." - }, - "today": { - "title": "Heute", - "usual": "Üblich {low}–{high}", - "learning": "Üblicher Bereich wird noch gelernt", - "asOf": "Stand {date}", - "details": "Details" - }, - "state": { - "within": "Im Bereich", - "above": "Über üblich", - "below": "Unter üblich", - "learning": "Lernt noch" - }, - "chart": { - "title": "Nebeneinander", - "legend": "Schattiert: dein üblicher Bereich.", - "label": "{signals} im gewählten Zeitraum, je eine Zeile." - }, - "range": { - "label": "Zeitraum", - "7d": "7 T", - "30d": "30 T", - "90d": "90 T", - "1y": "1 J" - }, - "relationships": { - "title": "Wie sie zusammenhängen", - "insufficient": "{x} und {y}: bisher {count} von {required} gemeinsamen Tagen.", - "noClearLink": "Kein klarer Zusammenhang zwischen {x} und {y} über {count} gemeinsame Tage.", - "splitHigher": "Wenn {x} unter {threshold} lag, war {y} um {amount} höher als an anderen Tagen.", - "splitLower": "Wenn {x} unter {threshold} lag, war {y} um {amount} niedriger als an anderen Tagen.", - "splitDays": "Tage darunter: {below}. Andere Tage: {other}.", - "correlationSameDayHigher": "Wenn {x} höher liegt, ist auch {y} meist höher (r = {r}).", - "correlationSameDayLower": "Wenn {x} höher liegt, ist {y} meist niedriger (r = {r}).", - "correlationNextDayHigher": "Wenn {x} höher liegt, ist {y} am nächsten Tag meist höher (r = {r}).", - "correlationNextDayLower": "Wenn {x} höher liegt, ist {y} am nächsten Tag meist niedriger (r = {r}).", - "pairedDays": "Gemeinsame Tage: {count}", - "footnote": "Erscheint, sobald zwei Werte an mindestens 14 Tagen zusammen vorliegen. Ein Muster, keine Ursache.", - "scatterCaption": "Jeder Punkt ist ein Tag: {x} nach rechts, {y} nach oben." - }, - "trends": { - "title": "Trends", - "window": "90 Tage, Wochenmittel", - "insufficient": "Braucht 14 Tage, bisher {count}" - }, - "labs": { - "title": "Laborwerte", - "above": "Über dem Bereich", - "below": "Unter dem Bereich", - "trendsTitle": "Trends", - "trendNeeds": "Ein Trend braucht drei Werte über mindestens ein Jahr. Noch nicht so weit: {markers}." - }, - "screeners": { - "title": "Fragebögen", - "none": "Noch keine Fragebögen ausgefüllt.", - "checkIns": "Ausgefüllt: {count}", - "improved": "Besser als beim ersten Mal", - "worsened": "Schlechter als beim ersten Mal", - "within_threshold": "Im üblichen Schwankungsbereich", - "single": "Bisher einmal ausgefüllt", - "open": "Seelisches Wohlbefinden öffnen" - }, - "cycle": { - "title": "Zyklus", - "today": "Zyklustag {day}.", - "todayWithPhase": "Zyklustag {day}, {phase}.", - "average": "Durchschnittliche Zykluslänge: {days} Tage.", - "needs": "Ein Durchschnitt braucht zwei erfasste Periodenbeginne; bisher sind es {count}.", - "lengths": "Letzte Zyklen in Tagen: {lengths}", - "open": "Zyklus öffnen" - }, - "links": { - "title": "Einzelseiten", - "workouts": "Workouts" - }, - "missing": { - "title": "Noch nicht erfasst: {signals}.", - "connect": "Quelle verbinden" - } } } diff --git a/messages/en.json b/messages/en.json index fe74c3170..0c7e01d4f 100644 --- a/messages/en.json +++ b/messages/en.json @@ -510,9 +510,7 @@ "documents": "Documents", "vaccinations": "Vaccinations", "mentalWellbeing": "Mental wellbeing", - "timeline": "Timeline", - "topics": "Topics", - "previewBadge": "Beta" + "timeline": "Timeline" }, "auth": { "login": "Sign in", @@ -6145,10 +6143,6 @@ "access": { "title": "Shared access", "subtitle": "Who can open your health record, and whose you can open." - }, - "preview": { - "title": "Preview features", - "subtitle": "Try what is not finished yet. Everything here stays off until you switch it on." } }, "profile": "Profile", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Passkey removed.", "integrationDisconnected": "{provider} disconnected.", "integrationDisconnectFailed": "Could not disconnect {provider}.", - "preview": { - "topics": { - "title": "Topics", - "description": "Adds a Topics area that brings related signals together, beside your Insights pages.", - "detail": "Eight topics, from heart to cycle, show your signals side by side, how they move together and links into the single-metric pages you already use. Your Insights pages, navigation and links stay exactly as they are. Everything is computed from your own values, without AI. Switching it off removes the entry and deletes nothing.", - "savedOn": "Topics preview switched on.", - "savedOff": "Topics preview switched off.", - "open": "Open Topics" - }, - "loadError": "Could not load your preview settings." - }, "timezoneSaved": "Timezone saved.", "moduleState": { "on": "On", @@ -13782,171 +13765,5 @@ "startsOn": "Start", "endsOn": "End" } - }, - "topics": { - "overview": { - "title": "Topics", - "description": "Related signals brought together from your own values; open one to see them side by side.", - "emptyTitle": "Nothing to bring together yet", - "emptyDescription": "Topics appear once there are readings for them, from a device, an import or your own entries.", - "notRecorded": "Nothing recorded yet for: {topics}.", - "hiddenByModule": "Hidden because the module is off: {topics}.", - "modulesLink": "Change modules in Settings" - }, - "detail": { - "back": "All topics" - }, - "loadError": "Could not load the topics.", - "previewNote": "This is a preview. It may change between releases, and your single-metric pages stay as they are.", - "recorded": "Signals recorded: {count} of {total}", - "tone": { - "steady": "Steady", - "watch": "Worth a look", - "learning": "Learning" - }, - "summary": { - "outsideAbove": "{signal} is above your usual range.", - "outsideBelow": "{signal} is below your usual range.", - "labs": "{count} of {total} lab values sit inside their reference range.", - "cycleDay": "Cycle day {day}.", - "steadyAll": "Everything recorded sits inside your usual range.", - "steadySome": "{count} of {total} signals sit inside your usual range; the others are still being learned.", - "learning": "Still learning your usual range. A week of readings is enough.", - "empty": "Nothing recorded yet." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "in range", - "cycleDay": "Day {day}" - }, - "signals": { - "mood": "Mood" - }, - "units": { - "moodScale": "of 5" - }, - "names": { - "heart": { - "title": "Heart", - "description": "Resting heart rate, heart-rate variability and cardio fitness, with the sleep and training that move them." - }, - "body": { - "title": "Body", - "description": "Weight and body composition over time." - }, - "bloodPressure": { - "title": "Blood pressure", - "description": "Systolic, diastolic and pulse, with the sleep and activity around them." - }, - "sleep": { - "title": "Sleep", - "description": "Time asleep and the signals measured at night." - }, - "activity": { - "title": "Activity & training", - "description": "Steps, exercise minutes, active energy and training load." - }, - "metabolism": { - "title": "Metabolism & labs", - "description": "Blood glucose and your lab values, with each marker's trend." - }, - "mind": { - "title": "Mind", - "description": "Mood and screener check-ins beside sleep and activity." - }, - "cycle": { - "title": "Cycle", - "description": "Your cycle with the temperature and resting heart rate that follow it." - } - }, - "sources": { - "heart": "These come from a watch, ring or chest strap, from Apple Health or Health Connect, or from your own entries.", - "body": "These come from a smart scale, an import or your own entries.", - "bloodPressure": "These come from a blood pressure monitor, an import or your own entries.", - "sleep": "These come from a watch or ring, from Apple Health or Health Connect, or from your own entries.", - "activity": "These come from a phone, watch or ring, or from Apple Health or Health Connect.", - "metabolism": "Glucose comes from a meter, a sensor import or your own entries; lab values from a lab report or your own entries.", - "mind": "These come from mood entries and the check-ins on the mental wellbeing page.", - "cycle": "These come from your cycle log and a wrist temperature sensor." - }, - "today": { - "title": "Today", - "usual": "Usual {low}–{high}", - "learning": "Usual range still being learned", - "asOf": "As of {date}", - "details": "Details" - }, - "state": { - "within": "Within", - "above": "Above usual", - "below": "Below usual", - "learning": "Learning" - }, - "chart": { - "title": "Side by side", - "legend": "Shaded: your usual range.", - "label": "{signals} over the selected period, one row each." - }, - "range": { - "label": "Period", - "7d": "7d", - "30d": "30d", - "90d": "90d", - "1y": "1y" - }, - "relationships": { - "title": "How they move together", - "insufficient": "{x} and {y}: {count} of {required} paired days so far.", - "noClearLink": "No clear link between {x} and {y} over {count} paired days.", - "splitHigher": "When {x} was under {threshold}, {y} was {amount} higher than on other days.", - "splitLower": "When {x} was under {threshold}, {y} was {amount} lower than on other days.", - "splitDays": "Days under: {below}. Other days: {other}.", - "correlationSameDayHigher": "When {x} runs higher, {y} tends to be higher too (r = {r}).", - "correlationSameDayLower": "When {x} runs higher, {y} tends to be lower (r = {r}).", - "correlationNextDayHigher": "When {x} runs higher, {y} the next day tends to be higher (r = {r}).", - "correlationNextDayLower": "When {x} runs higher, {y} the next day tends to be lower (r = {r}).", - "pairedDays": "Paired days: {count}", - "footnote": "Shown once two signals overlap on at least 14 days. A pattern, not a cause.", - "scatterCaption": "Each dot is one day: {x} across, {y} up." - }, - "trends": { - "title": "Trends", - "window": "90 days, weekly means", - "insufficient": "Needs 14 days, {count} so far" - }, - "labs": { - "title": "Lab values", - "above": "Above range", - "below": "Below range", - "trendsTitle": "Trends", - "trendNeeds": "A trend needs three values spanning a year. Not there yet: {markers}." - }, - "screeners": { - "title": "Check-ins", - "none": "No screener check-ins yet.", - "checkIns": "Check-ins: {count}", - "improved": "Better than the first", - "worsened": "Worse than the first", - "within_threshold": "Within the usual wobble", - "single": "One check-in so far", - "open": "Open mental wellbeing" - }, - "cycle": { - "title": "Cycle", - "today": "Cycle day {day}.", - "todayWithPhase": "Cycle day {day}, {phase} phase.", - "average": "Average cycle length: {days} days.", - "needs": "An average needs two logged period starts; there are {count} so far.", - "lengths": "Recent cycles, in days: {lengths}", - "open": "Open the cycle page" - }, - "links": { - "title": "Single-metric pages", - "workouts": "Workouts" - }, - "missing": { - "title": "Not recorded yet: {signals}.", - "connect": "Connect a source" - } } } diff --git a/messages/es.json b/messages/es.json index bee577c0e..c0eb52e19 100644 --- a/messages/es.json +++ b/messages/es.json @@ -510,9 +510,7 @@ "documents": "Documentos", "vaccinations": "Vacunas", "mentalWellbeing": "Bienestar mental", - "timeline": "Cronología", - "topics": "Temas", - "previewBadge": "Beta" + "timeline": "Cronología" }, "auth": { "login": "Iniciar sesión", @@ -6145,10 +6143,6 @@ "access": { "title": "Acceso compartido", "subtitle": "Quién puede abrir tu historial de salud y cuál puedes abrir tú." - }, - "preview": { - "title": "Funciones en vista previa", - "subtitle": "Prueba lo que aún no está terminado. Todo aquí sigue desactivado hasta que lo actives." } }, "profile": "Perfil", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Passkey eliminada.", "integrationDisconnected": "{provider} desconectado.", "integrationDisconnectFailed": "No se pudo desconectar {provider}.", - "preview": { - "topics": { - "title": "Temas", - "description": "Añade un área Temas que reúne valores relacionados, junto a tus páginas de Insights.", - "detail": "Ocho temas, del corazón al ciclo, muestran tus valores uno al lado del otro, cómo se mueven juntos y enlaces a las páginas por métrica que ya usas. Tus páginas de Insights, la navegación y los enlaces quedan exactamente como están. Todo se calcula con tus propios valores, sin IA. Desactivarlo quita la entrada y no borra nada.", - "savedOn": "Vista previa de Temas activada.", - "savedOff": "Vista previa de Temas desactivada.", - "open": "Abrir Temas" - }, - "loadError": "No se pudieron cargar tus ajustes de vista previa." - }, "timezoneSaved": "Zona horaria guardada.", "moduleState": { "on": "Activado", @@ -13782,171 +13765,5 @@ "startsOn": "Inicio", "endsOn": "Fin" } - }, - "topics": { - "overview": { - "title": "Temas", - "description": "Valores relacionados, reunidos a partir de tus propios datos; abre un tema para verlos uno al lado del otro.", - "emptyTitle": "Todavía no hay nada que reunir", - "emptyDescription": "Los temas aparecen en cuanto hay valores para ellos: de un dispositivo, una importación o tus propios registros.", - "notRecorded": "Aún sin registros para: {topics}.", - "hiddenByModule": "Ocultos porque el módulo está desactivado: {topics}.", - "modulesLink": "Cambiar módulos en los ajustes" - }, - "detail": { - "back": "Todos los temas" - }, - "loadError": "No se pudieron cargar los temas.", - "previewNote": "Esto es una vista previa. Puede cambiar entre versiones, y tus páginas por métrica siguen como están.", - "recorded": "Valores registrados: {count} de {total}", - "tone": { - "steady": "Estable", - "watch": "Merece un vistazo", - "learning": "Aprendiendo" - }, - "summary": { - "outsideAbove": "{signal} está por encima de tu rango habitual.", - "outsideBelow": "{signal} está por debajo de tu rango habitual.", - "labs": "{count} de {total} análisis están dentro de su rango de referencia.", - "cycleDay": "Día {day} del ciclo.", - "steadyAll": "Todo lo registrado está dentro de tu rango habitual.", - "steadySome": "{count} de {total} valores están dentro de tu rango habitual; los demás aún se están aprendiendo.", - "learning": "Tu rango habitual aún se está aprendiendo. Basta con una semana de registros.", - "empty": "Aún no hay nada registrado." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "en rango", - "cycleDay": "Día {day}" - }, - "signals": { - "mood": "Estado de ánimo" - }, - "units": { - "moodScale": "de 5" - }, - "names": { - "heart": { - "title": "Corazón", - "description": "Frecuencia cardíaca en reposo, variabilidad y forma cardiovascular, con el sueño y el entrenamiento que las mueven." - }, - "body": { - "title": "Cuerpo", - "description": "Peso y composición corporal a lo largo del tiempo." - }, - "bloodPressure": { - "title": "Presión arterial", - "description": "Sistólica, diastólica y pulso, con el sueño y la actividad a su alrededor." - }, - "sleep": { - "title": "Sueño", - "description": "Tiempo dormido y los valores medidos por la noche." - }, - "activity": { - "title": "Actividad y entrenamiento", - "description": "Pasos, minutos de ejercicio, energía activa y carga de entrenamiento." - }, - "metabolism": { - "title": "Metabolismo y análisis", - "description": "Glucosa y tus análisis, con la tendencia de cada marcador." - }, - "mind": { - "title": "Mente", - "description": "Estado de ánimo y cuestionarios junto al sueño y la actividad." - }, - "cycle": { - "title": "Ciclo", - "description": "Tu ciclo con la temperatura y la frecuencia cardíaca en reposo que lo acompañan." - } - }, - "sources": { - "heart": "Estos valores vienen de un reloj, un anillo o una banda pectoral, de Apple Salud o Health Connect, o de tus propios registros.", - "body": "Estos valores vienen de una báscula inteligente, una importación o tus propios registros.", - "bloodPressure": "Estos valores vienen de un tensiómetro, una importación o tus propios registros.", - "sleep": "Estos valores vienen de un reloj o un anillo, de Apple Salud o Health Connect, o de tus propios registros.", - "activity": "Estos valores vienen de un teléfono, un reloj o un anillo, o de Apple Salud o Health Connect.", - "metabolism": "La glucosa viene de un medidor, una importación de sensor o tus registros; los análisis, de un informe de laboratorio o de tus registros.", - "mind": "Estos valores vienen de tus registros de ánimo y de los cuestionarios de la página Bienestar mental.", - "cycle": "Estos valores vienen de tu registro del ciclo y de un sensor de temperatura en la muñeca." - }, - "today": { - "title": "Hoy", - "usual": "Habitual {low}–{high}", - "learning": "Rango habitual aún en aprendizaje", - "asOf": "A fecha de {date}", - "details": "Detalles" - }, - "state": { - "within": "Dentro", - "above": "Por encima", - "below": "Por debajo", - "learning": "Aprendiendo" - }, - "chart": { - "title": "Uno al lado del otro", - "legend": "Sombreado: tu rango habitual.", - "label": "{signals} en el periodo elegido, una fila cada uno." - }, - "range": { - "label": "Periodo", - "7d": "7 d", - "30d": "30 d", - "90d": "90 d", - "1y": "1 a" - }, - "relationships": { - "title": "Cómo se mueven juntos", - "insufficient": "{x} y {y}: {count} de {required} días emparejados por ahora.", - "noClearLink": "Sin relación clara entre {x} y {y} en {count} días emparejados.", - "splitHigher": "Cuando {x} estuvo por debajo de {threshold}, {y} fue {amount} más alto que otros días.", - "splitLower": "Cuando {x} estuvo por debajo de {threshold}, {y} fue {amount} más bajo que otros días.", - "splitDays": "Días por debajo: {below}. Otros días: {other}.", - "correlationSameDayHigher": "Cuando {x} sube, {y} también suele estar más alto (r = {r}).", - "correlationSameDayLower": "Cuando {x} sube, {y} suele estar más bajo (r = {r}).", - "correlationNextDayHigher": "Cuando {x} sube, {y} suele estar más alto al día siguiente (r = {r}).", - "correlationNextDayLower": "Cuando {x} sube, {y} suele estar más bajo al día siguiente (r = {r}).", - "pairedDays": "Días emparejados: {count}", - "footnote": "Se muestra cuando dos valores coinciden en al menos 14 días. Un patrón, no una causa.", - "scatterCaption": "Cada punto es un día: {x} en horizontal, {y} en vertical." - }, - "trends": { - "title": "Tendencias", - "window": "90 días, medias semanales", - "insufficient": "Necesita 14 días, {count} por ahora" - }, - "labs": { - "title": "Análisis", - "above": "Por encima del rango", - "below": "Por debajo del rango", - "trendsTitle": "Tendencias", - "trendNeeds": "Una tendencia necesita tres valores a lo largo de al menos un año. Aún no: {markers}." - }, - "screeners": { - "title": "Cuestionarios", - "none": "Aún no has completado ningún cuestionario.", - "checkIns": "Completados: {count}", - "improved": "Mejor que la primera vez", - "worsened": "Peor que la primera vez", - "within_threshold": "Dentro de la variación habitual", - "single": "Completado una vez por ahora", - "open": "Abrir Bienestar mental" - }, - "cycle": { - "title": "Ciclo", - "today": "Día {day} del ciclo.", - "todayWithPhase": "Día {day} del ciclo, fase {phase}.", - "average": "Duración media del ciclo: {days} días.", - "needs": "Una media necesita dos inicios de periodo registrados; por ahora hay {count}.", - "lengths": "Últimos ciclos, en días: {lengths}", - "open": "Abrir la página del ciclo" - }, - "links": { - "title": "Páginas por métrica", - "workouts": "Entrenamientos" - }, - "missing": { - "title": "Aún sin registrar: {signals}.", - "connect": "Conectar una fuente" - } } } diff --git a/messages/fr.json b/messages/fr.json index cfe4ed829..1ae591455 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -510,9 +510,7 @@ "documents": "Documents", "vaccinations": "Vaccinations", "mentalWellbeing": "Bien-être mental", - "timeline": "Chronologie", - "topics": "Thèmes", - "previewBadge": "Bêta" + "timeline": "Chronologie" }, "auth": { "login": "Se connecter", @@ -6145,10 +6143,6 @@ "access": { "title": "Accès partagé", "subtitle": "Qui peut ouvrir votre dossier de santé, et lequel vous pouvez ouvrir." - }, - "preview": { - "title": "Fonctions en avant-première", - "subtitle": "Essayez ce qui n'est pas encore terminé. Tout reste désactivé ici jusqu'à ce que vous l'activiez." } }, "profile": "Profil", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Passkey supprimée.", "integrationDisconnected": "{provider} déconnecté.", "integrationDisconnectFailed": "Impossible de déconnecter {provider}.", - "preview": { - "topics": { - "title": "Thèmes", - "description": "Ajoute un espace Thèmes qui rassemble les mesures liées, à côté de vos pages Insights.", - "detail": "Huit thèmes, du cœur au cycle, montrent vos mesures côte à côte, la façon dont elles évoluent ensemble et des liens vers les pages par mesure que vous utilisez déjà. Vos pages Insights, la navigation et les liens restent exactement tels quels. Tout est calculé à partir de vos propres valeurs, sans IA. Désactiver retire l'entrée et ne supprime rien.", - "savedOn": "Aperçu Thèmes activé.", - "savedOff": "Aperçu Thèmes désactivé.", - "open": "Ouvrir Thèmes" - }, - "loadError": "Impossible de charger vos réglages d'avant-première." - }, "timezoneSaved": "Fuseau horaire enregistré.", "moduleState": { "on": "Activé", @@ -13782,171 +13765,5 @@ "startsOn": "Début", "endsOn": "Fin" } - }, - "topics": { - "overview": { - "title": "Thèmes", - "description": "Des mesures liées, rassemblées à partir de vos propres valeurs ; ouvrez un thème pour les voir côte à côte.", - "emptyTitle": "Rien à rassembler pour l'instant", - "emptyDescription": "Les thèmes apparaissent dès qu'il y a des mesures pour eux : d'un appareil, d'un import ou saisies par vous.", - "notRecorded": "Rien d'enregistré pour l'instant : {topics}.", - "hiddenByModule": "Masqués car le module est désactivé : {topics}.", - "modulesLink": "Modifier les modules dans les réglages" - }, - "detail": { - "back": "Tous les thèmes" - }, - "loadError": "Impossible de charger les thèmes.", - "previewNote": "Ceci est un aperçu. Il peut changer d'une version à l'autre, et vos pages par mesure restent telles quelles.", - "recorded": "Mesures enregistrées : {count} sur {total}", - "tone": { - "steady": "Stable", - "watch": "À regarder", - "learning": "En apprentissage" - }, - "summary": { - "outsideAbove": "{signal} est au-dessus de votre plage habituelle.", - "outsideBelow": "{signal} est en dessous de votre plage habituelle.", - "labs": "{count} analyses sur {total} se situent dans leur plage de référence.", - "cycleDay": "Jour {day} du cycle.", - "steadyAll": "Tout ce qui est enregistré se situe dans votre plage habituelle.", - "steadySome": "{count} mesures sur {total} se situent dans votre plage habituelle ; les autres sont encore en apprentissage.", - "learning": "Votre plage habituelle est encore en apprentissage. Une semaine de mesures suffit.", - "empty": "Rien d'enregistré pour l'instant." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "dans la plage", - "cycleDay": "Jour {day}" - }, - "signals": { - "mood": "Humeur" - }, - "units": { - "moodScale": "sur 5" - }, - "names": { - "heart": { - "title": "Cœur", - "description": "Fréquence cardiaque au repos, variabilité et condition cardio, avec le sommeil et l'entraînement qui les font varier." - }, - "body": { - "title": "Corps", - "description": "Poids et composition corporelle dans le temps." - }, - "bloodPressure": { - "title": "Tension artérielle", - "description": "Systolique, diastolique et pouls, avec le sommeil et l'activité autour." - }, - "sleep": { - "title": "Sommeil", - "description": "Temps de sommeil et mesures prises la nuit." - }, - "activity": { - "title": "Activité et entraînement", - "description": "Pas, minutes d'exercice, énergie active et charge d'entraînement." - }, - "metabolism": { - "title": "Métabolisme et analyses", - "description": "Glycémie et vos analyses, avec la tendance de chaque marqueur." - }, - "mind": { - "title": "Psychisme", - "description": "Humeur et questionnaires à côté du sommeil et de l'activité." - }, - "cycle": { - "title": "Cycle", - "description": "Votre cycle avec la température et la fréquence cardiaque au repos qui le suivent." - } - }, - "sources": { - "heart": "Ces valeurs viennent d'une montre, d'une bague ou d'une ceinture thoracique, d'Apple Santé ou de Health Connect, ou de vos saisies.", - "body": "Ces valeurs viennent d'une balance connectée, d'un import ou de vos saisies.", - "bloodPressure": "Ces valeurs viennent d'un tensiomètre, d'un import ou de vos saisies.", - "sleep": "Ces valeurs viennent d'une montre ou d'une bague, d'Apple Santé ou de Health Connect, ou de vos saisies.", - "activity": "Ces valeurs viennent d'un téléphone, d'une montre ou d'une bague, ou d'Apple Santé ou de Health Connect.", - "metabolism": "La glycémie vient d'un lecteur, d'un import de capteur ou de vos saisies ; les analyses d'un compte rendu de laboratoire ou de vos saisies.", - "mind": "Ces valeurs viennent de vos saisies d'humeur et des questionnaires de la page Bien-être mental.", - "cycle": "Ces valeurs viennent de votre journal de cycle et d'un capteur de température au poignet." - }, - "today": { - "title": "Aujourd'hui", - "usual": "Habituel {low}–{high}", - "learning": "Plage habituelle encore en apprentissage", - "asOf": "Au {date}", - "details": "Détails" - }, - "state": { - "within": "Dans la plage", - "above": "Au-dessus", - "below": "En dessous", - "learning": "En apprentissage" - }, - "chart": { - "title": "Côte à côte", - "legend": "Zone ombrée : votre plage habituelle.", - "label": "{signals} sur la période choisie, une ligne chacune." - }, - "range": { - "label": "Période", - "7d": "7 j", - "30d": "30 j", - "90d": "90 j", - "1y": "1 a" - }, - "relationships": { - "title": "Comment elles évoluent ensemble", - "insufficient": "{x} et {y} : {count} jours communs sur {required} pour l'instant.", - "noClearLink": "Pas de lien net entre {x} et {y} sur {count} jours communs.", - "splitHigher": "Quand {x} était sous {threshold}, {y} était plus élevé de {amount} que les autres jours.", - "splitLower": "Quand {x} était sous {threshold}, {y} était plus bas de {amount} que les autres jours.", - "splitDays": "Jours en dessous : {below}. Autres jours : {other}.", - "correlationSameDayHigher": "Quand {x} est plus élevé, {y} tend à l'être aussi (r = {r}).", - "correlationSameDayLower": "Quand {x} est plus élevé, {y} tend à être plus bas (r = {r}).", - "correlationNextDayHigher": "Quand {x} est plus élevé, {y} tend à être plus élevé le lendemain (r = {r}).", - "correlationNextDayLower": "Quand {x} est plus élevé, {y} tend à être plus bas le lendemain (r = {r}).", - "pairedDays": "Jours communs : {count}", - "footnote": "Affiché dès que deux mesures se recoupent sur au moins 14 jours. Une tendance, pas une cause.", - "scatterCaption": "Chaque point est un jour : {x} en abscisse, {y} en ordonnée." - }, - "trends": { - "title": "Tendances", - "window": "90 jours, moyennes hebdomadaires", - "insufficient": "Il faut 14 jours, {count} pour l'instant" - }, - "labs": { - "title": "Analyses", - "above": "Au-dessus de la plage", - "below": "En dessous de la plage", - "trendsTitle": "Tendances", - "trendNeeds": "Une tendance demande trois valeurs sur au moins un an. Pas encore : {markers}." - }, - "screeners": { - "title": "Questionnaires", - "none": "Aucun questionnaire rempli pour l'instant.", - "checkIns": "Remplis : {count}", - "improved": "Mieux que la première fois", - "worsened": "Moins bien que la première fois", - "within_threshold": "Dans la variation habituelle", - "single": "Rempli une fois pour l'instant", - "open": "Ouvrir Bien-être mental" - }, - "cycle": { - "title": "Cycle", - "today": "Jour {day} du cycle.", - "todayWithPhase": "Jour {day} du cycle, phase {phase}.", - "average": "Durée moyenne du cycle : {days} jours.", - "needs": "Une moyenne demande deux débuts de règles enregistrés ; il y en a {count} pour l'instant.", - "lengths": "Derniers cycles, en jours : {lengths}", - "open": "Ouvrir la page Cycle" - }, - "links": { - "title": "Pages par mesure", - "workouts": "Entraînements" - }, - "missing": { - "title": "Pas encore enregistré : {signals}.", - "connect": "Connecter une source" - } } } diff --git a/messages/it.json b/messages/it.json index 192d1985e..9e30bf5ca 100644 --- a/messages/it.json +++ b/messages/it.json @@ -510,9 +510,7 @@ "documents": "Documenti", "vaccinations": "Vaccinazioni", "mentalWellbeing": "Benessere mentale", - "timeline": "Cronologia", - "topics": "Temi", - "previewBadge": "Beta" + "timeline": "Cronologia" }, "auth": { "login": "Accedi", @@ -6145,10 +6143,6 @@ "access": { "title": "Accesso condiviso", "subtitle": "Chi può aprire la tua cartella sanitaria e quale puoi aprire tu." - }, - "preview": { - "title": "Funzioni in anteprima", - "subtitle": "Prova ciò che non è ancora finito. Tutto qui resta spento finché non lo attivi." } }, "profile": "Profilo", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Passkey rimossa.", "integrationDisconnected": "{provider} disconnesso.", "integrationDisconnectFailed": "Impossibile disconnettere {provider}.", - "preview": { - "topics": { - "title": "Temi", - "description": "Aggiunge un'area Temi che raccoglie valori collegati, accanto alle tue pagine Insights.", - "detail": "Otto temi, dal cuore al ciclo, mostrano i tuoi valori affiancati, come si muovono insieme e collegamenti alle pagine per metrica che già usi. Le tue pagine Insights, la navigazione e i link restano esattamente come sono. Tutto è calcolato dai tuoi valori, senza IA. Disattivarla toglie la voce e non cancella nulla.", - "savedOn": "Anteprima Temi attivata.", - "savedOff": "Anteprima Temi disattivata.", - "open": "Apri Temi" - }, - "loadError": "Impossibile caricare le impostazioni delle anteprime." - }, "timezoneSaved": "Fuso orario salvato.", "moduleState": { "on": "Attivo", @@ -13782,171 +13765,5 @@ "startsOn": "Inizio", "endsOn": "Fine" } - }, - "topics": { - "overview": { - "title": "Temi", - "description": "Valori collegati, raccolti dai tuoi dati; apri un tema per vederli affiancati.", - "emptyTitle": "Ancora niente da raccogliere", - "emptyDescription": "I temi compaiono appena ci sono valori per loro: da un dispositivo, da un'importazione o inseriti da te.", - "notRecorded": "Ancora nessun valore per: {topics}.", - "hiddenByModule": "Nascosti perché il modulo è spento: {topics}.", - "modulesLink": "Cambia i moduli nelle impostazioni" - }, - "detail": { - "back": "Tutti i temi" - }, - "loadError": "Impossibile caricare i temi.", - "previewNote": "Questa è un'anteprima. Può cambiare tra una versione e l'altra, e le tue pagine per metrica restano come sono.", - "recorded": "Valori registrati: {count} di {total}", - "tone": { - "steady": "Stabile", - "watch": "Da guardare", - "learning": "In apprendimento" - }, - "summary": { - "outsideAbove": "{signal} è sopra il tuo intervallo abituale.", - "outsideBelow": "{signal} è sotto il tuo intervallo abituale.", - "labs": "{count} esami su {total} rientrano nel loro intervallo di riferimento.", - "cycleDay": "Giorno {day} del ciclo.", - "steadyAll": "Tutto ciò che è registrato rientra nel tuo intervallo abituale.", - "steadySome": "{count} valori su {total} rientrano nel tuo intervallo abituale; gli altri sono ancora in apprendimento.", - "learning": "Il tuo intervallo abituale è ancora in apprendimento. Basta una settimana di valori.", - "empty": "Ancora niente di registrato." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "nell'intervallo", - "cycleDay": "Giorno {day}" - }, - "signals": { - "mood": "Umore" - }, - "units": { - "moodScale": "su 5" - }, - "names": { - "heart": { - "title": "Cuore", - "description": "Frequenza cardiaca a riposo, variabilità e forma cardio, con il sonno e l'allenamento che le influenzano." - }, - "body": { - "title": "Corpo", - "description": "Peso e composizione corporea nel tempo." - }, - "bloodPressure": { - "title": "Pressione arteriosa", - "description": "Sistolica, diastolica e polso, con il sonno e l'attività intorno." - }, - "sleep": { - "title": "Sonno", - "description": "Tempo di sonno e i valori misurati di notte." - }, - "activity": { - "title": "Attività e allenamento", - "description": "Passi, minuti di esercizio, energia attiva e carico di allenamento." - }, - "metabolism": { - "title": "Metabolismo ed esami", - "description": "Glicemia e i tuoi esami, con l'andamento di ogni marcatore." - }, - "mind": { - "title": "Mente", - "description": "Umore e questionari accanto a sonno e attività." - }, - "cycle": { - "title": "Ciclo", - "description": "Il tuo ciclo con la temperatura e la frequenza cardiaca a riposo che lo seguono." - } - }, - "sources": { - "heart": "Questi valori arrivano da un orologio, un anello o una fascia toracica, da Apple Salute o Health Connect, o dai tuoi inserimenti.", - "body": "Questi valori arrivano da una bilancia smart, da un'importazione o dai tuoi inserimenti.", - "bloodPressure": "Questi valori arrivano da un misuratore di pressione, da un'importazione o dai tuoi inserimenti.", - "sleep": "Questi valori arrivano da un orologio o un anello, da Apple Salute o Health Connect, o dai tuoi inserimenti.", - "activity": "Questi valori arrivano da telefono, orologio o anello, o da Apple Salute o Health Connect.", - "metabolism": "La glicemia arriva da un glucometro, da un'importazione del sensore o dai tuoi inserimenti; gli esami da un referto o dai tuoi inserimenti.", - "mind": "Questi valori arrivano dalle tue registrazioni dell'umore e dai questionari della pagina Benessere mentale.", - "cycle": "Questi valori arrivano dal tuo diario del ciclo e da un sensore di temperatura al polso." - }, - "today": { - "title": "Oggi", - "usual": "Abituale {low}–{high}", - "learning": "Intervallo abituale ancora in apprendimento", - "asOf": "Al {date}", - "details": "Dettagli" - }, - "state": { - "within": "Nell'intervallo", - "above": "Sopra il solito", - "below": "Sotto il solito", - "learning": "In apprendimento" - }, - "chart": { - "title": "Affiancati", - "legend": "Area ombreggiata: il tuo intervallo abituale.", - "label": "{signals} nel periodo scelto, una riga ciascuno." - }, - "range": { - "label": "Periodo", - "7d": "7 g", - "30d": "30 g", - "90d": "90 g", - "1y": "1 a" - }, - "relationships": { - "title": "Come si muovono insieme", - "insufficient": "{x} e {y}: finora {count} giorni abbinati su {required}.", - "noClearLink": "Nessun legame chiaro tra {x} e {y} su {count} giorni abbinati.", - "splitHigher": "Quando {x} era sotto {threshold}, {y} era più alto di {amount} rispetto agli altri giorni.", - "splitLower": "Quando {x} era sotto {threshold}, {y} era più basso di {amount} rispetto agli altri giorni.", - "splitDays": "Giorni sotto: {below}. Altri giorni: {other}.", - "correlationSameDayHigher": "Quando {x} è più alto, anche {y} tende a esserlo (r = {r}).", - "correlationSameDayLower": "Quando {x} è più alto, {y} tende a essere più basso (r = {r}).", - "correlationNextDayHigher": "Quando {x} è più alto, il giorno dopo {y} tende a essere più alto (r = {r}).", - "correlationNextDayLower": "Quando {x} è più alto, il giorno dopo {y} tende a essere più basso (r = {r}).", - "pairedDays": "Giorni abbinati: {count}", - "footnote": "Compare quando due valori si sovrappongono per almeno 14 giorni. Uno schema, non una causa.", - "scatterCaption": "Ogni punto è un giorno: {x} in orizzontale, {y} in verticale." - }, - "trends": { - "title": "Andamenti", - "window": "90 giorni, medie settimanali", - "insufficient": "Servono 14 giorni, finora {count}" - }, - "labs": { - "title": "Esami", - "above": "Sopra l'intervallo", - "below": "Sotto l'intervallo", - "trendsTitle": "Andamenti", - "trendNeeds": "Un andamento richiede tre valori nell'arco di almeno un anno. Non ancora: {markers}." - }, - "screeners": { - "title": "Questionari", - "none": "Ancora nessun questionario compilato.", - "checkIns": "Compilati: {count}", - "improved": "Meglio della prima volta", - "worsened": "Peggio della prima volta", - "within_threshold": "Entro la variazione abituale", - "single": "Compilato una volta finora", - "open": "Apri Benessere mentale" - }, - "cycle": { - "title": "Ciclo", - "today": "Giorno {day} del ciclo.", - "todayWithPhase": "Giorno {day} del ciclo, fase {phase}.", - "average": "Durata media del ciclo: {days} giorni.", - "needs": "Una media richiede due inizi di mestruazione registrati; finora sono {count}.", - "lengths": "Ultimi cicli, in giorni: {lengths}", - "open": "Apri la pagina del ciclo" - }, - "links": { - "title": "Pagine per metrica", - "workouts": "Allenamenti" - }, - "missing": { - "title": "Non ancora registrato: {signals}.", - "connect": "Collega una fonte" - } } } diff --git a/messages/ko.json b/messages/ko.json index 83878af2c..0197d663d 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -510,9 +510,7 @@ "documents": "문서", "vaccinations": "예방접종", "mentalWellbeing": "정신 건강", - "timeline": "타임라인", - "topics": "주제", - "previewBadge": "베타" + "timeline": "타임라인" }, "auth": { "login": "로그인", @@ -6145,10 +6143,6 @@ "access": { "title": "공유 접근", "subtitle": "내 건강 기록을 누가 열 수 있고, 내가 누구의 기록을 열 수 있는지예요." - }, - "preview": { - "title": "미리 보기 기능", - "subtitle": "아직 완성되지 않은 기능을 써 보세요. 여기 있는 기능은 직접 켜기 전까지 꺼져 있습니다." } }, "profile": "프로필", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "패스키를 삭제했어요.", "integrationDisconnected": "{provider} 연결을 해제했어요.", "integrationDisconnectFailed": "{provider} 연결을 해제하지 못했어요.", - "preview": { - "topics": { - "title": "주제", - "description": "관련된 수치를 한데 모은 주제 영역을 인사이트 페이지 옆에 추가합니다.", - "detail": "심장부터 주기까지 여덟 가지 주제가 수치를 나란히 보여 주고, 함께 어떻게 움직이는지와 이미 쓰고 있는 개별 지표 페이지로 가는 링크를 보여 줍니다. 인사이트 페이지, 내비게이션, 링크는 그대로 유지됩니다. 모든 계산은 AI 없이 본인의 수치로 합니다. 끄면 메뉴 항목만 사라지고 아무것도 삭제되지 않습니다.", - "savedOn": "주제 미리 보기를 켰습니다.", - "savedOff": "주제 미리 보기를 껐습니다.", - "open": "주제 열기" - }, - "loadError": "미리 보기 설정을 불러오지 못했습니다." - }, "timezoneSaved": "시간대를 저장했습니다.", "moduleState": { "on": "켜짐", @@ -13782,171 +13765,5 @@ "startsOn": "시작", "endsOn": "종료" } - }, - "topics": { - "overview": { - "title": "주제", - "description": "본인의 수치에서 관련 지표를 모았습니다. 주제를 열면 나란히 볼 수 있습니다.", - "emptyTitle": "아직 모을 수치가 없습니다", - "emptyDescription": "기기, 가져오기 또는 직접 입력으로 수치가 생기면 주제가 나타납니다.", - "notRecorded": "아직 기록이 없는 주제: {topics}.", - "hiddenByModule": "모듈이 꺼져 있어 숨김: {topics}.", - "modulesLink": "설정에서 모듈 변경" - }, - "detail": { - "back": "모든 주제" - }, - "loadError": "주제를 불러오지 못했습니다.", - "previewNote": "미리 보기 기능입니다. 버전마다 바뀔 수 있으며, 개별 지표 페이지는 그대로입니다.", - "recorded": "기록된 지표: {total}개 중 {count}개", - "tone": { - "steady": "안정적", - "watch": "살펴볼 만함", - "learning": "학습 중" - }, - "summary": { - "outsideAbove": "{signal}이(가) 평소 범위보다 높습니다.", - "outsideBelow": "{signal}이(가) 평소 범위보다 낮습니다.", - "labs": "검사 수치 {total}개 중 {count}개가 참고 범위 안에 있습니다.", - "cycleDay": "주기 {day}일째.", - "steadyAll": "기록된 모든 수치가 평소 범위 안에 있습니다.", - "steadySome": "{total}개 중 {count}개 지표가 평소 범위 안에 있으며, 나머지는 아직 학습 중입니다.", - "learning": "평소 범위를 아직 학습 중입니다. 일주일 치 기록이면 충분합니다.", - "empty": "아직 기록이 없습니다." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "범위 내", - "cycleDay": "{day}일째" - }, - "signals": { - "mood": "기분" - }, - "units": { - "moodScale": "/ 5" - }, - "names": { - "heart": { - "title": "심장", - "description": "안정 시 심박수, 심박 변이도, 심폐 체력과 이에 영향을 주는 수면과 운동." - }, - "body": { - "title": "신체", - "description": "시간에 따른 체중과 체성분." - }, - "bloodPressure": { - "title": "혈압", - "description": "수축기, 이완기 혈압과 맥박, 그리고 주변의 수면과 활동." - }, - "sleep": { - "title": "수면", - "description": "수면 시간과 밤에 측정되는 수치." - }, - "activity": { - "title": "활동 및 운동", - "description": "걸음 수, 운동 시간, 활동 에너지와 훈련 부하." - }, - "metabolism": { - "title": "대사 및 검사", - "description": "혈당과 검사 수치, 그리고 각 지표의 추세." - }, - "mind": { - "title": "마음", - "description": "수면과 활동 옆에 놓인 기분과 설문." - }, - "cycle": { - "title": "주기", - "description": "주기와 이를 따라 변하는 체온, 안정 시 심박수." - } - }, - "sources": { - "heart": "이 수치는 워치, 링, 가슴 스트랩, Apple 건강 또는 Health Connect, 직접 입력에서 옵니다.", - "body": "이 수치는 스마트 체중계, 가져오기 또는 직접 입력에서 옵니다.", - "bloodPressure": "이 수치는 혈압계, 가져오기 또는 직접 입력에서 옵니다.", - "sleep": "이 수치는 워치나 링, Apple 건강 또는 Health Connect, 직접 입력에서 옵니다.", - "activity": "이 수치는 휴대폰, 워치, 링 또는 Apple 건강이나 Health Connect에서 옵니다.", - "metabolism": "혈당은 혈당 측정기, 센서 가져오기 또는 직접 입력에서, 검사 수치는 검사 보고서나 직접 입력에서 옵니다.", - "mind": "이 수치는 기분 기록과 정신 건강 페이지의 설문에서 옵니다.", - "cycle": "이 수치는 주기 기록과 손목 온도 센서에서 옵니다." - }, - "today": { - "title": "오늘", - "usual": "평소 {low}–{high}", - "learning": "평소 범위 학습 중", - "asOf": "{date} 기준", - "details": "자세히" - }, - "state": { - "within": "범위 내", - "above": "평소보다 높음", - "below": "평소보다 낮음", - "learning": "학습 중" - }, - "chart": { - "title": "나란히 보기", - "legend": "음영: 평소 범위.", - "label": "선택한 기간의 {signals}, 지표마다 한 줄." - }, - "range": { - "label": "기간", - "7d": "7일", - "30d": "30일", - "90d": "90일", - "1y": "1년" - }, - "relationships": { - "title": "함께 움직이는 방식", - "insufficient": "{x}와(과) {y}: 지금까지 {required}일 중 {count}일이 겹칩니다.", - "noClearLink": "겹치는 {count}일 동안 {x}와(과) {y} 사이에 뚜렷한 관계가 없습니다.", - "splitHigher": "{x}이(가) {threshold} 미만일 때 {y}이(가) 다른 날보다 {amount} 높았습니다.", - "splitLower": "{x}이(가) {threshold} 미만일 때 {y}이(가) 다른 날보다 {amount} 낮았습니다.", - "splitDays": "미만인 날: {below}. 다른 날: {other}.", - "correlationSameDayHigher": "{x}이(가) 높을수록 {y}도 높은 경향이 있습니다 (r = {r}).", - "correlationSameDayLower": "{x}이(가) 높을수록 {y}은(는) 낮은 경향이 있습니다 (r = {r}).", - "correlationNextDayHigher": "{x}이(가) 높으면 다음 날 {y}도 높은 경향이 있습니다 (r = {r}).", - "correlationNextDayLower": "{x}이(가) 높으면 다음 날 {y}은(는) 낮은 경향이 있습니다 (r = {r}).", - "pairedDays": "겹치는 날: {count}", - "footnote": "두 지표가 14일 이상 겹치면 표시됩니다. 패턴일 뿐 원인이 아닙니다.", - "scatterCaption": "점 하나가 하루입니다. 가로는 {x}, 세로는 {y}." - }, - "trends": { - "title": "추세", - "window": "90일, 주간 평균", - "insufficient": "14일이 필요합니다. 지금까지 {count}일" - }, - "labs": { - "title": "검사 수치", - "above": "범위 초과", - "below": "범위 미만", - "trendsTitle": "추세", - "trendNeeds": "추세에는 1년 이상에 걸친 수치 세 개가 필요합니다. 아직 부족: {markers}." - }, - "screeners": { - "title": "설문", - "none": "아직 작성한 설문이 없습니다.", - "checkIns": "작성 횟수: {count}", - "improved": "처음보다 좋아짐", - "worsened": "처음보다 나빠짐", - "within_threshold": "평소 변동 범위 내", - "single": "지금까지 한 번 작성", - "open": "정신 건강 열기" - }, - "cycle": { - "title": "주기", - "today": "주기 {day}일째.", - "todayWithPhase": "주기 {day}일째, {phase}.", - "average": "평균 주기 길이: {days}일.", - "needs": "평균을 내려면 생리 시작일 기록이 두 번 필요합니다. 지금까지 {count}번입니다.", - "lengths": "최근 주기(일): {lengths}", - "open": "주기 페이지 열기" - }, - "links": { - "title": "개별 지표 페이지", - "workouts": "운동" - }, - "missing": { - "title": "아직 기록되지 않음: {signals}.", - "connect": "데이터 소스 연결" - } } } diff --git a/messages/nl.json b/messages/nl.json index 36dfdf83d..86a5440ec 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -510,9 +510,7 @@ "documents": "Documenten", "vaccinations": "Vaccinaties", "mentalWellbeing": "Mentaal welzijn", - "timeline": "Tijdlijn", - "topics": "Thema's", - "previewBadge": "Bèta" + "timeline": "Tijdlijn" }, "auth": { "login": "Inloggen", @@ -6145,10 +6143,6 @@ "access": { "title": "Gedeelde toegang", "subtitle": "Wie je gezondheidsdossier kan openen, en wiens dossier jij kunt openen." - }, - "preview": { - "title": "Voorvertoningen", - "subtitle": "Probeer wat nog niet af is. Alles hier blijft uit tot je het aanzet." } }, "profile": "Profiel", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Passkey verwijderd.", "integrationDisconnected": "{provider} ontkoppeld.", "integrationDisconnectFailed": "{provider} kon niet worden ontkoppeld.", - "preview": { - "topics": { - "title": "Thema's", - "description": "Voegt een gedeelte Thema's toe dat samenhangende waarden bundelt, naast je Inzichten-pagina's.", - "detail": "Acht thema's, van hart tot cyclus, tonen je waarden naast elkaar, hoe ze samen bewegen en links naar de pagina's per meetwaarde die je al gebruikt. Je Inzichten-pagina's, de navigatie en alle links blijven precies zoals ze zijn. Alles wordt uit je eigen waarden berekend, zonder AI. Uitzetten haalt de ingang weg en verwijdert niets.", - "savedOn": "Voorvertoning Thema's aangezet.", - "savedOff": "Voorvertoning Thema's uitgezet.", - "open": "Thema's openen" - }, - "loadError": "Je voorvertoningsinstellingen konden niet worden geladen." - }, "timezoneSaved": "Tijdzone opgeslagen.", "moduleState": { "on": "Aan", @@ -13782,171 +13765,5 @@ "startsOn": "Begin", "endsOn": "Einde" } - }, - "topics": { - "overview": { - "title": "Thema's", - "description": "Samenhangende waarden, gebundeld uit je eigen gegevens; open een thema om ze naast elkaar te zien.", - "emptyTitle": "Nog niets om te bundelen", - "emptyDescription": "Thema's verschijnen zodra er waarden voor zijn: van een apparaat, uit een import of door jou ingevoerd.", - "notRecorded": "Nog niets vastgelegd voor: {topics}.", - "hiddenByModule": "Verborgen omdat de module uit staat: {topics}.", - "modulesLink": "Modules wijzigen in de instellingen" - }, - "detail": { - "back": "Alle thema's" - }, - "loadError": "De thema's konden niet worden geladen.", - "previewNote": "Dit is een voorvertoning. Die kan per versie veranderen, en je pagina's per meetwaarde blijven zoals ze zijn.", - "recorded": "Vastgelegde waarden: {count} van {total}", - "tone": { - "steady": "Stabiel", - "watch": "Het bekijken waard", - "learning": "Leert nog" - }, - "summary": { - "outsideAbove": "{signal} ligt boven je gebruikelijke bereik.", - "outsideBelow": "{signal} ligt onder je gebruikelijke bereik.", - "labs": "{count} van {total} labwaarden liggen binnen hun referentiebereik.", - "cycleDay": "Cyclusdag {day}.", - "steadyAll": "Alles wat is vastgelegd ligt binnen je gebruikelijke bereik.", - "steadySome": "{count} van {total} waarden liggen binnen je gebruikelijke bereik; de andere worden nog geleerd.", - "learning": "Je gebruikelijke bereik wordt nog geleerd. Een week aan metingen is genoeg.", - "empty": "Nog niets vastgelegd." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "binnen bereik", - "cycleDay": "Dag {day}" - }, - "signals": { - "mood": "Stemming" - }, - "units": { - "moodScale": "van 5" - }, - "names": { - "heart": { - "title": "Hart", - "description": "Rusthartslag, hartslagvariabiliteit en conditie, met de slaap en training die ze beïnvloeden." - }, - "body": { - "title": "Lichaam", - "description": "Gewicht en lichaamssamenstelling door de tijd." - }, - "bloodPressure": { - "title": "Bloeddruk", - "description": "Systolisch, diastolisch en hartslag, met de slaap en activiteit eromheen." - }, - "sleep": { - "title": "Slaap", - "description": "Slaapduur en de waarden die 's nachts worden gemeten." - }, - "activity": { - "title": "Activiteit en training", - "description": "Stappen, trainingsminuten, actieve energie en trainingsbelasting." - }, - "metabolism": { - "title": "Stofwisseling en lab", - "description": "Bloedglucose en je labwaarden, met de trend van elke marker." - }, - "mind": { - "title": "Geest", - "description": "Stemming en vragenlijsten naast slaap en activiteit." - }, - "cycle": { - "title": "Cyclus", - "description": "Je cyclus met de temperatuur en rusthartslag die ermee meebewegen." - } - }, - "sources": { - "heart": "Deze waarden komen van een horloge, ring of borstband, uit Apple Gezondheid of Health Connect, of van je eigen invoer.", - "body": "Deze waarden komen van een slimme weegschaal, een import of je eigen invoer.", - "bloodPressure": "Deze waarden komen van een bloeddrukmeter, een import of je eigen invoer.", - "sleep": "Deze waarden komen van een horloge of ring, uit Apple Gezondheid of Health Connect, of van je eigen invoer.", - "activity": "Deze waarden komen van een telefoon, horloge of ring, of uit Apple Gezondheid of Health Connect.", - "metabolism": "Glucose komt van een meter, een sensorimport of je eigen invoer; labwaarden uit een labrapport of je eigen invoer.", - "mind": "Deze waarden komen uit je stemmingsregistraties en de vragenlijsten op de pagina Mentaal welzijn.", - "cycle": "Deze waarden komen uit je cycluslogboek en een temperatuursensor aan de pols." - }, - "today": { - "title": "Vandaag", - "usual": "Gebruikelijk {low}–{high}", - "learning": "Gebruikelijk bereik wordt nog geleerd", - "asOf": "Per {date}", - "details": "Details" - }, - "state": { - "within": "Binnen bereik", - "above": "Boven gebruikelijk", - "below": "Onder gebruikelijk", - "learning": "Leert nog" - }, - "chart": { - "title": "Naast elkaar", - "legend": "Gearceerd: je gebruikelijke bereik.", - "label": "{signals} in de gekozen periode, elk op een eigen rij." - }, - "range": { - "label": "Periode", - "7d": "7 d", - "30d": "30 d", - "90d": "90 d", - "1y": "1 j" - }, - "relationships": { - "title": "Hoe ze samen bewegen", - "insufficient": "{x} en {y}: tot nu toe {count} van {required} gedeelde dagen.", - "noClearLink": "Geen duidelijk verband tussen {x} en {y} over {count} gedeelde dagen.", - "splitHigher": "Als {x} onder {threshold} lag, was {y} {amount} hoger dan op andere dagen.", - "splitLower": "Als {x} onder {threshold} lag, was {y} {amount} lager dan op andere dagen.", - "splitDays": "Dagen eronder: {below}. Andere dagen: {other}.", - "correlationSameDayHigher": "Als {x} hoger is, is {y} meestal ook hoger (r = {r}).", - "correlationSameDayLower": "Als {x} hoger is, is {y} meestal lager (r = {r}).", - "correlationNextDayHigher": "Als {x} hoger is, is {y} de volgende dag meestal hoger (r = {r}).", - "correlationNextDayLower": "Als {x} hoger is, is {y} de volgende dag meestal lager (r = {r}).", - "pairedDays": "Gedeelde dagen: {count}", - "footnote": "Verschijnt zodra twee waarden op minstens 14 dagen samenvallen. Een patroon, geen oorzaak.", - "scatterCaption": "Elke stip is één dag: {x} horizontaal, {y} verticaal." - }, - "trends": { - "title": "Trends", - "window": "90 dagen, weekgemiddelden", - "insufficient": "Heeft 14 dagen nodig, nu {count}" - }, - "labs": { - "title": "Labwaarden", - "above": "Boven het bereik", - "below": "Onder het bereik", - "trendsTitle": "Trends", - "trendNeeds": "Een trend heeft drie waarden over minstens een jaar nodig. Nog niet: {markers}." - }, - "screeners": { - "title": "Vragenlijsten", - "none": "Nog geen vragenlijsten ingevuld.", - "checkIns": "Ingevuld: {count}", - "improved": "Beter dan de eerste keer", - "worsened": "Slechter dan de eerste keer", - "within_threshold": "Binnen de gebruikelijke schommeling", - "single": "Tot nu toe één keer ingevuld", - "open": "Mentaal welzijn openen" - }, - "cycle": { - "title": "Cyclus", - "today": "Cyclusdag {day}.", - "todayWithPhase": "Cyclusdag {day}, {phase}.", - "average": "Gemiddelde cycluslengte: {days} dagen.", - "needs": "Een gemiddelde heeft twee vastgelegde menstruatiestarts nodig; nu zijn het er {count}.", - "lengths": "Recente cycli in dagen: {lengths}", - "open": "Cycluspagina openen" - }, - "links": { - "title": "Pagina's per meetwaarde", - "workouts": "Workouts" - }, - "missing": { - "title": "Nog niet vastgelegd: {signals}.", - "connect": "Een bron koppelen" - } } } diff --git a/messages/pl.json b/messages/pl.json index 1d5b6e607..916c2239a 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -510,9 +510,7 @@ "documents": "Dokumenty", "vaccinations": "Szczepienia", "mentalWellbeing": "Dobrostan psychiczny", - "timeline": "Oś czasu", - "topics": "Tematy", - "previewBadge": "Beta" + "timeline": "Oś czasu" }, "auth": { "login": "Zaloguj się", @@ -6145,10 +6143,6 @@ "access": { "title": "Udostępniony dostęp", "subtitle": "Kto może otworzyć twoją kartę zdrowia i czyją kartę możesz otworzyć ty." - }, - "preview": { - "title": "Funkcje w wersji próbnej", - "subtitle": "Wypróbuj to, co jeszcze nie jest gotowe. Wszystko tutaj pozostaje wyłączone, dopóki tego nie włączysz." } }, "profile": "Profil", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Usunięto passkey.", "integrationDisconnected": "Rozłączono {provider}.", "integrationDisconnectFailed": "Nie udało się rozłączyć {provider}.", - "preview": { - "topics": { - "title": "Tematy", - "description": "Dodaje obszar Tematy, który zbiera powiązane wartości, obok Twoich stron Insights.", - "detail": "Osiem tematów, od serca po cykl, pokazuje Twoje wartości obok siebie, jak zmieniają się razem, oraz linki do stron pojedynczych wskaźników, których już używasz. Strony Insights, nawigacja i linki zostają dokładnie takie, jakie są. Wszystko jest liczone z Twoich własnych wartości, bez AI. Wyłączenie usuwa wpis i niczego nie kasuje.", - "savedOn": "Wersja próbna Tematów włączona.", - "savedOff": "Wersja próbna Tematów wyłączona.", - "open": "Otwórz Tematy" - }, - "loadError": "Nie udało się wczytać ustawień wersji próbnych." - }, "timezoneSaved": "Strefa czasowa zapisana.", "moduleState": { "on": "Włączone", @@ -13782,171 +13765,5 @@ "startsOn": "Początek", "endsOn": "Koniec" } - }, - "topics": { - "overview": { - "title": "Tematy", - "description": "Powiązane wartości zebrane z Twoich danych; otwórz temat, aby zobaczyć je obok siebie.", - "emptyTitle": "Na razie nie ma czego zebrać", - "emptyDescription": "Tematy pojawiają się, gdy są dla nich wartości: z urządzenia, z importu lub wpisane przez Ciebie.", - "notRecorded": "Brak jeszcze wartości dla: {topics}.", - "hiddenByModule": "Ukryte, bo moduł jest wyłączony: {topics}.", - "modulesLink": "Zmień moduły w ustawieniach" - }, - "detail": { - "back": "Wszystkie tematy" - }, - "loadError": "Nie udało się wczytać tematów.", - "previewNote": "To wersja próbna. Może się zmieniać między wydaniami, a strony pojedynczych wskaźników zostają bez zmian.", - "recorded": "Zapisane wartości: {count} z {total}", - "tone": { - "steady": "Stabilnie", - "watch": "Warto zerknąć", - "learning": "W trakcie nauki" - }, - "summary": { - "outsideAbove": "{signal} jest powyżej Twojego zwykłego zakresu.", - "outsideBelow": "{signal} jest poniżej Twojego zwykłego zakresu.", - "labs": "{count} z {total} wyników badań mieści się w zakresie referencyjnym.", - "cycleDay": "Dzień cyklu {day}.", - "steadyAll": "Wszystko, co zapisane, mieści się w Twoim zwykłym zakresie.", - "steadySome": "{count} z {total} wartości mieści się w Twoim zwykłym zakresie; pozostałe są jeszcze poznawane.", - "learning": "Twój zwykły zakres jest jeszcze poznawany. Wystarczy tydzień pomiarów.", - "empty": "Nic jeszcze nie zapisano." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "w zakresie", - "cycleDay": "Dzień {day}" - }, - "signals": { - "mood": "Nastrój" - }, - "units": { - "moodScale": "z 5" - }, - "names": { - "heart": { - "title": "Serce", - "description": "Tętno spoczynkowe, zmienność rytmu serca i wydolność, wraz ze snem i treningiem, które na nie wpływają." - }, - "body": { - "title": "Ciało", - "description": "Masa ciała i skład ciała w czasie." - }, - "bloodPressure": { - "title": "Ciśnienie krwi", - "description": "Skurczowe, rozkurczowe i tętno, wraz ze snem i aktywnością wokół nich." - }, - "sleep": { - "title": "Sen", - "description": "Czas snu i wartości mierzone w nocy." - }, - "activity": { - "title": "Aktywność i trening", - "description": "Kroki, minuty ćwiczeń, aktywna energia i obciążenie treningowe." - }, - "metabolism": { - "title": "Metabolizm i badania", - "description": "Glukoza i Twoje wyniki badań, z trendem każdego markera." - }, - "mind": { - "title": "Psychika", - "description": "Nastrój i kwestionariusze obok snu i aktywności." - }, - "cycle": { - "title": "Cykl", - "description": "Twój cykl wraz z temperaturą i tętnem spoczynkowym, które za nim podążają." - } - }, - "sources": { - "heart": "Te wartości pochodzą z zegarka, pierścienia lub pasa piersiowego, z Apple Zdrowie lub Health Connect albo z Twoich wpisów.", - "body": "Te wartości pochodzą z inteligentnej wagi, z importu lub z Twoich wpisów.", - "bloodPressure": "Te wartości pochodzą z ciśnieniomierza, z importu lub z Twoich wpisów.", - "sleep": "Te wartości pochodzą z zegarka lub pierścienia, z Apple Zdrowie lub Health Connect albo z Twoich wpisów.", - "activity": "Te wartości pochodzą z telefonu, zegarka lub pierścienia albo z Apple Zdrowie lub Health Connect.", - "metabolism": "Glukoza pochodzi z glukometru, importu z sensora lub Twoich wpisów; wyniki badań z raportu laboratoryjnego lub Twoich wpisów.", - "mind": "Te wartości pochodzą z Twoich wpisów nastroju i kwestionariuszy na stronie Dobrostan psychiczny.", - "cycle": "Te wartości pochodzą z Twojego dziennika cyklu i czujnika temperatury na nadgarstku." - }, - "today": { - "title": "Dziś", - "usual": "Zwykle {low}–{high}", - "learning": "Zwykły zakres jest jeszcze poznawany", - "asOf": "Stan na {date}", - "details": "Szczegóły" - }, - "state": { - "within": "W zakresie", - "above": "Powyżej zwykłego", - "below": "Poniżej zwykłego", - "learning": "W trakcie nauki" - }, - "chart": { - "title": "Obok siebie", - "legend": "Zacieniowane: Twój zwykły zakres.", - "label": "{signals} w wybranym okresie, każdy w osobnym wierszu." - }, - "range": { - "label": "Okres", - "7d": "7 d", - "30d": "30 d", - "90d": "90 d", - "1y": "1 r" - }, - "relationships": { - "title": "Jak zmieniają się razem", - "insufficient": "{x} i {y}: na razie {count} z {required} wspólnych dni.", - "noClearLink": "Brak wyraźnego związku między {x} a {y} w ciągu {count} wspólnych dni.", - "splitHigher": "Gdy {x} było poniżej {threshold}, {y} było o {amount} wyższe niż w inne dni.", - "splitLower": "Gdy {x} było poniżej {threshold}, {y} było o {amount} niższe niż w inne dni.", - "splitDays": "Dni poniżej: {below}. Pozostałe dni: {other}.", - "correlationSameDayHigher": "Gdy {x} jest wyższe, {y} zwykle też jest wyższe (r = {r}).", - "correlationSameDayLower": "Gdy {x} jest wyższe, {y} zwykle jest niższe (r = {r}).", - "correlationNextDayHigher": "Gdy {x} jest wyższe, następnego dnia {y} zwykle jest wyższe (r = {r}).", - "correlationNextDayLower": "Gdy {x} jest wyższe, następnego dnia {y} zwykle jest niższe (r = {r}).", - "pairedDays": "Wspólne dni: {count}", - "footnote": "Pokazywane, gdy dwie wartości pokrywają się przez co najmniej 14 dni. Wzorzec, nie przyczyna.", - "scatterCaption": "Każdy punkt to jeden dzień: {x} w poziomie, {y} w pionie." - }, - "trends": { - "title": "Trendy", - "window": "90 dni, średnie tygodniowe", - "insufficient": "Potrzeba 14 dni, na razie {count}" - }, - "labs": { - "title": "Wyniki badań", - "above": "Powyżej zakresu", - "below": "Poniżej zakresu", - "trendsTitle": "Trendy", - "trendNeeds": "Trend wymaga trzech wartości w ciągu co najmniej roku. Jeszcze nie: {markers}." - }, - "screeners": { - "title": "Kwestionariusze", - "none": "Nie wypełniono jeszcze żadnego kwestionariusza.", - "checkIns": "Wypełnione: {count}", - "improved": "Lepiej niż za pierwszym razem", - "worsened": "Gorzej niż za pierwszym razem", - "within_threshold": "W granicach zwykłych wahań", - "single": "Na razie wypełniony raz", - "open": "Otwórz Dobrostan psychiczny" - }, - "cycle": { - "title": "Cykl", - "today": "Dzień cyklu {day}.", - "todayWithPhase": "Dzień cyklu {day}, faza: {phase}.", - "average": "Średnia długość cyklu: {days} dni.", - "needs": "Średnia wymaga dwóch zapisanych początków miesiączki; na razie jest ich {count}.", - "lengths": "Ostatnie cykle w dniach: {lengths}", - "open": "Otwórz stronę cyklu" - }, - "links": { - "title": "Strony wskaźników", - "workouts": "Treningi" - }, - "missing": { - "title": "Jeszcze nie zapisano: {signals}.", - "connect": "Połącz źródło" - } } } diff --git a/messages/pt-BR.json b/messages/pt-BR.json index 273caaff9..fcd90cced 100644 --- a/messages/pt-BR.json +++ b/messages/pt-BR.json @@ -510,9 +510,7 @@ "documents": "Documentos", "vaccinations": "Vacinas", "mentalWellbeing": "Bem-estar mental", - "timeline": "Linha do tempo", - "topics": "Temas", - "previewBadge": "Beta" + "timeline": "Linha do tempo" }, "auth": { "login": "Entrar", @@ -6145,10 +6143,6 @@ "access": { "title": "Acesso compartilhado", "subtitle": "Quem pode abrir seu registro de saúde e de quem você pode abrir." - }, - "preview": { - "title": "Recursos em prévia", - "subtitle": "Experimente o que ainda não está pronto. Tudo aqui fica desligado até você ativar." } }, "profile": "Perfil", @@ -7634,17 +7628,6 @@ "passkeyRemovedToast": "Chave de acesso removida.", "integrationDisconnected": "{provider} desconectado.", "integrationDisconnectFailed": "Não foi possível desconectar {provider}.", - "preview": { - "topics": { - "title": "Temas", - "description": "Adiciona uma área Temas que reúne valores relacionados, ao lado das suas páginas de Análises.", - "detail": "Oito temas, do coração ao ciclo, mostram seus valores lado a lado, como eles variam juntos e links para as páginas por métrica que você já usa. Suas páginas de Análises, a navegação e os links continuam exatamente como estão. Tudo é calculado a partir dos seus próprios valores, sem IA. Desativar remove a entrada e não apaga nada.", - "savedOn": "Prévia de Temas ativada.", - "savedOff": "Prévia de Temas desativada.", - "open": "Abrir Temas" - }, - "loadError": "Não foi possível carregar suas configurações de prévia." - }, "timezoneSaved": "Fuso horário salvo.", "moduleState": { "on": "Ligado", @@ -13782,171 +13765,5 @@ "startsOn": "Início", "endsOn": "Fim" } - }, - "topics": { - "overview": { - "title": "Temas", - "description": "Valores relacionados reunidos a partir dos seus dados; abra um tema para vê-los lado a lado.", - "emptyTitle": "Ainda não há o que reunir", - "emptyDescription": "Os temas aparecem assim que houver valores para eles: de um dispositivo, de uma importação ou registrados por você.", - "notRecorded": "Ainda sem registros para: {topics}.", - "hiddenByModule": "Ocultos porque o módulo está desligado: {topics}.", - "modulesLink": "Alterar módulos nas configurações" - }, - "detail": { - "back": "Todos os temas" - }, - "loadError": "Não foi possível carregar os temas.", - "previewNote": "Isto é uma prévia. Pode mudar entre versões, e suas páginas por métrica continuam como estão.", - "recorded": "Valores registrados: {count} de {total}", - "tone": { - "steady": "Estável", - "watch": "Vale uma olhada", - "learning": "Aprendendo" - }, - "summary": { - "outsideAbove": "{signal} está acima da sua faixa habitual.", - "outsideBelow": "{signal} está abaixo da sua faixa habitual.", - "labs": "{count} de {total} exames estão dentro da faixa de referência.", - "cycleDay": "Dia {day} do ciclo.", - "steadyAll": "Tudo o que foi registrado está dentro da sua faixa habitual.", - "steadySome": "{count} de {total} valores estão dentro da sua faixa habitual; os demais ainda estão sendo aprendidos.", - "learning": "Sua faixa habitual ainda está sendo aprendida. Uma semana de registros basta.", - "empty": "Nada registrado ainda." - }, - "headline": { - "labsValue": "{count}/{total}", - "labsUnit": "na faixa", - "cycleDay": "Dia {day}" - }, - "signals": { - "mood": "Humor" - }, - "units": { - "moodScale": "de 5" - }, - "names": { - "heart": { - "title": "Coração", - "description": "Frequência cardíaca em repouso, variabilidade e condicionamento, com o sono e o treino que os influenciam." - }, - "body": { - "title": "Corpo", - "description": "Peso e composição corporal ao longo do tempo." - }, - "bloodPressure": { - "title": "Pressão arterial", - "description": "Sistólica, diastólica e pulso, com o sono e a atividade ao redor." - }, - "sleep": { - "title": "Sono", - "description": "Tempo dormindo e os valores medidos à noite." - }, - "activity": { - "title": "Atividade e treino", - "description": "Passos, minutos de exercício, energia ativa e carga de treino." - }, - "metabolism": { - "title": "Metabolismo e exames", - "description": "Glicose e seus exames, com a tendência de cada marcador." - }, - "mind": { - "title": "Mente", - "description": "Humor e questionários ao lado do sono e da atividade." - }, - "cycle": { - "title": "Ciclo", - "description": "Seu ciclo com a temperatura e a frequência cardíaca em repouso que o acompanham." - } - }, - "sources": { - "heart": "Esses valores vêm de um relógio, anel ou cinta peitoral, do Apple Saúde ou do Health Connect, ou dos seus registros.", - "body": "Esses valores vêm de uma balança inteligente, de uma importação ou dos seus registros.", - "bloodPressure": "Esses valores vêm de um medidor de pressão, de uma importação ou dos seus registros.", - "sleep": "Esses valores vêm de um relógio ou anel, do Apple Saúde ou do Health Connect, ou dos seus registros.", - "activity": "Esses valores vêm de um celular, relógio ou anel, ou do Apple Saúde ou do Health Connect.", - "metabolism": "A glicose vem de um glicosímetro, de uma importação do sensor ou dos seus registros; os exames, de um laudo ou dos seus registros.", - "mind": "Esses valores vêm dos seus registros de humor e dos questionários da página Bem-estar mental.", - "cycle": "Esses valores vêm do seu registro do ciclo e de um sensor de temperatura no pulso." - }, - "today": { - "title": "Hoje", - "usual": "Habitual {low}–{high}", - "learning": "Faixa habitual ainda em aprendizado", - "asOf": "Em {date}", - "details": "Detalhes" - }, - "state": { - "within": "Dentro", - "above": "Acima do habitual", - "below": "Abaixo do habitual", - "learning": "Aprendendo" - }, - "chart": { - "title": "Lado a lado", - "legend": "Sombreado: sua faixa habitual.", - "label": "{signals} no período escolhido, uma linha cada." - }, - "range": { - "label": "Período", - "7d": "7d", - "30d": "30d", - "90d": "90d", - "1y": "1a" - }, - "relationships": { - "title": "Como eles variam juntos", - "insufficient": "{x} e {y}: {count} de {required} dias pareados até agora.", - "noClearLink": "Nenhuma relação clara entre {x} e {y} em {count} dias pareados.", - "splitHigher": "Quando {x} ficou abaixo de {threshold}, {y} foi {amount} mais alto do que nos outros dias.", - "splitLower": "Quando {x} ficou abaixo de {threshold}, {y} foi {amount} mais baixo do que nos outros dias.", - "splitDays": "Dias abaixo: {below}. Outros dias: {other}.", - "correlationSameDayHigher": "Quando {x} sobe, {y} também tende a ficar mais alto (r = {r}).", - "correlationSameDayLower": "Quando {x} sobe, {y} tende a ficar mais baixo (r = {r}).", - "correlationNextDayHigher": "Quando {x} sobe, {y} tende a ficar mais alto no dia seguinte (r = {r}).", - "correlationNextDayLower": "Quando {x} sobe, {y} tende a ficar mais baixo no dia seguinte (r = {r}).", - "pairedDays": "Dias pareados: {count}", - "footnote": "Aparece quando dois valores coincidem em pelo menos 14 dias. Um padrão, não uma causa.", - "scatterCaption": "Cada ponto é um dia: {x} na horizontal, {y} na vertical." - }, - "trends": { - "title": "Tendências", - "window": "90 dias, médias semanais", - "insufficient": "Precisa de 14 dias, {count} até agora" - }, - "labs": { - "title": "Exames", - "above": "Acima da faixa", - "below": "Abaixo da faixa", - "trendsTitle": "Tendências", - "trendNeeds": "Uma tendência precisa de três valores ao longo de pelo menos um ano. Ainda não: {markers}." - }, - "screeners": { - "title": "Questionários", - "none": "Nenhum questionário respondido ainda.", - "checkIns": "Respondidos: {count}", - "improved": "Melhor que na primeira vez", - "worsened": "Pior que na primeira vez", - "within_threshold": "Dentro da variação habitual", - "single": "Respondido uma vez até agora", - "open": "Abrir Bem-estar mental" - }, - "cycle": { - "title": "Ciclo", - "today": "Dia {day} do ciclo.", - "todayWithPhase": "Dia {day} do ciclo, fase {phase}.", - "average": "Duração média do ciclo: {days} dias.", - "needs": "Uma média precisa de dois inícios de menstruação registrados; até agora são {count}.", - "lengths": "Ciclos recentes, em dias: {lengths}", - "open": "Abrir a página do ciclo" - }, - "links": { - "title": "Páginas por métrica", - "workouts": "Treinos" - }, - "missing": { - "title": "Ainda não registrado: {signals}.", - "connect": "Conectar uma fonte" - } } } diff --git a/src/__tests__/baselines/test-as-never.json b/src/__tests__/baselines/test-as-never.json index f342756a4..e852565a5 100644 --- a/src/__tests__/baselines/test-as-never.json +++ b/src/__tests__/baselines/test-as-never.json @@ -1,7 +1,7 @@ { "$comment": "as never casts in tests, per test file under src/. Maintained by src/__tests__/test-realism-ratchet.test.ts.", - "count": 523, - "total": 5494, + "count": 524, + "total": 5495, "entries": { "__tests__/api/auth/login/mfa-branch.test.ts": 10, "__tests__/api/auth/mfa/verify.test.ts": 9, @@ -273,6 +273,7 @@ "components/medications/__tests__/use-medication-intake.test.ts": 1, "components/medications/detail/efficacy/__tests__/change-at-start-summary.test.tsx": 1, "components/mood/__tests__/mood-list-url-sync.test.tsx": 1, + "components/settings/__tests__/settings-shell.test.tsx": 1, "components/settings/integrations/__tests__/dawarich-card.test.tsx": 1, "components/timeline/__tests__/medication-rows.test.ts": 1, "lib/__tests__/acting-account-resolver.test.ts": 5, diff --git a/src/__tests__/baselines/version-stamp-comments.json b/src/__tests__/baselines/version-stamp-comments.json index 65ad892a5..b3e1eff8f 100644 --- a/src/__tests__/baselines/version-stamp-comments.json +++ b/src/__tests__/baselines/version-stamp-comments.json @@ -1,7 +1,7 @@ { "$comment": "Comment lines that open with a release version, per file under src/. Maintained by src/__tests__/version-stamp-ratchet.test.ts.", "count": 2954, - "total": 10499, + "total": 10500, "entries": { "__tests__/account-payload-consumer-guard.test.ts": 2, "__tests__/acting-account-boundary-guard.test.ts": 7, @@ -2807,7 +2807,7 @@ "lib/rollups/mood-rollups.ts": 4, "lib/rollups/tiered-context.ts": 6, "lib/score-config/rows.ts": 1, - "lib/settings/section-slugs.ts": 19, + "lib/settings/section-slugs.ts": 20, "lib/sharing/__tests__/account-access-parse.test.ts": 3, "lib/sharing/__tests__/account-access.test.ts": 2, "lib/sharing/__tests__/account-label.test.ts": 1, diff --git a/src/__tests__/settings-copy-tense.test.ts b/src/__tests__/settings-copy-tense.test.ts index b45b9b172..f6298b988 100644 --- a/src/__tests__/settings-copy-tense.test.ts +++ b/src/__tests__/settings-copy-tense.test.ts @@ -3,9 +3,8 @@ * * The workout-route switch is off for new accounts, which is what its detail * says rather than "off by default": an account that already held tracks at - * the upgrade started with it on (migration 0434). The Topics preview switch - * this file also held describes pages that now exist, so its copy is in the - * present tense like every other switch. + * the upgrade started with it on (migration 0434). (The Topics preview switch + * this file also held is unlisted until its pages ship, and its copy with it.) */ import { describe, expect, it } from "vitest"; diff --git a/src/__tests__/settings-legacy-routes.test.ts b/src/__tests__/settings-legacy-routes.test.ts index e2f037db5..870b11045 100644 --- a/src/__tests__/settings-legacy-routes.test.ts +++ b/src/__tests__/settings-legacy-routes.test.ts @@ -54,8 +54,6 @@ const HISTORICAL_SETTINGS_PATHS: readonly string[] = [ "/settings/export", "/settings/advanced", "/settings/privacy", - // Preview features (Settings > System). - "/settings/preview", "/settings/about", // The per-module personalisation slugs before the layout hub. "/settings/dashboard", diff --git a/src/app/topics/[topic]/page.tsx b/src/app/topics/[topic]/page.tsx deleted file mode 100644 index b7a8c0553..000000000 --- a/src/app/topics/[topic]/page.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { notFound } from "next/navigation"; - -import { TopicDetailView } from "@/components/topics/topic-detail"; -import { TopicsPreviewGate } from "@/components/topics/topics-preview-gate"; -import { isTopicKey } from "@/lib/topics/registry"; - -/** - * `/topics/` (preview): one topic page. A name that is not a topic is - * a 404 here, before anything renders; the preview switch is checked by the - * gate, the record's modules by the route behind the page. - */ -export default async function TopicPage({ - params, -}: { - params: Promise<{ topic: string }>; -}) { - const { topic } = await params; - if (!isTopicKey(topic)) notFound(); - return ( - - - - ); -} diff --git a/src/app/topics/page.tsx b/src/app/topics/page.tsx deleted file mode 100644 index 8161b826b..000000000 --- a/src/app/topics/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { TopicsOverview } from "@/components/topics/topics-overview"; -import { TopicsPreviewGate } from "@/components/topics/topics-preview-gate"; - -/** - * `/topics` (preview): the topic overview. Exists only for a person who - * switched the preview on; see `TopicsPreviewGate`. - */ -export default function TopicsPage() { - return ( - - - - ); -} diff --git a/src/components/charts/chart-runtime.ts b/src/components/charts/chart-runtime.ts index 0370e413f..5b4cc66a2 100644 --- a/src/components/charts/chart-runtime.ts +++ b/src/components/charts/chart-runtime.ts @@ -58,4 +58,3 @@ export { NutrientDailyBarChart } from "./nutrient-daily-bar-chart"; export { WorkoutHrChart } from "./workout-hr-chart"; export { WorkoutElevationChart } from "./workout-elevation-chart"; export { CoachResultChart } from "@/components/insights/coach-panel/result-chart"; -export { TopicSideBySideChart } from "@/components/topics/topic-side-by-side-chart"; diff --git a/src/components/command-palette/__tests__/build-index.test.ts b/src/components/command-palette/__tests__/build-index.test.ts index deecb4045..0dfdf379b 100644 --- a/src/components/command-palette/__tests__/build-index.test.ts +++ b/src/components/command-palette/__tests__/build-index.test.ts @@ -12,7 +12,6 @@ function index(over: Partial = {}) { t, modules: {}, navModules: {}, - previews: null, inSharedRecord: false, sections: null, isAdmin: false, @@ -28,16 +27,6 @@ function index(over: Partial = {}) { const ids = (entries: ReturnType) => entries.map((e) => e.id); -describe("buildPaletteIndex — previews", () => { - it("offers the Topics page only while the person switched the preview on", () => { - expect(ids(index())).not.toContain("nav:/topics"); - expect(ids(index({ previews: { topics: false } }))).not.toContain( - "nav:/topics", - ); - expect(ids(index({ previews: { topics: true } }))).toContain("nav:/topics"); - }); -}); - describe("buildPaletteIndex — modules", () => { it("a switched-off module takes its page, its Insights page and its cards along", () => { const off = { mood: false, timeline: false, environment: false }; diff --git a/src/components/command-palette/build-index.ts b/src/components/command-palette/build-index.ts index 1295a6159..112c8ac74 100644 --- a/src/components/command-palette/build-index.ts +++ b/src/components/command-palette/build-index.ts @@ -18,7 +18,6 @@ import { SETTINGS_SECTIONS } from "@/components/settings/settings-shell"; import { SUB_PAGE_SLUGS } from "@/lib/insights/sub-page-metric"; import { MODULE_REGISTRY, type ModuleKey } from "@/lib/modules/registry"; import { isSurfaceVisible, type SurfaceModuleMap } from "@/lib/modules/surface"; -import type { PreviewFeatures } from "@/lib/settings/preview-features"; import type { ShareDomain } from "@/lib/sharing/scope"; import { @@ -75,8 +74,6 @@ export interface PaletteIndexInput { modules: SurfaceModuleMap | undefined; /** The same map with `coach` following the AI capability (`useNavModules`). */ navModules: SurfaceModuleMap | undefined; - /** The person's own preview opt-ins; null offers no preview page. */ - previews: PreviewFeatures | null; inSharedRecord: boolean; /** The shared record's covered sections, when there is one. */ sections: ReadonlyArray | null; @@ -124,7 +121,6 @@ export function buildPaletteIndex(input: PaletteIndexInput): PaletteEntry[] { true, input.inSharedRecord, input.sections, - input.previews, ); const navHrefs = new Set(nav.map((d) => d.href)); for (const d of nav) { diff --git a/src/components/command-palette/use-palette-index.ts b/src/components/command-palette/use-palette-index.ts index 533e2dc43..32eb9a68d 100644 --- a/src/components/command-palette/use-palette-index.ts +++ b/src/components/command-palette/use-palette-index.ts @@ -10,7 +10,6 @@ import { useAiCapability } from "@/hooks/use-ai-capability"; import { useAuth } from "@/hooks/use-auth"; import { useModuleEnabledState } from "@/hooks/use-module-toggle"; import { useNavModules } from "@/hooks/use-nav-modules"; -import { usePreviewFeatures } from "@/hooks/use-preview-features"; import { useRecordCapabilities } from "@/hooks/use-record-capabilities"; import { buildPaletteIndex, @@ -33,7 +32,6 @@ export function usePaletteIndex(): PaletteEntry[] { const { t } = useTranslations(); const { user } = useAuth(); const navModules = useNavModules(); - const previews = usePreviewFeatures(); const capabilities = useRecordCapabilities(); const { inSharedRecord, sections, recordKind, level } = capabilities; const coach = useAiCapability("coach"); @@ -66,7 +64,6 @@ export function usePaletteIndex(): PaletteEntry[] { t, modules: user?.modules, navModules, - previews, inSharedRecord, sections, isAdmin: user?.role === "ADMIN", @@ -88,7 +85,6 @@ export function usePaletteIndex(): PaletteEntry[] { user?.modules, user?.role, navModules, - previews, inSharedRecord, sections, recordKind, diff --git a/src/components/labs/lab-trend-card.tsx b/src/components/labs/lab-trend-card.tsx index 2198493fc..94f87a107 100644 --- a/src/components/labs/lab-trend-card.tsx +++ b/src/components/labs/lab-trend-card.tsx @@ -6,7 +6,6 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { TileHeader } from "@/components/insights/tile-header"; import { useFormatters, useTranslations } from "@/lib/i18n/context"; -import { labTrendLines } from "./lab-trend-lines"; import type { BiomarkerTrendDto } from "./types"; /** @@ -28,12 +27,44 @@ export function LabTrendCard({ const fmt = useFormatters(); if (!trend || trend.status !== "ok") return null; - const { slope: slopeLine, projection: projectionLine } = labTrendLines( - trend, + const digits = Math.abs(trend.slopePerYear) >= 10 ? 0 : 2; + const per = (v: number) => fmt.number(Math.abs(v), digits); + const direction = + trend.slopePerYear > 0 + ? "rising" + : trend.slopePerYear < 0 + ? "falling" + : "flat"; + const slopeLine = t(`labs.trend.slope.${direction}`, { + amount: per(trend.slopePerYear), unit, - t, - fmt, - ); + n: trend.n, + since: fmt.dateShortSmartCalendar(trend.firstAt), + }); + const projectionLine = + trend.projection === "exits" && trend.exitDate + ? t(`labs.trend.projection.exits.${trend.exitBound ?? "high"}`, { + date: fmt.dateShortSmartCalendar(trend.exitDate), + }) + : trend.projection === "no_band" + ? null + : trend.projection === "stale" + ? t("labs.trend.projection.stale", { + date: fmt.dateShortSmartCalendar(trend.lastAt), + }) + : trend.projection === "beyond_horizon" + ? t( + trend.horizonCapped + ? "labs.trend.projection.beyond_horizon_capped" + : "labs.trend.projection.beyond_horizon", + { + years: fmt.number( + trend.horizonYears, + trend.horizonCapped ? 0 : 1, + ), + }, + ) + : t(`labs.trend.projection.${trend.projection}`); return ( diff --git a/src/components/labs/lab-trend-lines.ts b/src/components/labs/lab-trend-lines.ts deleted file mode 100644 index 2619b257c..000000000 --- a/src/components/labs/lab-trend-lines.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { Formatters } from "@/lib/format-locale"; - -import type { BiomarkerTrendDto } from "./types"; - -type Translate = ( - key: string, - params?: Record, -) => string; - -/** - * The two sentences a lab trend reads as: the slope across the readings, and - * where the straight line would meet the reference band (or why it is not - * drawn). Shared by the marker page's trend card and the metabolism topic, so - * one trend is never worded two ways. - */ -export function labTrendLines( - trend: Extract, - unit: string, - t: Translate, - fmt: Formatters, -): { slope: string; projection: string | null } { - const digits = Math.abs(trend.slopePerYear) >= 10 ? 0 : 2; - const direction = - trend.slopePerYear > 0 - ? "rising" - : trend.slopePerYear < 0 - ? "falling" - : "flat"; - const slope = t(`labs.trend.slope.${direction}`, { - amount: fmt.number(Math.abs(trend.slopePerYear), digits), - unit, - n: trend.n, - since: fmt.dateShortSmartCalendar(trend.firstAt), - }); - const projection = - trend.projection === "exits" && trend.exitDate - ? t(`labs.trend.projection.exits.${trend.exitBound ?? "high"}`, { - date: fmt.dateShortSmartCalendar(trend.exitDate), - }) - : trend.projection === "no_band" - ? null - : trend.projection === "stale" - ? t("labs.trend.projection.stale", { - date: fmt.dateShortSmartCalendar(trend.lastAt), - }) - : trend.projection === "beyond_horizon" - ? t( - trend.horizonCapped - ? "labs.trend.projection.beyond_horizon_capped" - : "labs.trend.projection.beyond_horizon", - { - years: fmt.number( - trend.horizonYears, - trend.horizonCapped ? 0 : 1, - ), - }, - ) - : t(`labs.trend.projection.${trend.projection}`); - return { slope, projection }; -} diff --git a/src/components/layout/__tests__/nav-model-shared-record.test.ts b/src/components/layout/__tests__/nav-model-shared-record.test.ts index ca870e5da..a635feb9f 100644 --- a/src/components/layout/__tests__/nav-model-shared-record.test.ts +++ b/src/components/layout/__tests__/nav-model-shared-record.test.ts @@ -105,31 +105,13 @@ describe("the destination list under a switch", () => { }); it("changes nothing for a session in its own record", () => { - const own = visibleNavDestinations(ALL_MODULES, true, false, null, { - topics: true, - }).map((d) => d.href); + const own = visibleNavDestinations(ALL_MODULES, true).map((d) => d.href); expect(own).toEqual( NAV_DESTINATIONS.filter((d) => !d.sharedRecordOnly).map((d) => d.href), ); expect(own).not.toContain("/profile"); }); - it("offers Topics inside a whole-record share only with the viewer's own preview on", () => { - const share = (previews: { topics: boolean } | null) => - visibleNavDestinations(ALL_MODULES, true, true, null, previews).map( - (d) => d.href, - ); - expect(share({ topics: true })).toContain("/topics"); - expect(share({ topics: false })).not.toContain("/topics"); - expect(share(null)).not.toContain("/topics"); - // A grant scoped to sections never opens a page that lays them side by side. - expect( - visibleNavDestinations(ALL_MODULES, true, true, ["measurements"], { - topics: true, - }).map((d) => d.href), - ).not.toContain("/topics"); - }); - it("offers the read-only profile summary only inside a shared record", () => { expect(hrefsInSharedRecord()).toContain("/profile"); }); diff --git a/src/components/layout/__tests__/nav-model.test.ts b/src/components/layout/__tests__/nav-model.test.ts index 85db16d55..294d53a9d 100644 --- a/src/components/layout/__tests__/nav-model.test.ts +++ b/src/components/layout/__tests__/nav-model.test.ts @@ -215,42 +215,6 @@ describe("mobileMoreHubDestinations — the F-1 mobile invariant (feature-only h }); }); -describe("a preview entry (Topics)", () => { - it("exists only while the person reading switched the preview on", () => { - const hrefs = (previews: { topics: boolean } | null, mounted = true) => - visibleNavDestinations({}, mounted, false, null, previews).map( - (d) => d.href, - ); - expect(hrefs(null)).not.toContain("/topics"); - expect(hrefs({ topics: false })).not.toContain("/topics"); - expect(hrefs({ topics: true })).toContain("/topics"); - // Fail-closed before mount, so SSR and the first paint agree. - expect(hrefs({ topics: true }, false)).not.toContain("/topics"); - }); - - it("sits directly below Insights in the sidebar", () => { - const hrefs = visibleNavDestinations({}, true, false, null, { - topics: true, - }).map((d) => d.href); - expect(hrefs[hrefs.indexOf("/insights") + 1]).toBe("/topics"); - }); - - it("leads the phone's More hub with its badge and never takes a bottom-bar slot", () => { - const hub = mobileMoreHubDestinations({ - modules: {}, - previews: { topics: true }, - }); - expect(hub[0]).toMatchObject({ href: "/topics", preview: "topics" }); - expect(BOTTOM_NAV_PRIMARY_SLOT_HREFS).not.toContain("/topics"); - expect( - mobileMoreHubDestinations({ - modules: {}, - previews: { topics: false }, - }).map((d) => d.href), - ).not.toContain("/topics"); - }); -}); - describe("isNavDestinationActive most-specific resolution", () => { it("matches the dashboard only on an exact path", () => { expect(isNavDestinationActive("/", "/")).toBe(true); diff --git a/src/components/layout/bottom-nav.tsx b/src/components/layout/bottom-nav.tsx index 89984ba22..dbb11755a 100644 --- a/src/components/layout/bottom-nav.tsx +++ b/src/components/layout/bottom-nav.tsx @@ -21,8 +21,6 @@ import { isSurfaceVisible } from "@/lib/modules/surface"; import { useCallback, useMemo, useState } from "react"; import { useAuth } from "@/hooks/use-auth"; import { useNavModules } from "@/hooks/use-nav-modules"; -import { usePreviewFeatures } from "@/hooks/use-preview-features"; -import { PreviewBadge } from "@/components/topics/preview-badge"; import { useMounted } from "@/hooks/use-mounted"; import { useRecordCapabilities } from "@/hooks/use-record-capabilities"; import { @@ -44,8 +42,6 @@ interface NavLink { href: string; tKey: string; icon: LucideIcon; - /** A preview entry; its tile carries the Beta badge. */ - preview?: string; } // v1.12.x — iOS-parity bottom bar (additive middle-path). @@ -115,7 +111,6 @@ export function BottomNav() { // The Coach entry follows the `coach` AI capability (a Coach that cannot // answer is not offered); the sidebar reads the same map. const navModules = useNavModules(); - const previews = usePreviewFeatures(); const moreHub = useMemo>( () => mobileMoreHubDestinations({ @@ -123,9 +118,8 @@ export function BottomNav() { mounted, sharedRecord, sections, - previews, }), - [navModules, mounted, sharedRecord, sections, previews], + [navModules, mounted, sharedRecord, sections], ); // Every slot but Home asks two things: does sharing cover it, and does its @@ -295,72 +289,52 @@ export function BottomNav() { second line instead of clipping the last character at the tile edge. */}
- {moreHub.map((item) => ( - setMoreOpen(false)} - /> - ))} + {moreHub.map((item) => { + const isActive = isActiveLink(item.href); + return ( + setMoreOpen(false)} + aria-current={isActive ? "page" : undefined} + // v1.12 — `min-h-14` matches the capture-picker tiles so + // the equivalent tappable rows share one height at this + // tier (and the larger row is a more comfortable target). + // v1.22.1 — trim the inner padding/gap (`px-3`, `gap-2.5`) + // to hand the label more horizontal room without changing + // the shared tile height. + className={cn( + "border-border flex min-h-14 items-center gap-2.5 rounded-lg border px-3 py-3 transition-colors", + isActive + ? "text-primary bg-primary/5" + : "text-foreground hover:bg-accent/40", + )} + > +
); } - -/** One destination tile in the More sheet. */ -function MoreHubTile({ - item, - active, - onNavigate, -}: { - item: NavLink; - active: boolean; - onNavigate: () => void; -}) { - const { t } = useTranslations(); - return ( - -