// User profile — name, email, title, bio, signature, default agent. // Persisted in localStorage; reactive across tabs. import { useEffect, useSyncExternalStore } from "react" export type Profile = { name: string email: string title: string bio: string signature: string avatarUrl: string defaultAgentId: string } export const DEFAULT_PROFILE: Profile = { name: "Signed-in user", email: "user@example.com", title: "", bio: "", signature: "", avatarUrl: "", defaultAgentId: "", } const STORAGE_KEY = "crema.profile" const CHANGE_EVENT = "crema:profile-change" function readFromStorage(): Profile { if (typeof window === "undefined") return DEFAULT_PROFILE try { const raw = localStorage.getItem(STORAGE_KEY) if (!raw) return DEFAULT_PROFILE const parsed = JSON.parse(raw) as Partial return { name: typeof parsed.name === "string" && parsed.name.trim().length > 0 ? parsed.name : DEFAULT_PROFILE.name, email: typeof parsed.email === "string" ? parsed.email : DEFAULT_PROFILE.email, title: typeof parsed.title === "string" ? parsed.title : DEFAULT_PROFILE.title, bio: typeof parsed.bio === "string" ? parsed.bio : DEFAULT_PROFILE.bio, signature: typeof parsed.signature === "string" ? parsed.signature : DEFAULT_PROFILE.signature, avatarUrl: typeof parsed.avatarUrl === "string" ? parsed.avatarUrl : DEFAULT_PROFILE.avatarUrl, defaultAgentId: typeof parsed.defaultAgentId === "string" ? parsed.defaultAgentId : DEFAULT_PROFILE.defaultAgentId, } } catch { return DEFAULT_PROFILE } } export function loadProfile(): Profile { return readFromStorage() } export function saveProfile(next: Profile) { if (typeof window === "undefined") return localStorage.setItem(STORAGE_KEY, JSON.stringify(next)) window.dispatchEvent(new CustomEvent(CHANGE_EVENT)) } export function resetProfile() { saveProfile(DEFAULT_PROFILE) } export function profileInitials(name: string): string { const words = name.trim().split(/\s+/).filter(Boolean) if (words.length === 0) return "?" if (words.length === 1) return words[0].slice(0, 2).toUpperCase() return (words[0][0] + words[words.length - 1][0]).toUpperCase() } let cached: Profile | null = null function subscribe(cb: () => void): () => void { const onChange = () => { cached = null cb() } window.addEventListener(CHANGE_EVENT, onChange) window.addEventListener("storage", (e) => { if (e.key === STORAGE_KEY) onChange() }) return () => { window.removeEventListener(CHANGE_EVENT, onChange) } } function getSnapshot(): Profile { if (!cached) cached = readFromStorage() return cached } function getServerSnapshot(): Profile { return DEFAULT_PROFILE } export function useProfile(): Profile { const value = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) useEffect(() => { cached = null }, []) return value }