SPB Git

spb/toit-ka Public

Toit-Ka — louer ou acheter un toit au Québec, un seul endroit (fusion Lou-Ka × Immo-Ka) — www.toit-ka.com

Python 40.2% TypeScript 39% CSS 20.2% HTML 0.7%
2.7 KB · 83 lines tsx
Raw Blame History
1// -----------------------------------------------------------------------------2// Author: Simon-Pierre Boucher3// Contact: contact@spboucher.ai4// Project: Toit-Ka5// account.tsx : contexte de compte partagé — profil connecté + favoris ♥6//   Un seul fetch au montage ; les favoris vivent au HUB Groupe KA (magasin7//   central « Mon univers Ka ») : toggle optimiste, poussé au serveur qui8//   relaie au hub. Non connecté -> clic ♥ redirige vers la connexion KA ID.9// -----------------------------------------------------------------------------10import {11  ReactNode, createContext, useCallback, useContext, useEffect, useState,12} from "react";13import {14  Listing, User, favItemFromListing, fetchFavorites, fetchMe, toggleFavorite,15} from "./api";1617interface AccountState {18  user: User | null;19  enabled: boolean;20  loaded: boolean;21  favs: Set<string>;22  toggleFav: (l: Listing) => void;23  refresh: () => void;24}2526const Ctx = createContext<AccountState>({27  user: null, enabled: false, loaded: false, favs: new Set(),28  toggleFav: () => {}, refresh: () => {},29});3031export const useAccount = () => useContext(Ctx);3233/** Redirige vers la connexion KA ID, avec retour sur la page courante. */34export function kaLogin() {35  const next = window.location.pathname + window.location.search;36  window.location.href = `/api/auth/ka/login?next=${encodeURIComponent(next)}`;37}3839export function AccountProvider({ children }: { children: ReactNode }) {40  const [user, setUser] = useState<User | null>(null);41  const [enabled, setEnabled] = useState(false);42  const [loaded, setLoaded] = useState(false);43  const [favs, setFavs] = useState<Set<string>>(new Set());4445  const refresh = useCallback(() => {46    fetchMe()47      .then((r) => {48        setUser(r.user);49        setEnabled(r.enabled !== false);50        setLoaded(true);51        if (r.user && r.user.ka_id) {52          fetchFavorites()53            .then((f) => setFavs(new Set(f.ids)))54            .catch(() => setFavs(new Set()));55        } else {56          setFavs(new Set());57        }58      })59      .catch(() => { setUser(null); setLoaded(true); });60  }, []);6162  useEffect(() => { refresh(); }, [refresh]);6364  const toggleFav = useCallback((l: Listing) => {65    if (!user || !user.ka_id) { kaLogin(); return; }66    setFavs((prev) => {67      const next = new Set(prev);68      const on = !next.has(l.uid);69      if (on) next.add(l.uid); else next.delete(l.uid);70      toggleFavorite(on, favItemFromListing(l)).catch((e) => {71        if (String(e).includes("401")) kaLogin();72      });73      return next;74    });75  }, [user]);7677  return (78    <Ctx.Provider value={{ user, enabled, loaded, favs, toggleFav, refresh }}>79      {children}80    </Ctx.Provider>81  );82}83