Skip to content

Commit 4ef6d5d

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 9e05e06 + 74de19d commit 4ef6d5d

File tree

23 files changed

+844
-461
lines changed

23 files changed

+844
-461
lines changed

app/api/auth/logout/route.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { NextResponse } from "next/server";
2+
3+
export async function POST() {
4+
try {
5+
const response = NextResponse.json(
6+
{ message: "Logged out successfully" },
7+
{ status: 200 },
8+
);
9+
10+
// Clear the HTTP-only cookie
11+
response.cookies.delete("token");
12+
13+
return response;
14+
} catch (error: any) {
15+
return NextResponse.json({ message: "Logout failed" }, { status: 500 });
16+
}
17+
}
File renamed without changes.

app/auth/logout/handleLogout.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { axiosInstance } from "@/lib/api/axios";
2+
import { useUserStore } from "@/lib/store/user";
3+
4+
export const handleLogout = async () => {
5+
try {
6+
// Call logout API
7+
await axiosInstance.post("/auth/logout");
8+
9+
// Clear user store
10+
useUserStore.getState().logout();
11+
12+
// Clear cookies
13+
document.cookie = "token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
14+
15+
// Clear local storage
16+
localStorage.removeItem("user-storage");
17+
18+
// Refresh the page to ensure clean state
19+
window.location.href = "/auth/login";
20+
} catch (error) {
21+
console.error("Logout failed:", error);
22+
throw error;
23+
}
24+
};

app/auth/logout/page.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"use client";
2+
3+
import { Button } from "@/components/ui/button";
4+
import Image from "next/image";
5+
import Link from "next/link";
6+
import { toast } from "sonner";
7+
import { handleLogout } from "./handleLogout";
8+
9+
export default function Logout() {
10+
const onLogout = async () => {
11+
try {
12+
await handleLogout();
13+
toast.success("Logged out successfully");
14+
} catch (error) {
15+
toast.error("Failed to logout");
16+
}
17+
};
18+
19+
return (
20+
<div className="h-screen w-full flex flex-col items-center justify-center bg-white">
21+
<div className="container px-4 flex flex-col items-center">
22+
{/* Confirmation GIF */}
23+
<Image
24+
src="/gifs/yes_no.gif"
25+
alt="Confirm Logout"
26+
width={500}
27+
height={500}
28+
/>
29+
30+
{/* Description */}
31+
<div className="mt-8 text-center">
32+
<h2 className="text-2xl font-semibold md:text-3xl mb-4">
33+
Are you sure you want to logout?
34+
</h2>
35+
<p className="text-gray-600 mb-8">
36+
You&apos;ll need to sign in again to access your account.
37+
</p>
38+
</div>
39+
40+
{/* Action Buttons */}
41+
<div className="flex gap-4">
42+
<Button
43+
onClick={onLogout}
44+
variant="destructive"
45+
className="flex items-center space-x-2 px-6 py-2 rounded transition duration-150 text-base h-full"
46+
>
47+
<span>Yes, Logout</span>
48+
</Button>
49+
50+
<Link
51+
href="/"
52+
className="flex items-center space-x-2 bg-neutral-500 hover:bg-neutral-700 text-white px-6 py-2 rounded transition duration-150"
53+
>
54+
<span>Cancel</span>
55+
</Link>
56+
</div>
57+
</div>
58+
</div>
59+
);
60+
}
File renamed without changes.
File renamed without changes.

