// ----------------------------------------------------------------------------- // Rent-Ka — Rental listings aggregator (Canada, outside Québec) // Author: Simon-Pierre Boucher — contact@spboucher.ai // account.tsx: shared account context — signed-in profile + saved rentals // One fetch at app mount; card hearts, the account menu and the // Favorites/Manage pages read the same state (optimistic toggle). // ----------------------------------------------------------------------------- import { ReactNode, createContext, useCallback, useContext, useEffect, useState, } from "react"; import { Me, addFavorite, fetchFavorites, fetchMe, removeFavorite } from "./api"; interface AccountState { me: Me | null; loaded: boolean; // first fetch done favs: Set; // saved uids toggleFav: (uid: string) => void; refresh: () => void; // re-fetch profile + saved (after login/role) } const Ctx = createContext({ me: null, loaded: false, favs: new Set(), toggleFav: () => {}, refresh: () => {}, }); export const useAccount = () => useContext(Ctx); export function AccountProvider({ children }: { children: ReactNode }) { const [me, setMe] = useState(null); const [loaded, setLoaded] = useState(false); const [favs, setFavs] = useState>(new Set()); const refresh = useCallback(() => { fetchMe().then((m) => { setMe(m); setLoaded(true); if (m) { fetchFavorites() .then((f) => setFavs(new Set(f.uids))) .catch(() => setFavs(new Set())); } else { setFavs(new Set()); } }); }, []); useEffect(() => { refresh(); }, [refresh]); const toggleFav = useCallback((uid: string) => { setFavs((prev) => { const next = new Set(prev); if (next.has(uid)) { next.delete(uid); removeFavorite(uid).catch(() => {}); } else { next.add(uid); addFavorite(uid).catch(() => {}); } return next; }); }, []); return ( {children} ); }