diff --git a/app/api/authChange/route.ts b/app/api/authChange/route.ts new file mode 100644 index 0000000..cc58bad --- /dev/null +++ b/app/api/authChange/route.ts @@ -0,0 +1,54 @@ +// app/api/auth-change/route.ts +import { NextRequest, NextResponse } from 'next/server'; +import { createServerClient, CookieOptions } from '@supabase/ssr'; + +export async function POST(request: NextRequest) { + const { event, session } = await request.json(); + + // Initialize Supabase client with SSR capabilities + const supabase = createServerClient( + process.env.NEXT_PUBLIC_SUPABASE_URL!, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, + { + cookies: { + get(name: string) { + return request.cookies.get(name)?.value || null; + }, + set(name: string, value: string, options: CookieOptions) { + request.cookies.set({ + name, + value, + ...options, + }); + }, + remove(name: string, options: CookieOptions) { + request.cookies.set({ + name, + value: '', + ...options, + }); + }, + }, + } + ); + + if (event === 'SIGNED_IN') { + // Handle user sign in + if (session) { + // Update session cookies + const response = NextResponse.json({ message: 'User signed in' }); + response.cookies.set('supabase-auth-token', session.access_token, { + httpOnly: true, + path: '/', + }); + return response; + } + } else if (event === 'SIGNED_OUT') { + // Handle user sign out + const response = NextResponse.json({ message: 'User signed out' }); + response.cookies.delete('supabase-auth-token'); + return response; + } + + return NextResponse.json({ message: 'Auth state change handled' }); +} diff --git a/app/api/logout/route.ts b/app/api/logout/route.ts index 8b3e498..e8e3ab7 100644 --- a/app/api/logout/route.ts +++ b/app/api/logout/route.ts @@ -1,11 +1,10 @@ -import type { NextApiRequest, NextApiResponse } from 'next' import { NextRequest, NextResponse } from 'next/server' import { createClient } from '../../utils/supabase/server' import { deleteCookie } from '../../utils/supabase/cookies' export async function POST(req: NextRequest) { - const supabase = createClient() + const supabase = createClient(); const { error } = await supabase.auth.signOut() diff --git a/app/components/NavbarClient.tsx b/app/components/NavbarClient.tsx index 2ed05a6..395f02c 100644 --- a/app/components/NavbarClient.tsx +++ b/app/components/NavbarClient.tsx @@ -1,6 +1,6 @@ 'use client'; -import { startTransition, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { AppBar, Toolbar, Grid, Button, Box } from '@mui/material'; import Link from 'next/link'; @@ -54,23 +54,10 @@ const NavbarClient: React.FC = ({ initialUserData }) => { await fetch('/api/logout', { method: 'POST', }) - router.push('/login') // Redirect to the login page or any other page after logout + router.push('/') // Redirect to the login page or any other page after logout window.location.reload(); // }) } -// // app/components/SuspenseWrapper.tsx -// import React, { Suspense } from 'react' -// import DataComponent from './DataComponent' - -// const SuspenseWrapper: React.FC = () => { -// return ( -// Loading...}> -// -// -// ) -// } - -// export default SuspenseWrapper return ( diff --git a/app/login/actions.ts b/app/login/actions.ts index ea9448c..51cfe00 100644 --- a/app/login/actions.ts +++ b/app/login/actions.ts @@ -5,7 +5,7 @@ import { revalidatePath } from 'next/cache'; import { redirect } from 'next/navigation'; import { createClient } from '../utils/supabase/server'; import { deleteCookie } from "../utils/supabase/cookies"; -import { NextApiResponse } from "next"; +import { NextRequest, NextResponse } from "next/server"; export async function login(formData: FormData) { const supabase = createClient(); @@ -57,8 +57,9 @@ export async function signup(formData: FormData) { redirect('/dashboard') }; -export async function logout(context: { res: NextApiResponse }) { - const supabase = createClient() +export async function logout(req: NextRequest): Promise { + const supabase = createClient(); + const response = NextResponse.redirect('/login'); const { error } = await supabase.auth.signOut() @@ -67,7 +68,7 @@ export async function logout(context: { res: NextApiResponse }) { } // Delete cookies if needed - deleteCookie(context.res, 'yourCookieName') + deleteCookie(response, 'user-data') revalidatePath('/', 'layout') redirect('/login') // Redirect to the login page or any other page after logout diff --git a/app/login/page.tsx b/app/login/page.tsx index d38b356..8d336fb 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -1,12 +1,40 @@ 'use client'; -import React from 'react'; +import React, { useEffect } from 'react'; import Link from "next/link"; import MainLayout from '../layout'; import { TextField, Button, Grid, Typography, Box, IconButton } from "@mui/material"; import ArrowCircleLeftTwoToneIcon from '@mui/icons-material/ArrowCircleLeftTwoTone'; import { login } from './actions'; +import { createClient } from '../utils/supabase/client'; +import { useRouter } from 'next/navigation'; + +const supabase = createClient(); const Login: React.FC = () => { + const router = useRouter(); + + useEffect(() => { + // Client-side listener setup for authentication state changes + const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => { + fetch('/api/authChange', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ event, session }), + }); + + // Optional: Redirect after login or logout based on the event + if (event === 'SIGNED_IN') { + router.push('/dashboard'); // Redirect to dashboard after login + } else if (event === 'SIGNED_OUT') { + router.push('/login'); // Redirect to login page after logout + } + }); + + // Cleanup on component unmount + return () => { + authListener.subscription.unsubscribe(); + }; + }, [router]); return (
@@ -31,9 +59,7 @@ const Login: React.FC = () => { Sign in to your account -
+ { }; export default Login; -