Skip to content

Commit 02c46c6

Browse files
authored
Merge pull request #185 from HarK-github/pr-public-route
Added check for authenticated users access to public pages
2 parents b3ef855 + bcd9c02 commit 02c46c6

4 files changed

Lines changed: 74 additions & 6 deletions

File tree

app/src/App.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Dashboard from "./components/discussion-forum/dashboard.jsx";
2323
import { SidebarProvider } from "./components/ui/sidebar.jsx";
2424
import { ThemeProvider } from "@/Context/ThemeProvider.jsx";
2525
import { NavMenu } from "./components/NavMenu";
26+
import PublicRoute from "./Context/PublicRoute";
2627
import ContestCalendar from "./components/ContestCalendar";
2728

2829
const BACKEND = import.meta.env.VITE_BACKEND;
@@ -95,8 +96,9 @@ function App() {
9596
<div className="App bg-background w-full">
9697
<NavMenu />
9798
<Routes>
98-
<Route exact path="/register" element={<Register />} />
99-
<Route exact path="/login" element={<Login />} />
99+
100+
<Route exact path="/register" element={<PublicRoute><Register /></PublicRoute>} />
101+
<Route exact path="/login" element={<PublicRoute><Login /></PublicRoute>} />
100102
<Route
101103
exact
102104
path="/leetcoderankingsccps"

app/src/Context/AuthContext.jsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createContext, useState, useContext } from "react";
1+
import { createContext, useState, useContext, useEffect } from "react"; // add useEffect
22
import { jwtDecode } from "jwt-decode";
33
import { useNavigate } from "react-router-dom";
44
import {
@@ -28,12 +28,24 @@ export const AuthProvider = ({ children }) => {
2828
authTokens ? jwtDecode(authTokens.access) : null,
2929
);
3030
const navigate = useNavigate();
31-
const [loading] = useState(false);
31+
const [loading, setLoading] = useState(false);
32+
33+
const isAuthenticated = Boolean(authTokens?.access);
3234
let [userNames, setUserNames] = useState(
3335
localStorage.getItem("userNames")
3436
? JSON.parse(localStorage.getItem("userNames"))
3537
: null,
3638
);
39+
useEffect(() => {
40+
if (authTokens) {
41+
setUser(jwtDecode(authTokens.access));
42+
} else {
43+
setUser(null);
44+
}
45+
setLoading(false);
46+
}, [authTokens]);
47+
48+
3749
let getUsernamesData = async (authToken) => {
3850
let usernames_response = await fetch(BACKEND + "/userDetails/", {
3951
method: "GET",
@@ -227,6 +239,7 @@ export const AuthProvider = ({ children }) => {
227239
let contextData = {
228240
user: user,
229241
authTokens: authTokens,
242+
isAuthenticated,
230243
loginUser: loginUser,
231244
registerUser: registerUser,
232245
logoutUser: logoutUser,
@@ -238,6 +251,7 @@ export const AuthProvider = ({ children }) => {
238251
loading,
239252
userNames: userNames,
240253
};
254+
241255
// useEffect(() => {
242256

243257
// const token = async (username) => {

app/src/Context/PublicRoute.jsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// PublicRoute.jsx
2+
import { Navigate } from "react-router-dom";
3+
import { useAuth } from "./AuthContext.jsx";
4+
5+
const PublicRoute = ({ children }) => {
6+
const { isAuthenticated, loading } = useAuth();
7+
8+
if (loading) {
9+
return (
10+
<div className="flex h-screen items-center justify-center">
11+
<div>Loading...</div>
12+
</div>
13+
);
14+
}
15+
16+
if (isAuthenticated) {
17+
return <Navigate to="/" replace />;
18+
}
19+
20+
return children;
21+
};
22+
23+
export default PublicRoute;

app/src/components/Login.jsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useSidebar } from "@/components/ui/sidebar";
33
import { zodResolver } from "@hookform/resolvers/zod";
44
import { useForm } from "react-hook-form";
55
import { z } from "zod";
6+
import { useEffect } from "react";
67

78
import { Button } from "@/components/ui/button";
89
import {
@@ -26,20 +27,48 @@ const FormSchema = z.object({
2627
});
2728

2829
const Login = () => {
29-
let { SignInWithGoogle, loginUser } = useAuth();
30+
let { SignInWithGoogle, loginUser, isAuthenticated, loading } = useAuth(); // Get isAuthenticated and loading
3031
const { open, isMobile } = useSidebar();
3132
const navigate = useNavigate();
33+
34+
useEffect(() => {
35+
if (isAuthenticated && !loading) {
36+
navigate("/");
37+
}
38+
}, [isAuthenticated, loading, navigate]);
39+
3240
const form = useForm({
3341
resolver: zodResolver(FormSchema),
3442
defaultValues: {
3543
username: "",
3644
password: "",
3745
},
3846
});
47+
3948
async function handleGoogleAuth(e) {
4049
e.preventDefault();
4150
await SignInWithGoogle();
4251
navigate("/");
52+
}
53+
if (loading) {
54+
return (
55+
<div
56+
className="text-foreground flex h-full flex-col"
57+
style={{
58+
width:
59+
open && !isMobile
60+
? "calc(100vw - var(--sidebar-width))"
61+
: "100vw",
62+
}}
63+
>
64+
<div className="m-auto">Loading...</div>
65+
</div>
66+
);
67+
}
68+
69+
// Don't render login form if already authenticated (will redirect)
70+
if (isAuthenticated) {
71+
return null; // Or a loading spinner since useEffect will redirect
4372
}
4473

4574
return (
@@ -101,4 +130,4 @@ const Login = () => {
101130
</div>
102131
);
103132
};
104-
export default Login;
133+
export default Login;

0 commit comments

Comments
 (0)