+
+ Connect your Garmin account to automatically import new activities and wellness data every hour.
+ Credentials are encrypted at rest.
+
+
+ {garminConfig?.connected && (
+
+
✓ Connected as {garminConfig.email}
+
+ {garminConfig.last_sync_at && (
+
+ Last sync: {new Date(garminConfig.last_sync_at).toLocaleString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })}
+
+ )}
+ {garminConfig.last_sync_status && (
+
+ {garminConfig.last_sync_status}
+
+ )}
+
+
+ )}
+
+
+
+ setGcForm(f => ({ ...f, email: e.target.value }))} />
+
+
+ setGcForm(f => ({ ...f, password: e.target.value }))} />
+
+
+
+ {[
+ ['sync_enabled', 'Enable hourly sync'],
+ ['sync_activities', 'Sync activities (FIT download)'],
+ ['sync_wellness', 'Sync wellness data'],
+ ].map(([key, label]) => (
+
+ ))}
+
+
+
+ {gcError && {gcError}
}
+
+
+ {
+ if (!garminConfig?.connected && !gcForm.password) {
+ setGcError('Password is required for first-time setup')
+ return
+ }
+ const payload = { ...gcForm }
+ if (!payload.password) delete payload.password
+ saveGarmin.mutate(payload)
+ }}
+ loading={saveGarmin.isPending}
+ saved={gcSaved}
+ label={garminConfig?.connected ? 'Update' : 'Connect'}
+ />
+ {garminConfig?.connected && (
+ <>
+
+
+ >
+ )}
+
+
+
{/* PocketID — admin only */}
{user?.is_admin && (