Skip to content

Commit ec52841

Browse files
committed
fix: added proper state management and route verification of dashboard page
Signed-off-by: Arya Pratap Singh <[email protected]>
1 parent fd2564a commit ec52841

File tree

4 files changed

+106
-19
lines changed

4 files changed

+106
-19
lines changed

components/AuthComponent/SignupForm.tsx

+23-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"use client";
22

33
import React, { useState } from "react";
4-
import { useRouter } from "next/navigation";
54
import { zodResolver } from "@hookform/resolvers/zod";
65
import { useForm } from "react-hook-form";
76
import * as z from "zod";
@@ -32,17 +31,23 @@ import {
3231
CardTitle,
3332
} from "@/components/ui/card";
3433
import { Alert, AlertDescription } from "@/components/ui/alert";
35-
import { useAuthStore } from "@/store/AuthStore/useAuthStore";
3634
import AuthBottom from "./AuthBottom";
3735
import LoadingButton from "./LoadingButton";
3836
import { signupSchema } from "@/validations/validation";
37+
import { useEffect } from "react"
38+
import { useRouter, useSearchParams } from "next/navigation"
39+
import { useAuthStore } from "@/store/AuthStore/useAuthStore"
40+
import { useAuth } from "@/hooks/useAuth";
3941

4042
type SignupFormValues = z.infer<typeof signupSchema>;
4143

