diff --git a/messages/de.json b/messages/de.json index bed6128bc..a1e1232e1 100644 --- a/messages/de.json +++ b/messages/de.json @@ -212,6 +212,7 @@ "themeLight": "Hell", "collapseSidebar": "Einklappen", "userMenu": "Benutzermenü", + "accountSettings": "Kontoeinstellungen", "mood": "Stimmung", "workouts": "Workouts", "skipToContent": "Zum Inhalt springen", @@ -3583,7 +3584,7 @@ "withingsCredentialsSaved": "Zugangsdaten gespeichert", "withingsCredentialsSavedPlaceholder": "Gespeichert — neue eingeben zum Ersetzen", "withingsCredentialsSavedPlaceholderSecret": "Gespeichert — neues eingeben zum Ersetzen", - "withingsSaveCredentials": "Zugangsdaten speichern", + "withingsSaveCredentials": "Speichern", "configured": "Konfiguriert", "withingsSync": "Jetzt synchronisieren", "withingsFullSync": "Alle Daten synchronisieren", @@ -3608,7 +3609,7 @@ "whoopCredentialsSaved": "Zugangsdaten gespeichert", "whoopCredentialsSavedPlaceholder": "Gespeichert — neu eingeben zum Ersetzen", "whoopCredentialsSavedPlaceholderSecret": "Gespeichert — neu eingeben zum Ersetzen", - "whoopSaveCredentials": "Zugangsdaten speichern", + "whoopSaveCredentials": "Speichern", "whoopSync": "Jetzt synchronisieren", "whoopFullSync": "Alle Daten synchronisieren", "whoopFullSyncTitle": "Vollständige Synchronisierung?", @@ -3635,7 +3636,7 @@ "fitbitCredentialsSaved": "Zugangsdaten gespeichert", "fitbitCredentialsSavedPlaceholder": "Gespeichert — neu eingeben zum Ersetzen", "fitbitCredentialsSavedPlaceholderSecret": "Gespeichert — neu eingeben zum Ersetzen", - "fitbitSaveCredentials": "Zugangsdaten speichern", + "fitbitSaveCredentials": "Speichern", "fitbitSync": "Jetzt synchronisieren", "fitbitFullSync": "Alle Daten synchronisieren", "fitbitFullSyncTitle": "Vollständige Synchronisierung?", diff --git a/messages/en.json b/messages/en.json index d9d9a08ba..862cc9cc6 100644 --- a/messages/en.json +++ b/messages/en.json @@ -212,6 +212,7 @@ "themeLight": "Light", "collapseSidebar": "Collapse", "userMenu": "User menu", + "accountSettings": "Account settings", "mood": "Mood", "workouts": "Workouts", "skipToContent": "Skip to content", @@ -3583,7 +3584,7 @@ "withingsCredentialsSaved": "Credentials saved", "withingsCredentialsSavedPlaceholder": "Saved — enter new to replace", "withingsCredentialsSavedPlaceholderSecret": "Saved — enter new to replace", - "withingsSaveCredentials": "Save credentials", + "withingsSaveCredentials": "Save", "configured": "Configured", "withingsSync": "Sync now", "withingsFullSync": "Sync all data", @@ -3608,7 +3609,7 @@ "whoopCredentialsSaved": "Credentials saved", "whoopCredentialsSavedPlaceholder": "Saved — enter new to replace", "whoopCredentialsSavedPlaceholderSecret": "Saved — enter new to replace", - "whoopSaveCredentials": "Save credentials", + "whoopSaveCredentials": "Save", "whoopSync": "Sync now", "whoopFullSync": "Sync all data", "whoopFullSyncTitle": "Full synchronization?", @@ -3635,7 +3636,7 @@ "fitbitCredentialsSaved": "Credentials saved", "fitbitCredentialsSavedPlaceholder": "Saved — enter new to replace", "fitbitCredentialsSavedPlaceholderSecret": "Saved — enter new to replace", - "fitbitSaveCredentials": "Save credentials", + "fitbitSaveCredentials": "Save", "fitbitSync": "Sync now", "fitbitFullSync": "Sync all data", "fitbitFullSyncTitle": "Full synchronization?", diff --git a/messages/es.json b/messages/es.json index 2629b9c90..72aef43b0 100644 --- a/messages/es.json +++ b/messages/es.json @@ -212,6 +212,7 @@ "themeLight": "Claro", "collapseSidebar": "Contraer", "userMenu": "Menú de usuario", + "accountSettings": "Ajustes de cuenta", "mood": "Estado de ánimo", "workouts": "Entrenamientos", "skipToContent": "Saltar al contenido", @@ -3583,7 +3584,7 @@ "withingsCredentialsSaved": "Credenciales guardadas", "withingsCredentialsSavedPlaceholder": "Guardado — introduce uno nuevo para reemplazarlo", "withingsCredentialsSavedPlaceholderSecret": "Guardado — introduce uno nuevo para reemplazarlo", - "withingsSaveCredentials": "Guardar credenciales", + "withingsSaveCredentials": "Guardar", "configured": "Configurado", "withingsSync": "Sincronizar ahora", "withingsFullSync": "Sincronizar todos los datos", @@ -3608,7 +3609,7 @@ "whoopCredentialsSaved": "Credenciales guardadas", "whoopCredentialsSavedPlaceholder": "Guardado — introduce nuevas para reemplazar", "whoopCredentialsSavedPlaceholderSecret": "Guardado — introduce nuevas para reemplazar", - "whoopSaveCredentials": "Guardar credenciales", + "whoopSaveCredentials": "Guardar", "whoopSync": "Sincronizar ahora", "whoopFullSync": "Sincronizar todos los datos", "whoopFullSyncTitle": "¿Sincronización completa?", @@ -3635,7 +3636,7 @@ "fitbitCredentialsSaved": "Credenciales guardadas", "fitbitCredentialsSavedPlaceholder": "Guardado: introduce nuevas para reemplazar", "fitbitCredentialsSavedPlaceholderSecret": "Guardado: introduce nuevas para reemplazar", - "fitbitSaveCredentials": "Guardar credenciales", + "fitbitSaveCredentials": "Guardar", "fitbitSync": "Sincronizar ahora", "fitbitFullSync": "Sincronizar todos los datos", "fitbitFullSyncTitle": "¿Sincronización completa?", diff --git a/messages/fr.json b/messages/fr.json index f352bd636..0f58f7f5f 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -212,6 +212,7 @@ "themeLight": "Clair", "collapseSidebar": "Réduire", "userMenu": "Menu utilisateur", + "accountSettings": "Paramètres du compte", "mood": "Humeur", "workouts": "Entraînements", "skipToContent": "Aller au contenu", @@ -3583,7 +3584,7 @@ "withingsCredentialsSaved": "Identifiants enregistrés", "withingsCredentialsSavedPlaceholder": "Enregistré — saisissez-en un nouveau pour remplacer", "withingsCredentialsSavedPlaceholderSecret": "Enregistré — saisissez-en un nouveau pour remplacer", - "withingsSaveCredentials": "Enregistrer les identifiants", + "withingsSaveCredentials": "Enregistrer", "configured": "Configuré", "withingsSync": "Synchroniser maintenant", "withingsFullSync": "Synchroniser toutes les données", @@ -3608,7 +3609,7 @@ "whoopCredentialsSaved": "Identifiants enregistrés", "whoopCredentialsSavedPlaceholder": "Enregistré — saisir de nouveaux pour remplacer", "whoopCredentialsSavedPlaceholderSecret": "Enregistré — saisir de nouveaux pour remplacer", - "whoopSaveCredentials": "Enregistrer les identifiants", + "whoopSaveCredentials": "Enregistrer", "whoopSync": "Synchroniser", "whoopFullSync": "Synchroniser toutes les données", "whoopFullSyncTitle": "Synchronisation complète ?", @@ -3635,7 +3636,7 @@ "fitbitCredentialsSaved": "Identifiants enregistrés", "fitbitCredentialsSavedPlaceholder": "Enregistré — saisissez-en de nouveaux pour remplacer", "fitbitCredentialsSavedPlaceholderSecret": "Enregistré — saisissez-en de nouveaux pour remplacer", - "fitbitSaveCredentials": "Enregistrer les identifiants", + "fitbitSaveCredentials": "Enregistrer", "fitbitSync": "Synchroniser maintenant", "fitbitFullSync": "Tout synchroniser", "fitbitFullSyncTitle": "Synchronisation complète ?", diff --git a/messages/it.json b/messages/it.json index a9325f736..e252fde9e 100644 --- a/messages/it.json +++ b/messages/it.json @@ -212,6 +212,7 @@ "themeLight": "Chiaro", "collapseSidebar": "Riduci", "userMenu": "Menu utente", + "accountSettings": "Impostazioni account", "mood": "Umore", "workouts": "Allenamenti", "skipToContent": "Vai al contenuto", @@ -3583,7 +3584,7 @@ "withingsCredentialsSaved": "Credenziali salvate", "withingsCredentialsSavedPlaceholder": "Salvato — inseriscine uno nuovo per sostituirlo", "withingsCredentialsSavedPlaceholderSecret": "Salvato — inseriscine uno nuovo per sostituirlo", - "withingsSaveCredentials": "Salva credenziali", + "withingsSaveCredentials": "Salva", "configured": "Configurato", "withingsSync": "Sincronizza ora", "withingsFullSync": "Sincronizza tutti i dati", @@ -3608,7 +3609,7 @@ "whoopCredentialsSaved": "Credenziali salvate", "whoopCredentialsSavedPlaceholder": "Salvato — inserisci nuove per sostituire", "whoopCredentialsSavedPlaceholderSecret": "Salvato — inserisci nuove per sostituire", - "whoopSaveCredentials": "Salva credenziali", + "whoopSaveCredentials": "Salva", "whoopSync": "Sincronizza ora", "whoopFullSync": "Sincronizza tutti i dati", "whoopFullSyncTitle": "Sincronizzazione completa?", @@ -3635,7 +3636,7 @@ "fitbitCredentialsSaved": "Credenziali salvate", "fitbitCredentialsSavedPlaceholder": "Salvato — inserisci nuove per sostituire", "fitbitCredentialsSavedPlaceholderSecret": "Salvato — inserisci nuove per sostituire", - "fitbitSaveCredentials": "Salva credenziali", + "fitbitSaveCredentials": "Salva", "fitbitSync": "Sincronizza ora", "fitbitFullSync": "Sincronizza tutti i dati", "fitbitFullSyncTitle": "Sincronizzazione completa?", diff --git a/messages/pl.json b/messages/pl.json index 1e6fe6c4a..645e40fd7 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -212,6 +212,7 @@ "themeLight": "Jasny", "collapseSidebar": "Zwiń", "userMenu": "Menu użytkownika", + "accountSettings": "Ustawienia konta", "mood": "Nastrój", "workouts": "Treningi", "skipToContent": "Przejdź do treści", @@ -3583,7 +3584,7 @@ "withingsCredentialsSaved": "Dane logowania zapisane", "withingsCredentialsSavedPlaceholder": "Zapisano — wprowadź nowy, aby zastąpić", "withingsCredentialsSavedPlaceholderSecret": "Zapisano — wprowadź nowy, aby zastąpić", - "withingsSaveCredentials": "Zapisz dane logowania", + "withingsSaveCredentials": "Zapisz", "configured": "Skonfigurowano", "withingsSync": "Synchronizuj teraz", "withingsFullSync": "Synchronizuj wszystkie dane", @@ -3608,7 +3609,7 @@ "whoopCredentialsSaved": "Dane zapisane", "whoopCredentialsSavedPlaceholder": "Zapisano — wpisz nowe, aby zastąpić", "whoopCredentialsSavedPlaceholderSecret": "Zapisano — wpisz nowe, aby zastąpić", - "whoopSaveCredentials": "Zapisz dane", + "whoopSaveCredentials": "Zapisz", "whoopSync": "Synchronizuj teraz", "whoopFullSync": "Synchronizuj wszystkie dane", "whoopFullSyncTitle": "Pełna synchronizacja?", @@ -3635,7 +3636,7 @@ "fitbitCredentialsSaved": "Dane uwierzytelniające zapisane", "fitbitCredentialsSavedPlaceholder": "Zapisano — wpisz nowe, aby zastąpić", "fitbitCredentialsSavedPlaceholderSecret": "Zapisano — wpisz nowe, aby zastąpić", - "fitbitSaveCredentials": "Zapisz dane uwierzytelniające", + "fitbitSaveCredentials": "Zapisz", "fitbitSync": "Synchronizuj teraz", "fitbitFullSync": "Synchronizuj wszystkie dane", "fitbitFullSyncTitle": "Pełna synchronizacja?", diff --git a/src/components/settings/integrations-section.tsx b/src/components/settings/integrations-section.tsx index 275033c30..afdc9d224 100644 --- a/src/components/settings/integrations-section.tsx +++ b/src/components/settings/integrations-section.tsx @@ -10,7 +10,6 @@ import { Loader2, RefreshCw, Save, - Smile, Unlink, } from "lucide-react"; @@ -42,14 +41,6 @@ import { queryKeys, } from "@/lib/query-keys"; -interface GlobalServiceAvailability { - telegramGlobal: boolean; - ntfyGlobal: boolean; - webPushGlobal: boolean; - apiGlobal: boolean; - moodLogGlobal: boolean; -} - // v1.4.15 Phase B2: shared status payload for both integration cards. // v1.4.19 Phase A5: the redundant in-card status banner is gone — the // IntegrationStatusPill now owns state + last-sync presentation, and @@ -183,23 +174,11 @@ export function IntegrationsSection() { const { t } = useTranslations(); const { isAuthenticated } = useAuth(); - const { data: globalServices } = useQuery({ - queryKey: queryKeys.settingsGlobalServices(), - queryFn: async () => { - const res = await fetch("/api/settings/global-services"); - if (!res.ok) throw new Error("Failed"); - return (await res.json()).data as GlobalServiceAvailability; - }, - enabled: isAuthenticated, - }); - const { data: integrationStatus } = useIntegrationStatuses(isAuthenticated); - const moodLogEnabled = globalServices?.moodLogGlobal ?? true; const withingsViewModel = pickStatus(integrationStatus, "withings"); const whoopViewModel = pickStatus(integrationStatus, "whoop"); const fitbitViewModel = pickStatus(integrationStatus, "fitbit"); - const moodLogViewModel = pickStatus(integrationStatus, "moodlog"); return (
- {moodLogEnabled && }
); } @@ -1545,354 +1523,3 @@ function FitbitCard({ ); } - -function MoodLogCard({ - viewModel, -}: { - viewModel: IntegrationStatusViewModel | undefined; -}) { - const { t } = useTranslations(); - const queryClient = useQueryClient(); - const [url, setUrl] = useState(""); - const [apiKey, setApiKey] = useState(""); - const [saving, setSaving] = useState(false); - const [syncing, setSyncing] = useState(false); - const [msg, setMsg] = useState(null); - const [msgType, setMsgType] = useState<"success" | "error" | null>(null); - - // v1.12.1 — read off the consolidated /api/integrations/status - // envelope; the per-card /api/integrations/moodlog/status round-trip - // is gone. Mutations invalidate the envelope so the card's webhook - // secret / entry-count / last-sync repaint on the next refetch. - const status = viewModel; - const refreshStatus = () => - queryClient.invalidateQueries({ - queryKey: queryKeys.integrationsStatus(), - }); - - async function handleSave(e: React.FormEvent) { - e.preventDefault(); - setSaving(true); - setMsg(null); - const res = await fetch("/api/settings/moodlog", { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ url: url.trim(), apiKey: apiKey.trim() }), - }); - if (res.ok) { - setMsg(t("settings.saved")); - setMsgType("success"); - setUrl(""); - setApiKey(""); - void refreshStatus(); - } else { - const json = await res.json(); - setMsg(json.error || t("settings.savingError")); - setMsgType("error"); - } - setSaving(false); - } - - async function handleSync(fullSync = false) { - setSyncing(true); - setMsg(null); - try { - const res = await fetch("/api/integrations/moodlog/sync", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ fullSync }), - }); - if (res.ok) { - const json = await res.json(); - setMsg( - t("settings.moodLogSyncResult", { count: json.data.imported }), - ); - setMsgType("success"); - void refreshStatus(); - } else { - setMsg(t("settings.moodLogSyncFailed")); - setMsgType("error"); - } - } catch { - setMsg(t("settings.moodLogSyncFailed")); - setMsgType("error"); - } - setSyncing(false); - } - - async function handleDisconnect() { - const res = await fetch("/api/settings/moodlog", { method: "DELETE" }); - if (res.ok) { - setMsg(t("settings.moodLogDisconnected")); - setMsgType("success"); - void refreshStatus(); - } - } - - // Mirror Withings logic: the pill state comes from the cross- - // integration envelope, which also carries `legacyLastSyncedAt` - // (the user's moodLog last-sync timestamp) so a manual sync paints - // a fresh "X min ago" once the envelope refetches. - const pillState: IntegrationPillState = status?.configured - ? pillStateFor(viewModel) - : "disconnected"; - const pillLastSyncAt = - status?.legacyLastSyncedAt ?? viewModel?.lastSuccessAt ?? null; - const errorMessage = - pillState === "error" && viewModel?.lastError ? viewModel.lastError : null; - - return ( -
- - {t("settings.moodLogTitle")} - - } - description={ - <> -

{t("settings.moodLogDescription")}

-

- {t("settings.moodLogDeprecated")} -

- - } - status={ - - } - /> - - {/* v1.4.19 A5 — visual divider matches Withings for consistency - (the maintainer explicitly called the asymmetry out). */} -
- -
- {errorMessage && } - -
-
- - setUrl(e.target.value)} - autoComplete="off" - spellCheck={false} - autoCapitalize="none" - enterKeyHint="next" - /> -
-
- - setApiKey(e.target.value)} - autoComplete="off" - inputMode="text" - spellCheck={false} - autoCapitalize="none" - enterKeyHint="done" - /> -
- {/* v1.4.33 — save-button placement contract: - right-aligned primary `Speichern` with the secondary - `Verbindung testen` immediately to its left. Mood Log - used to left-align its row, which was the only - integration form that did. */} -
- - -
-
- - {status?.configured && ( -
- {status.webhookSecret && ( -
- - {/* v1.4.33 — the webhook secret is a long hex string; - on a 393 CSS px viewport the input + Copy button - used to push past the card edge and trigger a body - horizontal scroll. Stack vertically on ` - - -
-

- {t("settings.moodLogWebhookSecretHelp")} -

-
- )} - - {/* v1.4.19 A5 — The "letzter Sync" line that used to - live here is gone. The pill in the card header - already carries that information; repeating it - inside the body is the redundancy the maintainer flagged. The - entry-count is the only number we still surface - because it's an integration-specific datapoint the - pill cannot convey. */} -
- - {t("settings.moodLogEntries")}: {status.entryCount} - -
- - {/* v1.4.33 — the Sync / Voll-Sync / Trennen triplet - overflowed the card edge on a 393 CSS px viewport - (~376 px of buttons + gaps inside 345 px of inner - width). Match the Withings card pattern: `flex-wrap` - + `min-w-[10rem]` on ` - - - - - - - - - - {t("settings.moodLogFullSyncTitle")} - - - {t("settings.moodLogFullSyncDescription")} - - - - {t("common.cancel")} - handleSync(true)}> - {t("settings.moodLogFullSyncConfirm")} - - - - - - - - {/* v1.4.3: aligned with the Withings disconnect button — - outline + text-destructive instead of solid destructive - so the trigger reads as a reversible action; the actual - "yes, disconnect" confirmation inside the dialog keeps - its solid-red treatment. */} - - - - - - {t("settings.moodLogDisconnectTitle")} - - - {t("settings.moodLogDisconnectDescription")} - - - - {t("common.cancel")} - - {t("settings.moodLogDisconnect")} - - - - -
-
- )} - - {msg && ( -

- {msg} -

- )} - - - ); -}