main.tsx 3.0 KB

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