main.tsx 3.0 KB

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