feat(onboarding): surface AI-provider setup on the done step

AI Insights, Coach and the daily briefing are default-ON but need a BYOK
or local provider that onboarding never mentioned, so a fresh user met
the flagship feature as a cold error. Add an optional, skippable card to
the onboarding done step that explains what the AI does (plain-language
summaries of your readings, data stays with you) and deep-links to
Settings -> AI. Adds onboarding.done.aiTitle/aiBody/aiCta across all six
locales.
This commit is contained in:
Marc-André Bombeck committed 2026-06-18 19:09:12 +02:00
1 parent 3d213d1fbf
commit cd816607e4
7 files changed
+58 -7

No files matched your search

+4 -1
View File
@@ -3626,7 +3626,10 @@
"learning": "Manche Einblicke – Glukose, Schlafrhythmus, Blutdrucktrends, Zyklus – schärfen sich in den ersten ein bis zwei Wochen, sobald sich deine Daten ansammeln. Leere Kacheln heißen jetzt nur, dass wir deine Basislinie noch lernen.",
"connectCta": "Gerät verbinden",
"logCta": "Ersten Wert eintragen",
"importCta": "Bestehende Daten importieren"
"importCta": "Bestehende Daten importieren",
"aiTitle": "KI-Einblicke aktivieren (optional)",
"aiBody": "Coach, Tagesbriefing und Einschätzungen fassen deine Werte in Klartext zusammen. Dafür verbindest du deinen eigenen KI-Schlüssel (OpenAI, Anthropic) oder ein lokales Modell — deine Daten bleiben bei dir.",
"aiCta": "KI-Anbieter verbinden"
},
"welcomeBack": {
"title": "Willkommen zurück",
+4 -1
View File
@@ -3626,7 +3626,10 @@
"learning": "Some insights — glucose, sleep rhythm, blood-pressure trends, cycle — sharpen over the first week or two as your data builds up. Empty tiles now just mean we're still learning your baseline.",
"connectCta": "Connect a device",
"logCta": "Log your first measurement",
"importCta": "Import existing history"
"importCta": "Import existing history",
"aiTitle": "Turn on AI Insights (optional)",
"aiBody": "Coach, the daily briefing and assessments turn your readings into plain language. For that you connect your own AI key (OpenAI, Anthropic) or a local model — your data stays with you.",
"aiCta": "Connect an AI provider"
},
"welcomeBack": {
"title": "Welcome back",
+4 -1
View File
@@ -3626,7 +3626,10 @@
"learning": "Algunas conclusiones —glucosa, ritmo de sueño, tendencias de presión arterial, ciclo— se afinan durante la primera semana o dos a medida que se acumulan tus datos. Las casillas vacías ahora solo significan que aún estamos aprendiendo tu línea base.",
"connectCta": "Conectar un dispositivo",
"logCta": "Registra tu primera medición",
"importCta": "Importar historial existente"
"importCta": "Importar historial existente",
"aiTitle": "Activar Insights con IA (opcional)",
"aiBody": "El coach, el briefing diario y las valoraciones convierten tus lecturas en lenguaje claro. Para ello conectas tu propia clave de IA (OpenAI, Anthropic) o un modelo local: tus datos siguen siendo tuyos.",
"aiCta": "Conectar un proveedor de IA"
},
"welcomeBack": {
"title": "Bienvenido de nuevo",
+4 -1
View File
@@ -3626,7 +3626,10 @@
"learning": "Certaines analyses — glycémie, rythme de sommeil, tendances de tension, cycle — s'affinent au cours de la première semaine ou deux à mesure que vos données s'accumulent. Des tuiles vides signifient simplement que nous apprenons encore votre référence.",
"connectCta": "Connecter un appareil",
"logCta": "Enregistrez votre première mesure",
"importCta": "Importer un historique existant"
"importCta": "Importer un historique existant",
"aiTitle": "Activer les Insights IA (facultatif)",
"aiBody": "Le coach, le briefing quotidien et les évaluations traduisent tes mesures en langage clair. Pour cela, connecte ta propre clé IA (OpenAI, Anthropic) ou un modèle local — tes données restent chez toi.",
"aiCta": "Connecter un fournisseur d'IA"
},
"welcomeBack": {
"title": "Bon retour",
+4 -1
View File
@@ -3626,7 +3626,10 @@
"learning": "Alcune analisi — glicemia, ritmo del sonno, tendenze della pressione, ciclo — si affinano nella prima settimana o due man mano che i tuoi dati si accumulano. Le caselle vuote ora indicano solo che stiamo ancora imparando il tuo riferimento.",
"connectCta": "Collega un dispositivo",
"logCta": "Registra la tua prima misurazione",
"importCta": "Importa la cronologia esistente"
"importCta": "Importa la cronologia esistente",
"aiTitle": "Attiva gli Insight IA (facoltativo)",
"aiBody": "Il coach, il briefing giornaliero e le valutazioni trasformano le tue misurazioni in linguaggio chiaro. Per farlo colleghi la tua chiave IA (OpenAI, Anthropic) o un modello locale: i tuoi dati restano tuoi.",
"aiCta": "Collega un provider IA"
},
"welcomeBack": {
"title": "Bentornato",
+4 -1
View File
@@ -3626,7 +3626,10 @@
"learning": "Niektóre wnioski — glukoza, rytm snu, trendy ciśnienia, cykl — wyostrzają się w ciągu pierwszego tygodnia lub dwóch, w miarę gromadzenia danych. Puste kafelki oznaczają teraz tylko, że wciąż poznajemy Twój punkt odniesienia.",
"connectCta": "Połącz urządzenie",
"logCta": "Zapisz pierwszy pomiar",
"importCta": "Importuj istniejącą historię"
"importCta": "Importuj istniejącą historię",
"aiTitle": "Włącz Insighty AI (opcjonalnie)",
"aiBody": "Coach, codzienny briefing i oceny zamieniają Twoje pomiary w prosty język. W tym celu łączysz własny klucz AI (OpenAI, Anthropic) lub model lokalny — Twoje dane pozostają u Ciebie.",
"aiCta": "Połącz dostawcę AI"
},
"welcomeBack": {
"title": "Witaj ponownie",
+34 -1
View File
@@ -1,7 +1,13 @@
"use client";
import Link from "next/link";
import { CheckCircle2, FileUp, PlusCircle, Plug } from "lucide-react";
import {
CheckCircle2,
FileUp,
PlusCircle,
Plug,
Sparkles,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { useTranslations } from "@/lib/i18n/context";
@@ -51,6 +57,33 @@ export function DoneScreen() {
</p>
</header>
{/* v1.18.6 — surface the AI Insights / Coach / briefing setup at
the highest-intent moment. The flagship feature needs a BYOK or
local provider that the rest of onboarding never mentions, so a
fresh user otherwise discovers it as a cold error. This card is
skippable by construction — it is an optional deep-link, not a
gate. */}
<div className="border-border/60 bg-muted/30 mx-auto flex w-full max-w-md flex-col items-center gap-2 rounded-lg border p-4 text-center">
<span
aria-hidden="true"
className="from-dracula-purple to-dracula-pink flex size-9 items-center justify-center rounded-full bg-gradient-to-br"
>
<Sparkles className="text-background size-4" />
</span>
<p className="text-foreground text-sm font-medium">
{t("onboarding.done.aiTitle")}
</p>
<p className="text-muted-foreground text-sm leading-relaxed">
{t("onboarding.done.aiBody")}
</p>
<Link
href="/settings/ai"
className="text-primary text-sm font-medium underline-offset-4 hover:underline"
>
{t("onboarding.done.aiCta")}
</Link>
</div>
<div className="flex w-full max-w-xs flex-col gap-2">
<Button asChild size="lg">
<Link