4244
export default function SignupForm() {
4345
const { isSigningUp, signup, signupError } = useAuthStore();
4446
const router = useRouter();
4547
const [showPassword, setShowPassword] = useState(false);
48+
const { isSigningIn, signin, signinError } = useAuthStore()
49+
const { user, loading } = useAuth()
50+
const searchParams = useSearchParams()
4651

4752
const form = useForm<SignupFormValues>({
4853
resolver: zodResolver(signupSchema),
@@ -55,9 +60,22 @@ export default function SignupForm() {
5560
},
5661
});
5762

58-
const onSubmit = (data: SignupFormValues) => {
59-
signup(data, router);
60-
};
63+
useEffect(() => {
64+
// If user is already authenticated, redirect to the intended URL or dashboard
65+
if (user && !loading) {
66+
const redirectTo = searchParams.get('redirect') || '/dashboard'
67+
router.push(redirectTo)
68+
}
69+
}, [user, loading, router, searchParams])
70+
71+
const onSubmit = async (data: SignupFormValues) => {
72+
try {
73+
signup(data, router);
74+
// The redirect will be handled by the useEffect above when the user state updates
75+
} catch (error) {
76+
console.error('Sign in error:', error)
77+
}
78+
}
6179

6280
return (
6381
<main className="flex min-h-screen items-center justify-center md:p-0 p-2">

components/DashboardV2/V2Navbar.tsx

+38-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ import Link from "next/link";
2323
import Image from "next/image";
2424
import { ToggleTheme } from "./ToggleTheme";
2525
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar";
26+
import { useAuth } from "@/hooks/useAuth";
27+
import { signout } from "@/app/actions/action";
28+
import { useRouter } from "next/navigation";
2629

2730
interface RouteProps {
2831
href: string;
@@ -72,6 +75,38 @@ const featureList: FeatureProps[] = [
7275

7376
export const V2Navbar = () => {
7477
const [isOpen, setIsOpen] = React.useState(false);
78+
const { user, loading } = useAuth();
79+
const router = useRouter();
80+
81+
const handleSignOut = async () => {
82+
await signout();
83+
router.push('/auth/signin');
84+
};
85+
86+
const renderAuthButtons = () => {
87+
if (loading) return null;
88+
89+
if (user) {
90+
return (
91+
<Button onClick={handleSignOut} className="rounded-2xl">
92+
Sign Out
93+
</Button>
94+
);
95+
}
96+
97+
return (
98+
<>
99+
<Link href="/auth/register">
100+
<Button className="rounded-2xl">Register</Button>
101+
</Link>
102+
<Link href="/auth/signin">
103+
<Button className="rounded-2xl">Login</Button>
104+
</Link>
105+
</>
106+
);
107+
};
108+
109+
75110
return (
76111
<header className="shadow-inner w-[90%] md:w-[70%] lg:w-[75%] lg:max-w-screen-xl top-5 mx-auto sticky border border-secondary z-40 rounded-2xl flex justify-between items-center p-2 bg-secondary/30 backdrop-blur-md">
77112
<Link href="/" className="flex items-center font-semibold">
@@ -127,6 +162,8 @@ export const V2Navbar = () => {
127162
<Separator className="mb-2" />
128163

129164
<ToggleTheme />
165+
<Separator className="mb-2" />
166+
{renderAuthButtons()}
130167
</SheetFooter>
131168
</SheetContent>
132169
</Sheet>
@@ -181,13 +218,7 @@ export const V2Navbar = () => {
181218

182219
<div className="hidden lg:flex gap-2">
183220
<ToggleTheme />
184-
185-
<Link href="/auth/register">
186-
<Button className="rounded-2xl">Register</Button>
187-
</Link>
188-
<Link href="/auth/signin">
189-
<Button className="rounded-2xl">Login</Button>
190-
</Link>
221+
{renderAuthButtons()}
191222
</div>
192223
</header>
193224
);

hooks/useAuth.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { useEffect, useState } from 'react';
2+
import { createClient } from '@/utils/supabase/client';
3+
4+
import { User } from '@supabase/supabase-js';
5+
6+
export function useAuth() {
7+
const [user, setUser] = useState<User | null>(null);
8+
const [loading, setLoading] = useState(true);
9+
const supabase = createClient();
10+
11+
useEffect(() => {
12+
// Check active sessions and sets the user
13+
const getUser = async () => {
14+
const { data: { user }, error } = await supabase.auth.getUser();
15+
setUser(user);
16+
setLoading(false);
17+
};
18+
19+
getUser();
20+
21+
// Listen for changes on auth state (login, logout, etc)
22+
const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
23+
setUser(session?.user ?? null);
24+
setLoading(false);
25+
});
26+
27+
return () => {
28+
subscription.unsubscribe();
29+
};
30+
}, []);
31+
32+
return { user, loading };
33+
}

store/AuthStore/useAuthStore.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@ interface authStore {
1515
isSigningIn: boolean;
1616
signinError: string | null;
1717
signin: (signinMetaData: { email: string, password: string },router: any) => void;
18-
logout: () => void;
19-
18+
logout: (router: any) => void;
2019
signupError: string | null;
2120
isSigningUp: boolean;
2221
signup: (signupMetaData: User,router: any) => void;
2322
user: User | null;
24-
2523
authUserLoading: boolean;
2624
fetchAuthUser: () => void;
2725
authUser: User | null;
@@ -32,7 +30,7 @@ export const useAuthStore = create<authStore>((set) => ({
3230
isSigningIn: false,
3331
signin: async (signinMetaData,router) => {
3432
const supabase = createClient()
35-
set({ isSigningIn: true })
33+
set({ isSigningIn: true, signinError: null })
3634
try {
3735
const { data, error: loginError } =
3836
await supabase.auth.signInWithPassword(signinMetaData);
@@ -44,7 +42,8 @@ export const useAuthStore = create<authStore>((set) => ({
4442
}
4543

4644
if (data.session) {
47-
router.push("/dashboard");
45+
// Ensure we have a session before redirecting
46+
await router.push('/dashboard');
4847
} else {
4948
throw new Error("Unable to retrieve session after login.");
5049
}
@@ -56,8 +55,14 @@ export const useAuthStore = create<authStore>((set) => ({
5655
}
5756
},
5857

59-
logout: () => {
60-
console.log('logout');
58+
logout: async (router) => {
59+
const supabase = createClient()
60+
try {
61+
await supabase.auth.signOut();
62+
router.push('/auth/signin');
63+
} catch (error) {
64+
console.error('Logout error:', error);
65+
}
6166
},
6267

6368
signupError: null,

0 commit comments

Comments
 (0)