app/not-found.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function NotFound() {
77
<div className="h-screen w-full flex flex-col items-center justify-center bg-white">
88
<div className="container px-4 flex flex-col items-center">
99
{/* Error Code */}
10-
<Image src={"/404.svg"} alt="404" width={400} height={400} />
10+
<Image src={"/gifs/404.gif"} alt="404" width={500} height={500} />
1111

1212
{/* Description */}
1313
<div className="mt-8 text-center">

components/LoginPage/Login.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { cn } from "@/lib/utils";
66
import { useMutation } from "@tanstack/react-query";
77
import { useRouter } from "next/navigation";
88
import React, { useRef } from "react";
9+
import { toast } from "sonner";
910
import { Input } from "../ui/input";
1011
import { Label } from "../ui/label";
11-
import { toast } from "sonner";
1212

1313
interface LoginFormData {
1414
identifier: string;
@@ -38,8 +38,8 @@ export default function LoginForm() {
3838
// Reset form
3939
formRef.current?.reset();
4040

41-
// Redirect to Home
42-
router.replace("/");
41+
// Redirect to profile page
42+
router.replace("/profile/me");
4343
},
4444
onError: (error: any) => {
4545
console.error("Login failed:", error);

components/Navbar.tsx

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ import {
1313
navigationMenuTriggerStyle,
1414
} from "@/components/ui/navigation-menu";
1515
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
16-
import { loginSignup, navbarItems } from "@/data/navbarItems";
16+
import { loginSignup, navbarItems, profileMenuItems } from "@/data/navbarItems";
17+
import { useUserStore } from "@/lib/store";
1718
import { cn } from "@/lib/utils";
1819
import { Menu } from "lucide-react";
1920
import Link from "next/link";
2021
import * as React from "react";
22+
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
2123

2224
const ListItem = React.forwardRef<
2325
React.ElementRef<typeof Link>,
@@ -50,11 +52,16 @@ ListItem.displayName = "ListItem";
5052
export function Navbar() {
5153
const [isOpen, setIsOpen] = useState(false);
5254

55+
const { user, token } = useUserStore();
56+
const isLoggedIn = !!token;
57+
5358
return (
5459
<div className="w-full border-b relative flex-shrink-0">
5560
<div className="container mx-auto flex h-16 items-center justify-between max-w-[90vw]">
5661
{/* Left - Brand */}
57-
<div className="text-xl font-bold">IIITS</div>
62+
<Link href="/" className="text-xl font-bold">
63+
IIITS
64+
</Link>
5865

5966
{/* Mobile Menu Button */}
6067
<div className="sm:hidden">
@@ -68,7 +75,9 @@ export function Navbar() {
6875
<div className="flex h-full flex-col">
6976
{/* Sheet Header */}
7077
<div className="border-b pb-4">
71-
<h2 className="text-lg font-semibold">IIITS</h2>
78+
<Link href="/" className="text-lg font-semibold">
79+
IIITS
80+
</Link>
7281
</div>
7382

7483
{/* Scrollable Content */}
@@ -105,12 +114,22 @@ export function Navbar() {
105114

106115
{/* Sheet Footer */}
107116
<div className="border-t pt-4">
108-
<div className="flex flex-col gap-2 text-lg">
109-
{loginSignup.map((item) => (
110-
<Link key={item.href} href={item.href} passHref>
111-
<Button variant={item.variant}>{item.text}</Button>
112-
</Link>
113-
))}
117+
<div className="flex gap-2 text-lg">
118+
{isLoggedIn ? (
119+
<>
120+
{profileMenuItems.map((item) => (
121+
<Button key={item.title} variant="outline" asChild>
122+
<Link href={item.href}>{item.title}</Link>
123+
</Button>
124+
))}
125+
</>
126+
) : (
127+
loginSignup.map((item) => (
128+
<Link key={item.href} href={item.href} passHref>
129+
<Button variant={item.variant}>{item.text}</Button>
130+
</Link>
131+
))
132+
)}
114133
</div>
115134
</div>
116135
</div>
@@ -156,11 +175,39 @@ export function Navbar() {
156175

157176
{/* Desktop - Auth Buttons */}
158177
<div className="hidden items-center gap-2 sm:flex">
159-
{loginSignup.map((item) => (
160-
<Link key={item.href} href={item.href} passHref>
161-
<Button variant={item.variant}>{item.text}</Button>
162-
</Link>
163-
))}
178+
{isLoggedIn ? (
179+
<NavigationMenu>
180+
<NavigationMenuList>
181+
<NavigationMenuItem>
182+
<NavigationMenuTrigger className="h-8 w-8 rounded-full">
183+
<Avatar>
184+
<AvatarImage src={user?.profilePicture || ""} />
185+
<AvatarFallback>{user?.name?.[0] || "U"}</AvatarFallback>
186+
</Avatar>
187+
</NavigationMenuTrigger>
188+
<NavigationMenuContent>
189+
<ul className="grid w-[300px] gap-2 p-4">
190+
{profileMenuItems.map((item) => (
191+
<ListItem
192+
key={item.href}
193+
title={item.title}
194+
href={item.href}
195+
>
196+
{item.description}
197+
</ListItem>
198+
))}
199+
</ul>
200+
</NavigationMenuContent>
201+
</NavigationMenuItem>
202+
</NavigationMenuList>
203+
</NavigationMenu>
204+
) : (
205+
loginSignup.map((item) => (
206+
<Link key={item.href} href={item.href} passHref>
207+
<Button variant={item.variant}>{item.text}</Button>
208+
</Link>
209+
))
210+
)}
164211
</div>
165212
</div>
166213
</div>

0 commit comments

Comments
 (0)