51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
import { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
|
|
import { apiFetch } from '../lib/api';
|
|
|
|
export interface User {
|
|
id: string;
|
|
email: string | null;
|
|
nickname: string;
|
|
subscriptionLevel?: number;
|
|
}
|
|
|
|
interface AuthContextValue {
|
|
user: User | null;
|
|
loading: boolean;
|
|
setUser: (u: User | null) => void;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextValue | null>(null);
|
|
|
|
interface MeResponse {
|
|
success: boolean;
|
|
data: { user: User };
|
|
}
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
const [user, setUser] = useState<User | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
|
|
apiFetch<MeResponse>('/auth/me')
|
|
.then((res) => { if (!cancelled) setUser(res.data.user); })
|
|
.catch(() => { if (!cancelled) setUser(null); })
|
|
.finally(() => { if (!cancelled) setLoading(false); });
|
|
|
|
return () => { cancelled = true; };
|
|
}, []);
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ user, loading, setUser }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useAuthContext(): AuthContextValue {
|
|
const ctx = useContext(AuthContext);
|
|
if (!ctx) throw new Error('useAuthContext must be used inside AuthProvider');
|
|
return ctx;
|
|
}
|