import { createContext, useContext, useCallback, useState } from "react"; import type { ReactNode } from "react"; import { pb } from "@/lib/pocketbase"; import type { AuthRecord } from "pocketbase"; import { useNavigate } from "@tanstack/react-router"; /** * Represents the shape of the authenticated user object from PocketBase. */ /** * Context value for authentication state and actions. */ export interface AuthContextValue { user: AuthRecord | null; isLoading: boolean; login: (email: string, password: string) => Promise; signup: ( email: string, password: string, passwordConfirm: string, ) => Promise; logout: () => Promise; } const AuthContext = createContext(undefined); /** * Provider for authentication context. */ export function AuthProvider({ children }: { children: ReactNode }) { const [isLoading, setIsLoading] = useState(false); const [user, setUser] = useState(pb.authStore.record); const navigate = useNavigate(); function updateUser() { if (pb.authStore.isValid) { setUser(pb.authStore.record); } setIsLoading(false); } const login = useCallback(async (email: string, password: string) => { console.log("login"); setIsLoading(true); await pb.collection("users").authWithPassword(email, password); updateUser(); navigate({ to: "/campaigns" }); }, []); const signup = useCallback( async (email: string, password: string, passwordConfirm: string) => { console.log("signup"); setIsLoading(true); await pb.collection("users").create({ email, password, passwordConfirm }); await pb.collection("users").authWithPassword(email, password); updateUser(); navigate({ to: "/campaigns" }); }, [], ); const logout = useCallback(async () => { console.log("logout"); pb.authStore.clear(); setUser(null); navigate({ to: "/" }); }, []); return ( {children} ); } /** * Hook to access authentication context. * Throws if used outside of AuthProvider. */ export function useAuth(): AuthContextValue { const ctx = useContext(AuthContext); if (!ctx) throw new Error("useAuth must be used within an AuthProvider"); return ctx; }