Scrapboard.org client
at main 72 lines 1.8 kB view raw
1"use client"; 2 3import { 4 createContext, 5 useContext, 6 useState, 7 useEffect, 8 ReactNode, 9} from "react"; 10import { AppBskyActorDefs } from "@atproto/api"; 11import { useAuth } from "./hooks/useAuth"; 12 13type Profile = AppBskyActorDefs.ProfileViewDetailed; 14 15type ProfileContextType = { 16 profile: Profile | null; 17 loading: boolean; 18 error: Error | null; 19}; 20 21const ProfileContext = createContext<ProfileContextType | null>(null); 22 23export function ProfileProvider({ children }: { children: ReactNode }) { 24 const { agent, loading: authLoading, session } = useAuth(); 25 const [profile, setProfile] = useState<Profile | null>(null); 26 const [loading, setLoading] = useState(true); 27 const [error, setError] = useState<Error | null>(null); 28 29 useEffect(() => { 30 const fetchProfile = async () => { 31 if (!agent || authLoading || !session?.did) 32 return console.warn( 33 "No agent or session available", 34 !agent, 35 authLoading, 36 session?.did 37 ); 38 39 setLoading(true); 40 setError(null); 41 42 try { 43 const res = await agent.getProfile({ 44 actor: session!.did, 45 }); 46 setProfile(res.data); 47 } catch (err) { 48 setError( 49 err instanceof Error ? err : new Error("Failed to fetch profile") 50 ); 51 setProfile(null); 52 console.error("Error fetching profile:", err); 53 } finally { 54 setLoading(false); 55 } 56 }; 57 58 fetchProfile(); 59 }, [agent, authLoading, session]); 60 61 return ( 62 <ProfileContext.Provider value={{ profile, loading, error }}> 63 {children} 64 </ProfileContext.Provider> 65 ); 66} 67 68export function useProfile() { 69 const ctx = useContext(ProfileContext); 70 if (!ctx) throw new Error("useProfile must be used inside <ProfileProvider>"); 71 return ctx; 72}