Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 1x | import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import React from "react";
import { BrowserRouter } from "react-router-dom";
import { ToastContainer } from "@common/components/ui/ToastContainer";
import { AuthProvider, SupabaseProvider } from "@common/contexts";
import { FilterProvider } from "@common/contexts/FilterContext";
import { ToastProvider } from "@common/contexts/ToastContext";
interface AppProvidersProps {
children: React.ReactNode;
queryClient?: QueryClient;
enableDevtools?: boolean;
toastPosition?:
| "top-right"
| "top-left"
| "top-center"
| "bottom-right"
| "bottom-left"
| "bottom-center";
maxToasts?: number;
}
// Create a default query client if none is provided
const createDefaultQueryClient = () =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 30, // 30 minutes (formerly cacheTime)
retry: (failureCount, error: any) => {
// Don't retry on 4xx errors except 408, 429
if (error?.status >= 400 && error?.status < 500) {
return error?.status === 408 || error?.status === 429
? failureCount < 2
: false;
}
// Retry on network errors and 5xx errors
return failureCount < 3;
},
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
},
mutations: {
retry: (failureCount, error: any) => {
// Don't retry mutations on 4xx errors
if (error?.status >= 400 && error?.status < 500) {
return false;
}
return failureCount < 2;
},
},
},
});
export const AppProviders: React.FC<AppProvidersProps> = ({
children,
queryClient,
enableDevtools = process.env.NODE_ENV === "development",
toastPosition = "top-right",
maxToasts = 5,
}) => {
const client = queryClient || createDefaultQueryClient();
return (
<BrowserRouter>
<QueryClientProvider client={client}>
<SupabaseProvider>
<AuthProvider>
<ToastProvider defaultDuration={5000} maxToasts={maxToasts}>
<FilterProvider>
{children}
{import.meta.env.MODE !== 'production' && (
<ToastContainer
position={toastPosition}
maxToasts={maxToasts}
/>
)}
</FilterProvider>
</ToastProvider>
</AuthProvider>
</SupabaseProvider>
{enableDevtools && <ReactQueryDevtools initialIsOpen={false} />}
</QueryClientProvider>
</BrowserRouter>
);
};
// Hook to check if we're inside the providers
export const useAppProviders = () => {
return {
isInsideProviders: true, // We can expand this if needed
};
};
// Higher-order component for wrapping components with providers
export const withAppProviders = <P extends object>(
Component: React.ComponentType<P>,
providerOptions?: Omit<AppProvidersProps, "children">,
) => {
const WrappedComponent = (props: P) => (
<AppProviders {...providerOptions}>
<Component {...props} />
</AppProviders>
);
WrappedComponent.displayName = `withAppProviders(${Component.displayName || Component.name})`;
return WrappedComponent;
};
// Test wrapper for unit tests
export const TestProviders: React.FC<{
children: React.ReactNode;
initialFilters?: any;
mockToasts?: boolean;
}> = ({ children, mockToasts = false }) => {
const testQueryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
gcTime: 0,
},
mutations: {
retry: false,
},
},
});
return (
<QueryClientProvider client={testQueryClient}>
<SupabaseProvider>
<AuthProvider>
<ToastProvider defaultDuration={mockToasts ? 0 : 5000}>
<FilterProvider>{children}</FilterProvider>
</ToastProvider>
</AuthProvider>
</SupabaseProvider>
</QueryClientProvider>
);
};
export default AppProviders;
|