'use client' import { useEffect } from 'react' import { updateUserSettingsAction } from '@/actions/user-settings' import { useUserSettingsStore } from '@/stores/user-settings/store' import type { UserSettings } from '@/lib/user-settings' import { buildMigrationPatch, clearLegacyLocalStorage, } from '@/lib/user-settings-migration' interface Props { initial: UserSettings isDemo: boolean } /** * PBI-76: hydrates the user-settings Zustand store with server-rendered prefs * and opens an SSE subscription so other tabs/devices of the same user * immediately see changes. Demo accounts skip the SSE subscription — their * settings live only in-memory. */ export function UserSettingsBridge({ initial, isDemo }: Props) { const hydrate = useUserSettingsStore((s) => s.hydrate) const applyServerPatch = useUserSettingsStore((s) => s.applyServerPatch) useEffect(() => { hydrate(initial, isDemo) }, [hydrate, initial, isDemo]) // One-shot migration: read legacy localStorage prefs, push to server, clear. // Idempotent via marker; demo accounts skip (no server-write). useEffect(() => { if (isDemo) return const result = buildMigrationPatch() if (!result.hasData) { clearLegacyLocalStorage([]) return } let cancelled = false void (async () => { const res = await updateUserSettingsAction(result.patch) if (cancelled) return if ('success' in res && res.success) { applyServerPatch(result.patch) clearLegacyLocalStorage(result.legacyKeys) } })() return () => { cancelled = true } }, [isDemo, applyServerPatch]) useEffect(() => { if (isDemo) return const es = new EventSource('/api/realtime/user-settings') es.onmessage = (e) => { try { const patch = JSON.parse(e.data) as Partial applyServerPatch(patch) } catch { // ignore malformed event } } return () => es.close() }, [applyServerPatch, isDemo]) return null }