NLP-IBM-Debater / src /app /hooks /useApi.ts
Yassine Mhirsi
fixed typescript adn added logout
2251e03
raw
history blame
1.55 kB
import { useState, useEffect } from 'react';
import api from '../services/api-wrapper.ts';
import type { ApiError } from '../types/api.types';
type UseApiState<T> = {
data: T | null;
loading: boolean;
error: ApiError | null;
};
type UseApiOptions = {
immediate?: boolean; // Whether to fetch immediately on mount
};
/**
* Custom hook for making API calls with loading and error states
*
* @example
* const { data, loading, error, execute } = useApi<User[]>('/api/users');
*
* // Or with manual trigger
* const { data, loading, error, execute } = useApi<User[]>('/api/users', { immediate: false });
* execute(); // Call manually
*/
export function useApi<T>(
url: string,
options: UseApiOptions = { immediate: true }
): UseApiState<T> & { execute: () => Promise<void>; refetch: () => Promise<void> } {
const [state, setState] = useState({
data: null,
loading: options.immediate ?? true,
error: null,
} as UseApiState<T>);
const execute = async () => {
setState((prev) => ({ ...prev, loading: true, error: null }));
try {
const data = await api.get<T>(url);
setState({ data, loading: false, error: null });
} catch (err) {
setState({
data: null,
loading: false,
error: err as ApiError,
});
}
};
useEffect(() => {
if (options.immediate !== false) {
execute();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [url]);
return {
...state,
execute,
refetch: execute,
};
}
export default useApi;