63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { useApi } from '@/hooks/useApi';
|
|
import { fetchProfile } from '../api/settingsApi';
|
|
import { useCallback, useRef, useMemo, type ReactNode } from 'react';
|
|
import { ProfileContext } from '../contexts/ProfileContext';
|
|
import type { GetProfileApiResponse } from '../types/settingsApiType';
|
|
|
|
export const ProfileProvider = ({ children }: { children: ReactNode }) => {
|
|
const profileCache = useRef<GetProfileApiResponse | null>(null);
|
|
const pendingRequestRef = useRef<Promise<
|
|
GetProfileApiResponse | undefined
|
|
> | null>(null);
|
|
|
|
const { loading: isLoadingProfile, execute } = useApi(fetchProfile);
|
|
|
|
const refetchProfile = useCallback(
|
|
async (options?: {
|
|
force?: boolean;
|
|
}): Promise<GetProfileApiResponse | undefined> => {
|
|
// If forcing a refetch, clear the cache first
|
|
if (options?.force) {
|
|
profileCache.current = null;
|
|
}
|
|
|
|
// Return cached data if it exists
|
|
if (profileCache.current) {
|
|
return profileCache.current;
|
|
}
|
|
|
|
if (pendingRequestRef.current) {
|
|
return pendingRequestRef.current;
|
|
}
|
|
|
|
// If no request is pending, start a new one and store its promise
|
|
try {
|
|
pendingRequestRef.current = execute();
|
|
const result = await pendingRequestRef.current;
|
|
|
|
// Update cache on success
|
|
if (result?.success) {
|
|
profileCache.current = result;
|
|
}
|
|
return result;
|
|
} finally {
|
|
// Clear the pending request ref once the request is complete
|
|
pendingRequestRef.current = null;
|
|
}
|
|
},
|
|
[execute],
|
|
);
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
isLoadingProfile,
|
|
refetchProfile,
|
|
}),
|
|
[isLoadingProfile, refetchProfile],
|
|
);
|
|
|
|
return (
|
|
<ProfileContext.Provider value={value}>{children}</ProfileContext.Provider>
|
|
);
|
|
};
|