From 969e101d210921440cb749d9128feb3950054a98 Mon Sep 17 00:00:00 2001 From: Gib Date: Fri, 30 May 2025 11:19:22 -0500 Subject: [PATCH] We finally fixed the sign in and sign out stuff with our client components not updating --- src/app/(auth-pages)/profile/page.tsx | 11 +++- src/app/(auth-pages)/sign-in/page.tsx | 36 +++++++++--- src/components/context/auth.tsx | 39 ++++++++----- .../navigation/auth/AvatarDropdown.tsx | 10 +++- src/lib/actions/auth.ts | 57 +++++++------------ 5 files changed, 89 insertions(+), 64 deletions(-) diff --git a/src/app/(auth-pages)/profile/page.tsx b/src/app/(auth-pages)/profile/page.tsx index 748bb1f..094a11a 100644 --- a/src/app/(auth-pages)/profile/page.tsx +++ b/src/app/(auth-pages)/profile/page.tsx @@ -49,9 +49,14 @@ const ProfilePage = () => { confirmPassword: string; }) => { try { - await resetPassword(values); - } catch { - toast.error('Error resetting password!: '); + const result = await resetPassword(values); + if (!result.success) { + toast.error(`Error resetting password: ${result.error}`) + } + } catch (error) { + toast.error( + `Error resetting password!: ${error as string ?? 'Unknown error'}` + ); } } diff --git a/src/app/(auth-pages)/sign-in/page.tsx b/src/app/(auth-pages)/sign-in/page.tsx index 44e5be2..b0c9df0 100644 --- a/src/app/(auth-pages)/sign-in/page.tsx +++ b/src/app/(auth-pages)/sign-in/page.tsx @@ -1,13 +1,31 @@ +'use client'; import Link from 'next/link'; -import { getUser, signIn } from '@/lib/actions'; -import { FormMessage, type Message, SubmitButton } from '@/components/default'; +import { signIn } from '@/lib/actions'; +import { SubmitButton } from '@/components/default'; import { Input, Label } from '@/components/ui'; -import { redirect } from 'next/navigation'; +import { useRouter } from 'next/navigation'; +import { useAuth } from '@/components/context/auth'; +import { useEffect } from 'react'; + +const Login = () => { + const router = useRouter(); + const { isAuthenticated, refreshUserData } = useAuth(); + + // Redirect if already authenticated + useEffect(() => { + if (isAuthenticated) { + router.push('/'); + } + }, [isAuthenticated, router]); + + const handleSignIn = async (formData: FormData) => { + const result = await signIn(formData); + if (result?.success) { + await refreshUserData(); + router.push('/'); + } + }; -const Login = async (props: { searchParams: Promise }) => { - const searchParams = await props.searchParams; - const user = await getUser(); - if (user.success) redirect('/profile'); return (

Sign in

@@ -35,12 +53,12 @@ const Login = async (props: { searchParams: Promise }) => { placeholder='Your password' required /> - + Sign in - ); }; + export default Login; diff --git a/src/components/context/auth.tsx b/src/components/context/auth.tsx index 018a2a7..1b44a7f 100644 --- a/src/components/context/auth.tsx +++ b/src/components/context/auth.tsx @@ -1,8 +1,23 @@ 'use client'; -import React, { createContext, useContext, useState, useEffect, type ReactNode } from 'react'; -import { getUser, getProfile, updateProfile as updateProfileAction, getSignedUrl } from '@/lib/actions'; -import { type User, type Profile, createClient } from '@/utils/supabase'; +import React, { + type ReactNode, + createContext, + useContext, + useEffect, + useState, +} from 'react'; +import { + getProfile, + getSignedUrl, + getUser, + updateProfile as updateProfileAction, +} from '@/lib/actions'; +import { + type User, + type Profile, + createClient, +} from '@/utils/supabase'; import { toast } from 'sonner'; type AuthContextType = { @@ -41,30 +56,29 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { } setUser(userResponse.data); - + // Get profile data const profileResponse = await getProfile(); + if (!profileResponse.success) { setProfile(null); setAvatarUrl(null); return; } - + setProfile(profileResponse.data); - + // Get avatar URL if available if (profileResponse.data.avatar_url) { const avatarResponse = await getSignedUrl({ bucket: 'avatars', url: profileResponse.data.avatar_url, }); - if (avatarResponse.success) { setAvatarUrl(avatarResponse.data); } } } catch (error) { - console.error('Error fetching user data:', error); toast.error('Failed to load user data'); } finally { setIsLoading(false); @@ -73,8 +87,9 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { useEffect(() => { const supabase = createClient(); + fetchUserData().catch((error) => { - console.error('Error fetching user data:', error); + console.error('💥 Initial fetch error:', error); }); const { @@ -90,13 +105,8 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { } }); - const intervalId = setInterval(() => { - void fetchUserData(); - }, 1 * 60 * 1000); - return () => { subscription.unsubscribe(); - clearInterval(intervalId); }; }, []); @@ -140,6 +150,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { }; const refreshUserData = async () => { + console.log('Manual refresh triggered'); await fetchUserData(); }; diff --git a/src/components/default/navigation/auth/AvatarDropdown.tsx b/src/components/default/navigation/auth/AvatarDropdown.tsx index b0484c1..abf4d90 100644 --- a/src/components/default/navigation/auth/AvatarDropdown.tsx +++ b/src/components/default/navigation/auth/AvatarDropdown.tsx @@ -13,14 +13,20 @@ import { DropdownMenuTrigger, } from '@/components/ui'; import { useAuth } from '@/components/context/auth'; +import { useRouter } from 'next/navigation'; import { signOut } from '@/lib/actions'; import { User } from 'lucide-react'; const AvatarDropdown = () => { - const { profile, avatarUrl, isLoading } = useAuth(); + const { profile, avatarUrl, isLoading, refreshUserData } = useAuth(); + const router = useRouter(); const handleSignOut = async () => { - await signOut(); + const result = await signOut(); + if (result?.success) { + await refreshUserData(); + router.push('/sign-in'); + } }; const getInitials = (name: string | null | undefined): string => { diff --git a/src/lib/actions/auth.ts b/src/lib/actions/auth.ts index 4498bb7..dce5593 100644 --- a/src/lib/actions/auth.ts +++ b/src/lib/actions/auth.ts @@ -7,7 +7,6 @@ import { headers } from 'next/headers'; import { redirect } from 'next/navigation'; import type { User } from '@/utils/supabase'; import type { Result } from './index'; -import { revalidatePath } from 'next/cache'; export const signUp = async (formData: FormData) => { const name = formData.get('name') as string; @@ -47,7 +46,9 @@ export const signUp = async (formData: FormData) => { } }; -export const signIn = async (formData: FormData) => { +export const signIn = async ( + formData: FormData, +): Promise> => { const email = formData.get('email') as string; const password = formData.get('password') as string; const supabase = await createServerClient(); @@ -56,11 +57,10 @@ export const signIn = async (formData: FormData) => { email, password, }); - if (error) { - return encodedRedirect('error', '/sign-in', error.message); + return { success: false, error: error.message }; } else { - return redirect('/'); + return { success: true, data: null }; } }; @@ -98,43 +98,27 @@ export const forgotPassword = async (formData: FormData) => { }; -export const resetPassword = async ( - formData: FormData | {password: string, confirmPassword: string} -) => { - let password = ''; - let confirmPassword = ''; - - if (formData instanceof FormData) { - password = formData.get('password') as string; - confirmPassword = formData.get('confirmPassword') as string; - } else { - password = formData.password; - confirmPassword = formData.confirmPassword; - } - +export const resetPassword = async ({ + password, + confirmPassword, +}: { + password: string, + confirmPassword: string +}): Promise> => { if (!password || !confirmPassword) { - encodedRedirect( - 'error', - '/reset-password', - 'Password and confirm password are required', - ); + return { success: false, error: 'Password and confirm password are required!' }; } - const supabase = await createServerClient(); - if (password !== confirmPassword) { - encodedRedirect('error', '/reset-password', 'Passwords do not match'); + return { success: false, error: 'Passwords do not match!' }; } - const { error } = await supabase.auth.updateUser({ - password: password, + password, }); - if (error) { - encodedRedirect('error', '/reset-password', 'Password update failed'); + return { success: false, error: `Password update failed: ${error.message}` }; } - - encodedRedirect('success', '/reset-password', 'Password updated'); + return { success: true, data: null }; }; @@ -165,10 +149,11 @@ export const resetPasswordFromEmail = async (formData: FormData) => { encodedRedirect('success', '/reset-password', 'Password updated'); }; -export const signOut = async () => { +export const signOut = async (): Promise> => { const supabase = await createServerClient(); - await supabase.auth.signOut(); - return redirect('/sign-in'); + const { error } = await supabase.auth.signOut(); + if (error) return { success: false, error: error.message } + return { success: true, data: null }; }; export const getUser = async (): Promise> => {