Python 61.6%
TypeScript 20.9%
CSS 11.4%
JavaScript 5.1%
HTML 1.1%
1// -----------------------------------------------------------------------------2// Auto-Ka — Agrégateur de voitures usagées à vendre (province de Québec)3// Auteur : Simon-Pierre Boucher — contact@spboucher.ai4// account.tsx : contexte de compte partagé — profil connecté + favoris.5// Les favoris vivent au HUB Groupe KA (magasin central « Mon univers Ka »,6// groupe-ka.com) : aucun stockage local, chaque ♥ est poussé au hub via7// l'API d'Auto·Ka et la liste est relue du hub. Un seul fetch au montage ;8// le cœur des cartes, la fiche et le menu compte lisent le même état9// (toggle optimiste, re-synchronisé sur erreur). Non connecté : le clic10// sur un ♥ envoie vers la connexion KA ID en gardant la page courante.11// -----------------------------------------------------------------------------12import {13 ReactNode, createContext, useCallback, useContext, useEffect, useState,14} from "react";15import {16 Me, Vehicle, fetchFavorites, fetchMe, toggleFavorite, vehicleFavItem,17} from "./api";1819interface AccountState {20 me: Me | null;21 enabled: boolean; // SSO KA ID configuré côté serveur22 loaded: boolean; // premier fetch terminé23 favs: Set<string>; // uids des véhicules favoris (au hub)24 toggleFav: (v: Vehicle) => void;25 refresh: () => void; // re-fetch profil + favoris26}2728const Ctx = createContext<AccountState>({29 me: null, enabled: false, loaded: false, favs: new Set(),30 toggleFav: () => {}, refresh: () => {},31});3233export const useAccount = () => useContext(Ctx);3435export function AccountProvider({ children }: { children: ReactNode }) {36 const [me, setMe] = useState<Me | null>(null);37 const [enabled, setEnabled] = useState(false);38 const [loaded, setLoaded] = useState(false);39 const [favs, setFavs] = useState<Set<string>>(new Set());4041 const loadFavs = useCallback(() => {42 fetchFavorites()43 .then((f) => setFavs(new Set(f.ids)))44 .catch(() => setFavs(new Set()));45 }, []);4647 const refresh = useCallback(() => {48 fetchMe().then((r) => {49 setMe(r.user);50 setEnabled(r.enabled);51 setLoaded(true);52 if (r.user) loadFavs();53 else setFavs(new Set());54 });55 }, [loadFavs]);5657 useEffect(() => { refresh(); }, [refresh]);5859 const toggleFav = useCallback((v: Vehicle) => {60 if (!me) {61 // pas de session : connexion KA ID puis retour sur la page courante62 const next = encodeURIComponent(63 window.location.pathname + window.location.search);64 window.location.href = `/api/auth/ka/login?next=${next}`;65 return;66 }67 setFavs((prev) => {68 const next = new Set(prev);69 const on = !next.has(v.uid);70 if (on) next.add(v.uid);71 else next.delete(v.uid);72 // pousse au hub (magasin central) ; en cas d'échec on se re-synchronise73 toggleFavorite(on, vehicleFavItem(v)).catch(loadFavs);74 return next;75 });76 }, [me, loadFavs]);7778 return (79 <Ctx.Provider value={{ me, enabled, loaded, favs, toggleFav, refresh }}>80 {children}81 </Ctx.Provider>82 );83}84