|
1 | | - |
| 1 | +import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; |
| 2 | +import { useEffect, useState } from 'react'; |
| 3 | +import AuthProvider, { useAuth } from './utils/auth'; |
2 | 4 | import { Toaster } from "@/components/ui/toaster"; |
3 | | -import { Toaster as Sonner } from "@/components/ui/sonner"; |
4 | | -import { TooltipProvider } from "@/components/ui/tooltip"; |
5 | | -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; |
6 | | -import { BrowserRouter, Routes, Route } from "react-router-dom"; |
7 | | -import { AuthProvider } from "./utils/auth"; |
8 | | -import AuthWrapper from "./components/AuthWrapper"; |
9 | | -import Friends from "./pages/Friends"; |
10 | | -import Navbar from "./components/Navbar"; |
| 5 | +import { useToast } from '@/hooks/use-toast'; |
| 6 | + |
| 7 | +// Import all pages |
| 8 | +import Navbar from '@/components/Navbar'; |
| 9 | +import Index from '@/pages/Index'; |
| 10 | +import Login from '@/pages/Login'; |
| 11 | +import Register from '@/pages/Register'; |
| 12 | +import ForgotPassword from '@/pages/ForgotPassword'; |
| 13 | +import Dashboard from '@/pages/Dashboard'; |
| 14 | +import Profile from '@/pages/Profile'; |
| 15 | +import Community from '@/pages/Community'; |
| 16 | +import Meditations from '@/pages/Meditations'; |
| 17 | +import Analytics from '@/pages/Analytics'; |
| 18 | +import MapPage from '@/pages/Map'; |
| 19 | +import Journal from '@/pages/Journal'; |
| 20 | +import JournalEntries from '@/pages/JournalEntries'; |
| 21 | +import Challenges from '@/pages/Challenges'; |
| 22 | +import Achievements from '@/pages/Achievements'; |
| 23 | +import Referrals from '@/pages/Referrals'; |
| 24 | +import Friends from '@/pages/Friends'; |
| 25 | +import Admin from '@/pages/Admin'; |
| 26 | +import Goodbye from '@/pages/Goodbye'; |
| 27 | +import NotFound from '@/pages/NotFound'; |
| 28 | + |
| 29 | +import { |
| 30 | + QueryClient, |
| 31 | + QueryClientProvider, |
| 32 | +} from '@tanstack/react-query' |
| 33 | + |
| 34 | +const queryClient = new QueryClient() |
| 35 | + |
| 36 | +function AuthWrapper({ children, adminOnly = false }: { children: React.ReactNode, adminOnly?: boolean }) { |
| 37 | + const { currentUser, isLoading, isAdmin } = useAuth(); |
| 38 | + const { toast } = useToast(); |
| 39 | + const [hasCheckedAuth, setHasCheckedAuth] = useState(false); |
11 | 40 |
|
12 | | -// Import all the page components |
13 | | -import Index from "./pages/Index"; |
14 | | -import Login from "./pages/Login"; |
15 | | -import Register from "./pages/Register"; |
16 | | -import ForgotPassword from "./pages/ForgotPassword"; |
17 | | -import Dashboard from "./pages/Dashboard"; |
18 | | -import Profile from "./pages/Profile"; |
19 | | -import Community from "./pages/Community"; |
20 | | -import Meditations from "./pages/Meditations"; |
21 | | -import Analytics from "./pages/Analytics"; |
22 | | -import MapPage from "./pages/Map"; // Renamed to avoid conflict with JS Map |
23 | | -import Journal from "./pages/Journal"; |
24 | | -import JournalEntries from "./pages/JournalEntries"; |
25 | | -import Challenges from "./pages/Challenges"; |
26 | | -import Achievements from "./pages/Achievements"; |
27 | | -import Referrals from "./pages/Referrals"; |
28 | | -import Admin from "./pages/Admin"; |
29 | | -import Goodbye from "./pages/Goodbye"; |
30 | | -import NotFound from "./pages/NotFound"; |
| 41 | + useEffect(() => { |
| 42 | + if (!isLoading) { |
| 43 | + setHasCheckedAuth(true); |
| 44 | + } |
| 45 | + }, [isLoading]); |
31 | 46 |
|
32 | | -const queryClient = new QueryClient(); |
| 47 | + if (isLoading) { |
| 48 | + return <div>Loading...</div>; |
| 49 | + } |
33 | 50 |
|
34 | | -const App = () => ( |
35 | | - <QueryClientProvider client={queryClient}> |
36 | | - <AuthProvider> |
37 | | - <TooltipProvider> |
38 | | - <Toaster /> |
39 | | - <Sonner /> |
40 | | - <BrowserRouter> |
41 | | - <div className="min-h-screen flex flex-col"> |
42 | | - <Navbar /> |
43 | | - <main className="flex-1"> |
44 | | - <Routes> |
45 | | - {/* Public routes */} |
46 | | - <Route path="/" element={<Index />} /> |
47 | | - <Route path="/login" element={<Login />} /> |
48 | | - <Route path="/register" element={<Register />} /> |
49 | | - <Route path="/forgot-password" element={<ForgotPassword />} /> |
| 51 | + if (!hasCheckedAuth) { |
| 52 | + return null; |
| 53 | + } |
50 | 54 |
|
51 | | - {/* Protected member routes */} |
52 | | - <Route |
53 | | - path="/dashboard" |
54 | | - element={ |
55 | | - <AuthWrapper requireAuth> |
56 | | - <Dashboard /> |
57 | | - </AuthWrapper> |
58 | | - } |
59 | | - /> |
60 | | - <Route |
61 | | - path="/profile" |
62 | | - element={ |
63 | | - <AuthWrapper requireAuth> |
64 | | - <Profile /> |
65 | | - </AuthWrapper> |
66 | | - } |
67 | | - /> |
68 | | - <Route |
69 | | - path="/community" |
70 | | - element={ |
71 | | - <AuthWrapper requireAuth> |
72 | | - <Community /> |
73 | | - </AuthWrapper> |
74 | | - } |
75 | | - /> |
76 | | - <Route |
77 | | - path="/meditations" |
78 | | - element={ |
79 | | - <AuthWrapper requireAuth> |
80 | | - <Meditations /> |
81 | | - </AuthWrapper> |
82 | | - } |
83 | | - /> |
84 | | - <Route |
85 | | - path="/analytics" |
86 | | - element={ |
87 | | - <AuthWrapper requireAuth> |
88 | | - <Analytics /> |
89 | | - </AuthWrapper> |
90 | | - } |
91 | | - /> |
92 | | - <Route |
93 | | - path="/map" |
94 | | - element={ |
95 | | - <AuthWrapper requireAuth> |
96 | | - <MapPage /> |
97 | | - </AuthWrapper> |
98 | | - } |
99 | | - /> |
100 | | - <Route |
101 | | - path="/journal" |
102 | | - element={ |
103 | | - <AuthWrapper requireAuth> |
104 | | - <Journal /> |
105 | | - </AuthWrapper> |
106 | | - } |
107 | | - /> |
108 | | - <Route |
109 | | - path="/journal-entries" |
110 | | - element={ |
111 | | - <AuthWrapper requireAuth> |
112 | | - <JournalEntries /> |
113 | | - </AuthWrapper> |
114 | | - } |
115 | | - /> |
116 | | - <Route |
117 | | - path="/challenges" |
118 | | - element={ |
119 | | - <AuthWrapper requireAuth> |
120 | | - <Challenges /> |
121 | | - </AuthWrapper> |
122 | | - } |
123 | | - /> |
124 | | - <Route |
125 | | - path="/achievements" |
126 | | - element={ |
127 | | - <AuthWrapper requireAuth> |
128 | | - <Achievements /> |
129 | | - </AuthWrapper> |
130 | | - } |
131 | | - /> |
132 | | - <Route |
133 | | - path="/referrals" |
134 | | - element={ |
135 | | - <AuthWrapper requireAuth> |
136 | | - <Referrals /> |
137 | | - </AuthWrapper> |
138 | | - } |
139 | | - /> |
140 | | - <Route |
141 | | - path="/friends" |
142 | | - element={ |
143 | | - <AuthWrapper requireAuth> |
144 | | - <Friends /> |
145 | | - </AuthWrapper> |
146 | | - } |
147 | | - /> |
| 55 | + if (!currentUser) { |
| 56 | + toast({ |
| 57 | + title: "Unauthorized", |
| 58 | + description: "You must be logged in to view this page.", |
| 59 | + }) |
| 60 | + return <Navigate to="/login" />; |
| 61 | + } |
148 | 62 |
|
149 | | - {/* Admin routes */} |
150 | | - <Route |
151 | | - path="/admin" |
152 | | - element={ |
153 | | - <AuthWrapper requireAuth requireAdmin> |
154 | | - <Admin /> |
155 | | - </AuthWrapper> |
156 | | - } |
157 | | - /> |
| 63 | + if (adminOnly && !isAdmin) { |
| 64 | + toast({ |
| 65 | + title: "Unauthorized", |
| 66 | + description: "You do not have permission to view this page.", |
| 67 | + }) |
| 68 | + return <Navigate to="/dashboard" />; |
| 69 | + } |
158 | 70 |
|
159 | | - <Route |
160 | | - path="/goodbye" |
161 | | - element={ |
162 | | - <AuthWrapper requireAuth> |
163 | | - <Goodbye /> |
164 | | - </AuthWrapper> |
165 | | - } |
166 | | - /> |
| 71 | + return <>{children}</>; |
| 72 | +} |
167 | 73 |
|
168 | | - {/* Catch-all route */} |
169 | | - <Route path="*" element={<NotFound />} /> |
170 | | - </Routes> |
171 | | - </main> |
172 | | - </div> |
173 | | - </BrowserRouter> |
174 | | - </TooltipProvider> |
175 | | - </AuthProvider> |
176 | | - </QueryClientProvider> |
177 | | -); |
| 74 | +function App() { |
| 75 | + return ( |
| 76 | + <Router> |
| 77 | + <AuthProvider> |
| 78 | + <Navbar /> |
| 79 | + <Routes> |
| 80 | + <Route path="/" element={<Index />} /> |
| 81 | + <Route path="/login" element={<Login />} /> |
| 82 | + <Route path="/register" element={<Register />} /> |
| 83 | + <Route path="/forgot-password" element={<ForgotPassword />} /> |
| 84 | + |
| 85 | + {/* Protected routes */} |
| 86 | + <Route path="/dashboard" element={ |
| 87 | + <AuthWrapper> |
| 88 | + <Dashboard /> |
| 89 | + </AuthWrapper> |
| 90 | + } /> |
| 91 | + |
| 92 | + <Route path="/profile" element={ |
| 93 | + <AuthWrapper> |
| 94 | + <Profile /> |
| 95 | + </AuthWrapper> |
| 96 | + } /> |
| 97 | + |
| 98 | + <Route path="/community" element={ |
| 99 | + <AuthWrapper> |
| 100 | + <Community /> |
| 101 | + </AuthWrapper> |
| 102 | + } /> |
| 103 | + |
| 104 | + <Route path="/meditations" element={ |
| 105 | + <AuthWrapper> |
| 106 | + <Meditations /> |
| 107 | + </AuthWrapper> |
| 108 | + } /> |
| 109 | + |
| 110 | + <Route path="/analytics" element={ |
| 111 | + <AuthWrapper> |
| 112 | + <Analytics /> |
| 113 | + </AuthWrapper> |
| 114 | + } /> |
| 115 | + |
| 116 | + <Route path="/map" element={ |
| 117 | + <AuthWrapper> |
| 118 | + <MapPage /> |
| 119 | + </AuthWrapper> |
| 120 | + } /> |
| 121 | + |
| 122 | + <Route path="/journal" element={ |
| 123 | + <AuthWrapper> |
| 124 | + <Journal /> |
| 125 | + </AuthWrapper> |
| 126 | + } /> |
| 127 | + |
| 128 | + <Route path="/journal/entries" element={ |
| 129 | + <AuthWrapper> |
| 130 | + <JournalEntries /> |
| 131 | + </AuthWrapper> |
| 132 | + } /> |
| 133 | + |
| 134 | + <Route path="/challenges" element={ |
| 135 | + <AuthWrapper> |
| 136 | + <Challenges /> |
| 137 | + </AuthWrapper> |
| 138 | + } /> |
| 139 | + |
| 140 | + <Route path="/achievements" element={ |
| 141 | + <AuthWrapper> |
| 142 | + <Achievements /> |
| 143 | + </AuthWrapper> |
| 144 | + } /> |
| 145 | + |
| 146 | + <Route path="/referrals" element={ |
| 147 | + <AuthWrapper> |
| 148 | + <Referrals /> |
| 149 | + </AuthWrapper> |
| 150 | + } /> |
| 151 | + |
| 152 | + <Route path="/friends" element={ |
| 153 | + <AuthWrapper> |
| 154 | + <Friends /> |
| 155 | + </AuthWrapper> |
| 156 | + } /> |
| 157 | + |
| 158 | + {/* Admin route */} |
| 159 | + <Route path="/admin" element={ |
| 160 | + <AuthWrapper adminOnly> |
| 161 | + <Admin /> |
| 162 | + </AuthWrapper> |
| 163 | + } /> |
| 164 | + |
| 165 | + {/* Misc routes */} |
| 166 | + <Route path="/goodbye" element={<Goodbye />} /> |
| 167 | + <Route path="*" element={<NotFound />} /> |
| 168 | + </Routes> |
| 169 | + </AuthProvider> |
| 170 | + <Toaster /> |
| 171 | + </Router> |
| 172 | + ); |
| 173 | +} |
178 | 174 |
|
179 | 175 | export default App; |
0 commit comments