Pre luanch plan phase 1 complete
This commit is contained in:
74
frontend/src/context/PageLoadingContext.tsx
Normal file
74
frontend/src/context/PageLoadingContext.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Page Loading Context - Global page loading state management
|
||||
* Provides a centralized loading indicator for page transitions and data fetching
|
||||
* Pages can use usePageLoading hook to show/hide the global spinner
|
||||
*/
|
||||
import React, { createContext, useContext, useState, useCallback, ReactNode, useRef } from 'react';
|
||||
|
||||
interface PageLoadingContextType {
|
||||
isLoading: boolean;
|
||||
loadingMessage: string | null;
|
||||
setLoading: (loading: boolean, message?: string) => void;
|
||||
startLoading: (message?: string) => void;
|
||||
stopLoading: () => void;
|
||||
}
|
||||
|
||||
const PageLoadingContext = createContext<PageLoadingContextType | undefined>(undefined);
|
||||
|
||||
export function PageLoadingProvider({ children }: { children: ReactNode }) {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [loadingMessage, setLoadingMessage] = useState<string | null>(null);
|
||||
const loadingCountRef = useRef(0);
|
||||
|
||||
const setLoading = useCallback((loading: boolean, message?: string) => {
|
||||
if (loading) {
|
||||
loadingCountRef.current++;
|
||||
setIsLoading(true);
|
||||
if (message) setLoadingMessage(message);
|
||||
} else {
|
||||
loadingCountRef.current = Math.max(0, loadingCountRef.current - 1);
|
||||
if (loadingCountRef.current === 0) {
|
||||
setIsLoading(false);
|
||||
setLoadingMessage(null);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const startLoading = useCallback((message?: string) => {
|
||||
setLoading(true, message);
|
||||
}, [setLoading]);
|
||||
|
||||
const stopLoading = useCallback(() => {
|
||||
setLoading(false);
|
||||
}, [setLoading]);
|
||||
|
||||
return (
|
||||
<PageLoadingContext.Provider value={{ isLoading, loadingMessage, setLoading, startLoading, stopLoading }}>
|
||||
{children}
|
||||
</PageLoadingContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePageLoadingContext() {
|
||||
const context = useContext(PageLoadingContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('usePageLoadingContext must be used within a PageLoadingProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for pages to manage loading state
|
||||
* Automatically tracks loading state and provides helper functions
|
||||
*/
|
||||
export function usePageLoading() {
|
||||
const { isLoading, loadingMessage, startLoading, stopLoading, setLoading } = usePageLoadingContext();
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
loadingMessage,
|
||||
startLoading,
|
||||
stopLoading,
|
||||
setLoading,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user