main.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { StrictMode } from 'react'
  2. import ReactDOM from 'react-dom/client'
  3. import { AxiosError } from 'axios'
  4. import {
  5. QueryCache,
  6. QueryClient,
  7. QueryClientProvider,
  8. } from '@tanstack/react-query'
  9. import { RouterProvider, createRouter } from '@tanstack/react-router'
  10. import { toast } from 'sonner'
  11. import { useAuthStore } from '@/stores/authStore'
  12. import { handleServerError } from '@/utils/handle-server-error'
  13. import { DirectionProvider } from './context/direction-context'
  14. import { FontProvider } from './context/font-context'
  15. import { ThemeProvider } from './context/theme-context'
  16. import './index.css'
  17. // Generated Routes
  18. import { routeTree } from './routeTree.gen'
  19. const queryClient = new QueryClient({
  20. defaultOptions: {
  21. queries: {
  22. retry: (failureCount, error) => {
  23. // eslint-disable-next-line no-console
  24. if (import.meta.env.DEV) console.log({ failureCount, error })
  25. if (failureCount >= 0 && import.meta.env.DEV) return false
  26. if (failureCount > 3 && import.meta.env.PROD) return false
  27. return !(
  28. error instanceof AxiosError &&
  29. [401, 403].includes(error.response?.status ?? 0)
  30. )
  31. },
  32. refetchOnWindowFocus: import.meta.env.PROD,
  33. staleTime: 10 * 1000, // 10s
  34. },
  35. mutations: {
  36. onError: (error) => {
  37. handleServerError(error)
  38. if (error instanceof AxiosError) {
  39. if (error.response?.status === 304) {
  40. toast.error('Content not modified!')
  41. }
  42. }
  43. },
  44. },
  45. },
  46. queryCache: new QueryCache({
  47. onError: (error) => {
  48. if (error instanceof AxiosError) {
  49. if (error.response?.status === 401) {
  50. toast.error('Session expired!')
  51. useAuthStore.getState().auth.reset()
  52. const redirect = `${router.history.location.href}`
  53. router.navigate({ to: '/sign-in', search: { redirect } })
  54. }
  55. if (error.response?.status === 500) {
  56. toast.error('Internal Server Error!')
  57. router.navigate({ to: '/500' })
  58. }
  59. if (error.response?.status === 403) {
  60. // router.navigate("/forbidden", { replace: true });
  61. }
  62. }
  63. },
  64. }),
  65. })
  66. // Create a new router instance
  67. const router = createRouter({
  68. routeTree,
  69. context: { queryClient },
  70. defaultPreload: 'intent',
  71. defaultPreloadStaleTime: 0,
  72. })
  73. // Register the router instance for type safety
  74. declare module '@tanstack/react-router' {
  75. interface Register {
  76. router: typeof router
  77. }
  78. }
  79. // Render the app
  80. const rootElement = document.getElementById('root')!
  81. if (!rootElement.innerHTML) {
  82. const root = ReactDOM.createRoot(rootElement)
  83. root.render(
  84. <StrictMode>
  85. <QueryClientProvider client={queryClient}>
  86. <ThemeProvider defaultTheme='light' storageKey='vite-ui-theme'>
  87. <FontProvider>
  88. <DirectionProvider>
  89. <RouterProvider router={router} />
  90. </DirectionProvider>
  91. </FontProvider>
  92. </ThemeProvider>
  93. </QueryClientProvider>
  94. </StrictMode>
  95. )
  96. }