Hint
Separate state logic from context provision — custom hook for consumers, provider component for setup
// ─── auth-context.tsx ───────────────────────────────────────────────────────
type AuthContextValue = {
user: User | null;
login: (credentials: Credentials) => Promise;
logout: () => void;
};
const AuthContext = createContext(null);
// Provider encapsulates all auth logic
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState(null);
const login = useCallback(async (creds) => {
const user = await api.login(creds);
setUser(user);
}, []);
const logout = useCallback(() => {
api.logout();
setUser(null);
}, []);
return (
{children}
);
}
// Custom hook — type-safe, error if used outside provider
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be used within AuthProvider');
return ctx;
}
// ─── app layout ──────────────────────────────────────────────────────────────