diff --git a/app/auth/register/page.tsx b/app/auth/register/page.tsx index 4b38104..ee9a4dd 100644 --- a/app/auth/register/page.tsx +++ b/app/auth/register/page.tsx @@ -1,9 +1,16 @@ +import { Suspense } from "react"; import SignupForm from "@/components/AuthComponent/SignupForm"; +import SearchParamsWrapper from "@/components/AuthComponent/SearchParamsWrapper"; + export default function SignupPage() { return (
- + Loading...
}> + + + + ); -} +} \ No newline at end of file diff --git a/components/AuthComponent/SearchParamsWrapper.tsx b/components/AuthComponent/SearchParamsWrapper.tsx new file mode 100644 index 0000000..ebd1db9 --- /dev/null +++ b/components/AuthComponent/SearchParamsWrapper.tsx @@ -0,0 +1,27 @@ +"use client"; + +import { useSearchParams } from "next/navigation"; +import React from "react"; + +interface ChildProps { + searchParams?: ReturnType; +} + +export default function SearchParamsWrapper({ + children +}: { + children: React.ReactNode +}) { + const searchParams = useSearchParams(); + + return ( + <> + {React.Children.map(children, child => { + if (React.isValidElement(child)) { + return React.cloneElement(child, { searchParams }); + } + return child; + })} + + ); +} \ No newline at end of file diff --git a/components/AuthComponent/SignupForm.tsx b/components/AuthComponent/SignupForm.tsx index 00d0ba2..7fa8367 100644 --- a/components/AuthComponent/SignupForm.tsx +++ b/components/AuthComponent/SignupForm.tsx @@ -1,7 +1,6 @@ "use client"; import React, { useState } from "react"; -import { useRouter } from "next/navigation"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import * as z from "zod"; @@ -32,17 +31,27 @@ import { CardTitle, } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; -import { useAuthStore } from "@/store/AuthStore/useAuthStore"; import AuthBottom from "./AuthBottom"; import LoadingButton from "./LoadingButton"; import { signupSchema } from "@/validations/validation"; +import { useEffect } from "react" +import { useRouter, useSearchParams } from "next/navigation" +import { useAuthStore } from "@/store/AuthStore/useAuthStore" +import { useAuth } from "@/hooks/useAuth"; type SignupFormValues = z.infer; -export default function SignupForm() { +interface SignupFormProps { + searchParams?: URLSearchParams; +} + +export default function SignupForm({searchParams}: SignupFormProps) { const { isSigningUp, signup, signupError } = useAuthStore(); const router = useRouter(); const [showPassword, setShowPassword] = useState(false); + const { isSigningIn, signin, signinError } = useAuthStore() + const { user, loading } = useAuth() + const form = useForm({ resolver: zodResolver(signupSchema), @@ -55,9 +64,22 @@ export default function SignupForm() { }, }); - const onSubmit = (data: SignupFormValues) => { - signup(data, router); - }; + useEffect(() => { + // If user is already authenticated, redirect to the intended URL or dashboard + if (user && !loading) { + const redirectTo = searchParams?.get('redirect') || '/dashboard' + router.push(redirectTo) + } + }, [user, loading, router, searchParams]) + + const onSubmit = async (data: SignupFormValues) => { + try { + signup(data, router); + // The redirect will be handled by the useEffect above when the user state updates + } catch (error) { + console.error('Sign in error:', error) + } + } return (
diff --git a/components/DashboardV2/V2Navbar.tsx b/components/DashboardV2/V2Navbar.tsx index f5a858d..ac2bff8 100644 --- a/components/DashboardV2/V2Navbar.tsx +++ b/components/DashboardV2/V2Navbar.tsx @@ -1,6 +1,6 @@ "use client"; import { ChevronsDown, Github, Menu } from "lucide-react"; -import React from "react"; +import React , { Suspense } from "react"; import { Sheet, SheetContent, @@ -23,6 +23,9 @@ import Link from "next/link"; import Image from "next/image"; import { ToggleTheme } from "./ToggleTheme"; import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar"; +import { useAuth } from "@/hooks/useAuth"; +import { signout } from "@/app/actions/action"; +import { useRouter } from "next/navigation"; interface RouteProps { href: string; @@ -70,8 +73,41 @@ const featureList: FeatureProps[] = [ }, ]; -export const V2Navbar = () => { +export const NavigationContent = () => { const [isOpen, setIsOpen] = React.useState(false); + const { user, loading } = useAuth(); + const router = useRouter(); + const [authState, setAuthState] = React.useState({ user, loading }); + + React.useEffect(() => { + setAuthState({ user, loading }); + }, [user, loading]); + + const handleSignOut = async () => { + await signout(); + router.push("/auth/signin"); + }; + + const renderAuthButtons = () => { + if (authState.loading) return null; + + return authState.user ? ( + + ) : ( + <> + + + + + + + + ); + }; + + return (
@@ -127,6 +163,8 @@ export const V2Navbar = () => { + + {renderAuthButtons()} @@ -181,14 +219,16 @@ export const V2Navbar = () => {
- - - - - - - + {renderAuthButtons()}
); }; + +export const V2Navbar = () => { + return ( + Loading...}> + + + ); +}; \ No newline at end of file diff --git a/hooks/useAuth.ts b/hooks/useAuth.ts new file mode 100644 index 0000000..742e6e2 --- /dev/null +++ b/hooks/useAuth.ts @@ -0,0 +1,33 @@ +import { useEffect, useState } from 'react'; +import { createClient } from '@/utils/supabase/client'; + +import { User } from '@supabase/supabase-js'; + +export function useAuth() { + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + const supabase = createClient(); + + useEffect(() => { + // Check active sessions and sets the user + const getUser = async () => { + const { data: { user }, error } = await supabase.auth.getUser(); + setUser(user); + setLoading(false); + }; + + getUser(); + + // Listen for changes on auth state (login, logout, etc) + const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => { + setUser(session?.user ?? null); + setLoading(false); + }); + + return () => { + subscription.unsubscribe(); + }; + }, []); + + return { user, loading }; +} \ No newline at end of file diff --git a/store/AuthStore/useAuthStore.ts b/store/AuthStore/useAuthStore.ts index ff27af9..d1ba178 100644 --- a/store/AuthStore/useAuthStore.ts +++ b/store/AuthStore/useAuthStore.ts @@ -15,13 +15,11 @@ interface authStore { isSigningIn: boolean; signinError: string | null; signin: (signinMetaData: { email: string, password: string },router: any) => void; - logout: () => void; - + logout: (router: any) => void; signupError: string | null; isSigningUp: boolean; signup: (signupMetaData: User,router: any) => void; user: User | null; - authUserLoading: boolean; fetchAuthUser: () => void; authUser: User | null; @@ -32,7 +30,7 @@ export const useAuthStore = create((set) => ({ isSigningIn: false, signin: async (signinMetaData,router) => { const supabase = createClient() - set({ isSigningIn: true }) + set({ isSigningIn: true, signinError: null }) try { const { data, error: loginError } = await supabase.auth.signInWithPassword(signinMetaData); @@ -44,7 +42,8 @@ export const useAuthStore = create((set) => ({ } if (data.session) { - router.push("/dashboard"); + // Ensure we have a session before redirecting + await router.push('/dashboard'); } else { throw new Error("Unable to retrieve session after login."); } @@ -56,8 +55,14 @@ export const useAuthStore = create((set) => ({ } }, - logout: () => { - console.log('logout'); + logout: async (router) => { + const supabase = createClient() + try { + await supabase.auth.signOut(); + router.push('/auth/signin'); + } catch (error) { + console.error('Logout error:', error); + } }, signupError: null,