Skip to content

Commit 298821e

Browse files
committed
feat: complete login, logout flow
1 parent 3019c75 commit 298821e

File tree

5 files changed

+104
-21
lines changed

5 files changed

+104
-21
lines changed

apps/web/src/app/auth/callback/page.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import Image from "next/image";
44
import { useRouter } from "next/navigation";
55
import { useEffect, useState } from "react";
6-
import { env } from "@/env";
6+
import { client } from "@/lib/client";
77

88
export default function AuthCallback() {
99
const router = useRouter();
@@ -40,22 +40,22 @@ export default function AuthCallback() {
4040
return;
4141
}
4242

43-
// Send tokens to backend
44-
const response = await fetch(`${env.NEXT_PUBLIC_BACKEND_URL}/api/auth/callback`, {
45-
method: "POST",
46-
headers: {
47-
"Content-Type": "application/json",
48-
},
49-
body: JSON.stringify({
43+
const response = await client.api.auth.callback.post(
44+
{
5045
access_token: accessToken,
5146
refresh_token: refreshToken,
52-
}),
53-
credentials: "include", // Important for cookies
54-
});
47+
},
48+
{
49+
headers: {
50+
"Content-Type": "application/json",
51+
credentials: "include",
52+
},
53+
}
54+
);
5555

56-
const result = await response.json();
56+
const result = response.data;
5757

58-
if (response.ok && result.success) {
58+
if (response.status === 200 && result?.user) {
5959
setStatus("success");
6060
setMessage("Authentication successful!");
6161
setUserInfo(result.user);
@@ -68,11 +68,11 @@ export default function AuthCallback() {
6868

6969
// Redirect to your desired page after a delay
7070
setTimeout(() => {
71-
router.push("/test");
71+
router.push("/dashboard");
7272
}, 3000);
7373
} else {
7474
setStatus("error");
75-
setMessage(result.error || "Authentication failed");
75+
setMessage(response.error?.value?.summary || "Authentication failed");
7676
}
7777
} catch (error) {
7878
console.error("Auth callback error:", error);

apps/web/src/app/auth/login/page.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
"use client";
22

33
import Image from "next/image";
4+
import { useRouter } from "next/navigation";
45
import { useEffect, useState } from "react";
6+
import { SIGN_IN_LINK } from "@/config/link";
57
import { env } from "@/env";
8+
import { client } from "@/lib/client";
69

710
interface UserInfo {
811
id: string;
@@ -13,6 +16,7 @@ interface UserInfo {
1316

1417
export default function TestPage() {
1518
const [user, setUser] = useState<UserInfo | null>(null);
19+
const router = useRouter();
1620

1721
useEffect(() => {
1822
// Check if user is logged in
@@ -24,17 +28,25 @@ export default function TestPage() {
2428

2529
const handleGoogleSignIn = () => {
2630
// Redirect to your backend's Google auth endpoint
27-
window.location.href = `${env.NEXT_PUBLIC_BACKEND_URL}/api/auth/google`;
31+
router.push(SIGN_IN_LINK);
2832
};
2933

3034
const handleSignOut = () => {
3135
localStorage.removeItem("user");
3236
setUser(null);
33-
// Optionally, also clear the backend session
34-
fetch(`${env.NEXT_PUBLIC_BACKEND_URL}api/auth/logout`, {
35-
method: "POST",
36-
credentials: "include",
37-
}).catch(console.error);
37+
38+
client.api.auth.logout
39+
.post(
40+
{},
41+
{
42+
headers: {
43+
credentials: "include",
44+
},
45+
}
46+
)
47+
.catch((error) => {
48+
console.error("Logout failed:", error);
49+
});
3850
};
3951

4052
if (user) {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"use client";
2+
3+
// Auth Guard for Dashboard Page
4+
5+
import { useRouter } from "next/navigation";
6+
import { useEffect, useState } from "react";
7+
import { client } from "@/lib/client";
8+
9+
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
10+
const [isAuthenticated, setIsAuthenticated] = useState(false);
11+
const router = useRouter();
12+
13+
useEffect(() => {
14+
// Check if user is logged in
15+
const storedUser = localStorage.getItem("user");
16+
if (storedUser) {
17+
setIsAuthenticated(true);
18+
} else {
19+
// Redirect to login page if not authenticated
20+
router.push("/auth/login");
21+
}
22+
}, [router]);
23+
24+
if (!isAuthenticated) {
25+
return <div>Loading...</div>; // or a loading spinner
26+
}
27+
28+
const handleLogout = () => {
29+
client.api.auth.logout
30+
.post(
31+
{},
32+
{
33+
headers: {
34+
credentials: "include",
35+
},
36+
}
37+
)
38+
.then(() => {
39+
localStorage.removeItem("user");
40+
setIsAuthenticated(false);
41+
router.push("/auth/login");
42+
})
43+
.catch((error) => {
44+
console.error("Logout failed:", error);
45+
});
46+
};
47+
48+
return (
49+
<div className="min-h-screen flex flex-col">
50+
<header className="bg-gray-800 text-white flex justify-between p-4">
51+
<h1 className="text-xl">Dashboard</h1>
52+
<button
53+
type="button"
54+
onClick={() => handleLogout()}
55+
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
56+
>
57+
Logout
58+
</button>
59+
</header>
60+
<main className="flex-1 p-6 bg-gray-100">{children}</main>
61+
</div>
62+
);
63+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function DashBoardPage() {
2+
return <div>Hello fellow traveller.</div>;
3+
}

apps/web/src/config/link.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { env } from "@/env";
2+
3+
const REDIRDCT_URI = encodeURIComponent(`${env.NEXT_PUBLIC_APP_URL}/auth/callback`);
4+
5+
export const SIGN_IN_LINK = `https://qtrkroiyvtnwdpjscyvp.supabase.co/auth/v1/authorize?provider=google&redirect_to=${REDIRDCT_URI}&scopes=email%20profile`;

0 commit comments

Comments
 (0)