Backup: 2025-06-07 19:48 - Script test
[Restore from backup: vip-coordinator-backup-2025-06-07-19-48-script-test]
This commit is contained in:
56
frontend/src/hooks/useApi.ts
Normal file
56
frontend/src/hooks/useApi.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
|
||||
// Simple hook for API calls that handles loading, error, and data states
|
||||
export function useApi<T>(
|
||||
apiCall: () => Promise<T>,
|
||||
dependencies: any[] = []
|
||||
) {
|
||||
const [data, setData] = useState<T | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const result = await apiCall();
|
||||
setData(result);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'An error occurred');
|
||||
setData(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, dependencies);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refetch: fetchData };
|
||||
}
|
||||
|
||||
// Hook for mutations (POST, PUT, DELETE)
|
||||
export function useMutation<TData = any, TVariables = any>(
|
||||
mutationFn: (variables: TVariables) => Promise<TData>
|
||||
) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const mutate = useCallback(async (variables: TVariables) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const result = await mutationFn(variables);
|
||||
return result;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'An error occurred';
|
||||
setError(errorMessage);
|
||||
throw err;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [mutationFn]);
|
||||
|
||||
return { mutate, loading, error };
|
||||
}
|
||||
74
frontend/src/hooks/useError.ts
Normal file
74
frontend/src/hooks/useError.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
export interface ApiError {
|
||||
message: string;
|
||||
code?: string;
|
||||
details?: unknown;
|
||||
}
|
||||
|
||||
export const useError = () => {
|
||||
const [error, setError] = useState<ApiError | null>(null);
|
||||
const [isError, setIsError] = useState(false);
|
||||
|
||||
const clearError = useCallback(() => {
|
||||
setError(null);
|
||||
setIsError(false);
|
||||
}, []);
|
||||
|
||||
const handleError = useCallback((error: unknown) => {
|
||||
console.error('API Error:', error);
|
||||
|
||||
let apiError: ApiError;
|
||||
|
||||
if (error instanceof Error) {
|
||||
// Check if it's our custom ApiError
|
||||
if ('status' in error && 'code' in error) {
|
||||
apiError = {
|
||||
message: error.message,
|
||||
code: (error as any).code,
|
||||
details: (error as any).details
|
||||
};
|
||||
} else {
|
||||
// Regular Error
|
||||
apiError = {
|
||||
message: error.message,
|
||||
code: 'ERROR'
|
||||
};
|
||||
}
|
||||
} else if (typeof error === 'object' && error !== null) {
|
||||
// Check for axios-like error structure
|
||||
const err = error as any;
|
||||
if (err.response?.data?.error) {
|
||||
apiError = {
|
||||
message: err.response.data.error.message || err.response.data.error,
|
||||
code: err.response.data.error.code,
|
||||
details: err.response.data.error.details
|
||||
};
|
||||
} else {
|
||||
apiError = {
|
||||
message: 'An unexpected error occurred',
|
||||
code: 'UNKNOWN_ERROR',
|
||||
details: error
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Unknown error type
|
||||
apiError = {
|
||||
message: 'An unexpected error occurred',
|
||||
code: 'UNKNOWN_ERROR'
|
||||
};
|
||||
}
|
||||
|
||||
setError(apiError);
|
||||
setIsError(true);
|
||||
|
||||
return apiError;
|
||||
}, []);
|
||||
|
||||
return {
|
||||
error,
|
||||
isError,
|
||||
clearError,
|
||||
handleError
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user