From fefe7e87170b0f25762978aa0ef6359e2302daed Mon Sep 17 00:00:00 2001 From: Gib Date: Thu, 17 Jul 2025 15:20:59 -0500 Subject: [PATCH] Refactor & clean up code. --- bun.lockb | Bin 379332 -> 382376 bytes package.json | 20 +-- src/app/(auth)/auth/success/page.tsx | 13 +- src/app/(auth)/forgot-password/layout.tsx | 14 ++ src/app/(auth)/forgot-password/page.tsx | 11 ++ src/app/(auth)/profile/layout.tsx | 14 ++ src/app/(auth)/profile/page.tsx | 9 ++ src/app/layout.tsx | 15 +- src/app/page.tsx | 11 +- .../buttons/client/sign-in-with-apple.tsx | 4 +- .../buttons/client/sign-in-with-microsoft.tsx | 4 +- .../default/auth/buttons/client/sign-out.tsx | 7 +- .../default/auth/buttons/server/sign-out.tsx | 45 ++++++ .../auth/cards/client/forgot-password.tsx | 5 +- .../default/auth/cards/client/index.tsx | 2 + .../default/auth/cards/client/sign-in.tsx | 88 +++++++----- .../forms/client/profile/avatar-upload.tsx | 17 ++- .../default/layout/header/avatar-dropdown.tsx | 10 +- .../default/layout/header/index.tsx | 98 +++++++------ src/lib/hooks/context/index.tsx | 2 +- src/lib/hooks/context/use-auth.tsx | 136 +++++++----------- src/lib/hooks/context/use-query.tsx | 5 +- src/lib/hooks/context/use-theme.tsx | 2 +- src/lib/hooks/use-file-upload.ts | 90 +++++++----- src/lib/queries/auth.ts | 55 +++---- src/lib/queries/index.ts | 4 +- src/lib/queries/storage.ts | 44 +++++- src/utils/supabase/client.ts | 14 +- src/utils/supabase/index.ts | 4 +- src/utils/supabase/server.ts | 9 +- src/utils/supabase/types.ts | 16 ++- 31 files changed, 473 insertions(+), 295 deletions(-) create mode 100644 src/app/(auth)/forgot-password/layout.tsx create mode 100644 src/app/(auth)/forgot-password/page.tsx create mode 100644 src/app/(auth)/profile/layout.tsx create mode 100644 src/app/(auth)/profile/page.tsx create mode 100644 src/components/default/auth/cards/client/index.tsx mode change 100644 => 100755 src/components/default/auth/forms/client/profile/avatar-upload.tsx mode change 100644 => 100755 src/lib/queries/storage.ts diff --git a/bun.lockb b/bun.lockb index f7124023b7ff4e09c49e8b730031e4d153f88513..fdccb78c2e2272390a23f9845c4676858998bd9e 100755 GIT binary patch delta 81392 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 D)v2(y diff --git a/package.json b/package.json index 6745fb8..4738558 100644 --- a/package.json +++ b/package.json @@ -48,12 +48,13 @@ "@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-tooltip": "^1.2.7", - "@sentry/nextjs": "^9.36.0", + "@sentry/nextjs": "^9.40.0", "@supabase-cache-helpers/postgrest-react-query": "^1.13.4", + "@supabase-cache-helpers/storage-react-query": "^1.3.5", "@supabase/ssr": "^0.6.1", - "@supabase/supabase-js": "^2.50.4", + "@supabase/supabase-js": "^2.51.0", "@t3-oss/env-nextjs": "^0.12.0", - "@tanstack/react-query": "^5.82.0", + "@tanstack/react-query": "^5.83.0", "@tanstack/react-table": "^8.21.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -64,7 +65,7 @@ "import-in-the-middle": "^1.14.2", "input-otp": "^1.4.2", "lucide-react": "^0.522.0", - "next": "^15.3.5", + "next": "^15.4.1", "next-plausible": "^3.12.4", "next-themes": "^0.4.6", "postgres": "^3.4.7", @@ -85,12 +86,12 @@ "@tailwindcss/postcss": "^4.1.11", "@types/cors": "^2.8.19", "@types/express": "^5.0.3", - "@types/node": "^20.19.6", + "@types/node": "^20.19.8", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", "drizzle-kit": "^0.30.6", - "eslint": "^9.30.1", - "eslint-config-next": "^15.3.5", + "eslint": "^9.31.0", + "eslint-config-next": "^15.4.1", "eslint-config-prettier": "^10.1.5", "eslint-plugin-drizzle": "^0.2.3", "eslint-plugin-prettier": "^5.5.1", @@ -100,7 +101,7 @@ "tailwindcss": "^4.1.11", "tw-animate-css": "^1.3.5", "typescript": "^5.8.3", - "typescript-eslint": "^8.36.0" + "typescript-eslint": "^8.37.0" }, "ct3aMetadata": { "initVersion": "7.39.3" @@ -108,6 +109,9 @@ "trustedDependencies": [ "@sentry/cli", "@tailwindcss/oxide", + "core-js-pure", + "esbuild", + "sharp", "unrs-resolver" ] } diff --git a/src/app/(auth)/auth/success/page.tsx b/src/app/(auth)/auth/success/page.tsx index c98dc2d..a18dad1 100644 --- a/src/app/(auth)/auth/success/page.tsx +++ b/src/app/(auth)/auth/success/page.tsx @@ -11,21 +11,14 @@ const AuthSuccessPage = () => { useEffect(() => { const handleAuthSuccess = async () => { - // Refresh the auth context to pick up the new session await refreshUser(); - // Small delay to ensure state is updated - setTimeout(() => { - router.push('/'); - }, 100); + setTimeout(() => router.push('/'), 100); }; - - handleAuthSuccess().catch((error) => { - console.error(`Error: ${error instanceof Error ? error.message : error}`); - }); + handleAuthSuccess() + .catch(error => console.error(`Error handling auth success: ${error}`)); }, [refreshUser, router]); - // Show loading while processing return (
diff --git a/src/app/(auth)/forgot-password/layout.tsx b/src/app/(auth)/forgot-password/layout.tsx new file mode 100644 index 0000000..55cd61c --- /dev/null +++ b/src/app/(auth)/forgot-password/layout.tsx @@ -0,0 +1,14 @@ +import type { Metadata } from 'next'; + +export const generateMetadata = (): Metadata => { + return { + title: 'Forgot Password', + }; +}; + +const ForgotPasswordLayout = ({ + children, +}: Readonly<{ children: React.ReactNode }>) => { + return <>{children}; +}; +export default ForgotPasswordLayout; diff --git a/src/app/(auth)/forgot-password/page.tsx b/src/app/(auth)/forgot-password/page.tsx new file mode 100644 index 0000000..35d1646 --- /dev/null +++ b/src/app/(auth)/forgot-password/page.tsx @@ -0,0 +1,11 @@ +'use client'; +import { ForgotPasswordCard } from '@/components/default/auth/cards/client'; + +const ForgotPasswordPage = () => { + return ( +
+ +
+ ); +}; +export default ForgotPasswordPage; diff --git a/src/app/(auth)/profile/layout.tsx b/src/app/(auth)/profile/layout.tsx new file mode 100644 index 0000000..09e67d4 --- /dev/null +++ b/src/app/(auth)/profile/layout.tsx @@ -0,0 +1,14 @@ +import type { Metadata } from 'next'; + +export const generateMetadata = (): Metadata => { + return { + title: 'Profile', + }; +}; + +const ProfileLayout = ({ + children, +}: Readonly<{ children: React.ReactNode }>) => { + return <>{children}; +}; +export default ProfileLayout; diff --git a/src/app/(auth)/profile/page.tsx b/src/app/(auth)/profile/page.tsx new file mode 100644 index 0000000..c80e708 --- /dev/null +++ b/src/app/(auth)/profile/page.tsx @@ -0,0 +1,9 @@ +'use client'; + +const ProfilePage = () => { + return ( +
+
+ ); +}; +export default ProfilePage; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 39e20f5..7d0164f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -12,6 +12,8 @@ import PlausibleProvider from 'next-plausible'; import { Toaster } from '@/components/ui'; import * as Sentry from '@sentry/nextjs'; import Header from '@/components/default/layout/header'; +import { SupabaseServer } from '@/utils/supabase'; +import { getCurrentUser } from '@/lib/queries'; export const generateMetadata = (): Metadata => { return { @@ -211,9 +213,11 @@ const fontSans = Inter({ variable: '--font-sans', }); -export default function RootLayout({ +const RootLayout = async ({ children, -}: Readonly<{ children: React.ReactNode }>) { +}: Readonly<{ children: React.ReactNode }>) => { + const client = await SupabaseServer(); + const { data: { user } } = await getCurrentUser(client); return ( - +
- {children} +
+ {children} +
@@ -248,3 +254,4 @@ export default function RootLayout({ ); }; +export default RootLayout; diff --git a/src/app/page.tsx b/src/app/page.tsx index 860807f..b354cf8 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,9 +1,10 @@ -import { SignInCard } from '@/components/default/auth/cards/client/sign-in'; +import { SignInCard } from '@/components/default/auth/cards/client'; -export default function HomePage() { +const HomePage = () => { return ( -
+
-
+
); -} +}; +export default HomePage; diff --git a/src/components/default/auth/buttons/client/sign-in-with-apple.tsx b/src/components/default/auth/buttons/client/sign-in-with-apple.tsx index c43b96f..b99dff7 100644 --- a/src/components/default/auth/buttons/client/sign-in-with-apple.tsx +++ b/src/components/default/auth/buttons/client/sign-in-with-apple.tsx @@ -8,7 +8,7 @@ import { import { useAuth } from '@/lib/hooks/context'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; -import { useSupabaseClient } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { FaApple } from 'react-icons/fa'; import { type ComponentProps } from 'react'; import { cn } from '@/lib/utils'; @@ -30,7 +30,7 @@ export const SignInWithApple = ({ const { loading, refreshUser } = useAuth(); const [statusMessage, setStatusMessage] = useState(''); const [ isLoading, setIsLoading ] = useState(false); - const supabase = useSupabaseClient(); + const supabase = SupabaseClient()!; const handleSignInWithApple = async (e: React.FormEvent) => { e.preventDefault(); diff --git a/src/components/default/auth/buttons/client/sign-in-with-microsoft.tsx b/src/components/default/auth/buttons/client/sign-in-with-microsoft.tsx index 2aafc43..7fab135 100644 --- a/src/components/default/auth/buttons/client/sign-in-with-microsoft.tsx +++ b/src/components/default/auth/buttons/client/sign-in-with-microsoft.tsx @@ -8,7 +8,7 @@ import { import { useAuth } from '@/lib/hooks/context'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; -import { useSupabaseClient } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { FaMicrosoft } from 'react-icons/fa'; import { type ComponentProps } from 'react'; import { cn } from '@/lib/utils'; @@ -30,7 +30,7 @@ export const SignInWithMicrosoft = ({ const { loading, refreshUser } = useAuth(); const [statusMessage, setStatusMessage] = useState(''); const [ isLoading, setIsLoading ] = useState(false); - const supabase = useSupabaseClient(); + const supabase = SupabaseClient()!; const handleSignInWithMicrosoft = async (e: React.FormEvent) => { e.preventDefault(); diff --git a/src/components/default/auth/buttons/client/sign-out.tsx b/src/components/default/auth/buttons/client/sign-out.tsx index 04dd2aa..802b525 100644 --- a/src/components/default/auth/buttons/client/sign-out.tsx +++ b/src/components/default/auth/buttons/client/sign-out.tsx @@ -3,7 +3,7 @@ import { SubmitButton, type SubmitButtonProps } from '@/components/default/forms import { useRouter } from 'next/navigation'; import { useAuth } from '@/lib/hooks/context'; import { signOut } from '@/lib/queries'; -import { useSupabaseClient } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { cn } from '@/lib/utils'; type SignOutProps = Omit @@ -13,8 +13,7 @@ export const SignOut = ({ pendingText = 'Signing out...', ...props }: SignOutProps) => { - - const supabase = useSupabaseClient(); + const supabase = SupabaseClient()!; const { loading, refreshUser } = useAuth(); const router = useRouter(); @@ -24,7 +23,7 @@ export const SignOut = ({ const result = await signOut(supabase); if (result.error) throw new Error(result.error.message); await refreshUser(); - router.push('/sign-in'); + router.push('/'); } catch (error) { console.error(error); } diff --git a/src/components/default/auth/buttons/server/sign-out.tsx b/src/components/default/auth/buttons/server/sign-out.tsx index e69de29..0802e1e 100644 --- a/src/components/default/auth/buttons/server/sign-out.tsx +++ b/src/components/default/auth/buttons/server/sign-out.tsx @@ -0,0 +1,45 @@ +'use server'; +import 'server-only'; +import { redirect } from 'next/navigation'; +import { SubmitButton, type SubmitButtonProps } from '@/components/default/forms'; +import { signOut } from '@/lib/queries'; +import { SupabaseServer } from '@/utils/supabase'; +import { cn } from '@/lib/utils'; + +type SignOutProps = Omit + +export const SignOut = async ({ + className, + pendingText = 'Signing out...', + ...props +}: SignOutProps) => { + const handleSignOut = async () => { + try { + const supabase = await SupabaseServer(); + if (!supabase) throw new Error('Supabase client not found'); + const result = await signOut(supabase); + if (result.error) throw new Error(result.error.message); + } catch (error) { + console.error(error); + //redirect('/global-error'); + } + redirect('/'); + }; + + return ( +
+ + Sign Out + +
+ ); +}; diff --git a/src/components/default/auth/cards/client/forgot-password.tsx b/src/components/default/auth/cards/client/forgot-password.tsx index 0f6f697..3c8e4df 100644 --- a/src/components/default/auth/cards/client/forgot-password.tsx +++ b/src/components/default/auth/cards/client/forgot-password.tsx @@ -21,7 +21,7 @@ import { forgotPassword } from '@/lib/queries'; import { useAuth } from '@/lib/hooks/context'; import { useEffect, useState, type ComponentProps } from 'react'; import { useRouter } from 'next/navigation'; -import { useSupabaseClient } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { StatusMessage, SubmitButton } from '@/components/default/forms'; import { cn } from '@/lib/utils'; @@ -55,7 +55,7 @@ export const ForgotPasswordCard = ({ const router = useRouter(); const { isAuthenticated, loading, refreshUser } = useAuth(); const [statusMessage, setStatusMessage] = useState(''); - const supabase = useSupabaseClient(); + const supabase = SupabaseClient()!; const form = useForm>({ resolver: zodResolver(forgotPasswordFormSchema), @@ -73,7 +73,6 @@ export const ForgotPasswordCard = ({ setStatusMessage(''); const formData = new FormData(); formData.append('email', values.email); - if (!supabase) throw new Error('Supabase client not found'); const result = await forgotPassword(supabase, formData); if (result.error) throw new Error(result.error.message); await refreshUser(); diff --git a/src/components/default/auth/cards/client/index.tsx b/src/components/default/auth/cards/client/index.tsx new file mode 100644 index 0000000..534acb4 --- /dev/null +++ b/src/components/default/auth/cards/client/index.tsx @@ -0,0 +1,2 @@ +export { ForgotPasswordCard } from './forgot-password'; +export { SignInCard } from './sign-in'; diff --git a/src/components/default/auth/cards/client/sign-in.tsx b/src/components/default/auth/cards/client/sign-in.tsx index c2c24bd..8a60317 100755 --- a/src/components/default/auth/cards/client/sign-in.tsx +++ b/src/components/default/auth/cards/client/sign-in.tsx @@ -7,7 +7,7 @@ import { signIn, signUp } from '@/lib/queries'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { useAuth } from '@/lib/hooks/context'; -import { useSupabaseClient } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { StatusMessage, SubmitButton } from '@/components/default/forms'; import { Card, @@ -93,7 +93,7 @@ export const SignInCard = ({ const router = useRouter(); const { isAuthenticated, loading, refreshUser } = useAuth(); const [statusMessage, setStatusMessage] = useState(''); - const supabase = useSupabaseClient(); + const supabase = SupabaseClient()!; const signInForm = useForm>({ resolver: zodResolver(signInFormSchema), @@ -283,14 +283,20 @@ export const SignInCard = ({ 'flex w-5/6 m-auto', signInWithMicrosoftProps?.submitButtonProps?.className), }} - textClassName={cn( - 'text-lg', - signInWithMicrosoftProps?.textClassName, - )} - iconClassName={cn( - 'size-6', - signInWithMicrosoftProps?.iconClassName, - )} + textProps={{ + ...signInWithMicrosoftProps?.textProps, + className: cn( + 'text-lg', + signInWithMicrosoftProps?.textProps?.className, + ), + }} + iconProps={{ + ...signInWithMicrosoftProps?.iconProps, + className: cn( + 'size-6', + signInWithMicrosoftProps?.iconProps?.className, + ), + }} /> @@ -444,14 +456,18 @@ export const SignInCard = ({ 'flex w-5/6 m-auto', signInWithMicrosoftProps?.submitButtonProps?.className), }} - textClassName={cn( - 'text-lg', - signInWithMicrosoftProps?.textClassName, - )} - iconClassName={cn( - 'size-6', - signInWithMicrosoftProps?.iconClassName, - )} + textProps={{ + className: cn( + 'text-lg', + signInWithMicrosoftProps?.textProps?.className, + ), + }} + iconProps={{ + className: cn( + 'size-6', + signInWithMicrosoftProps?.iconProps?.className, + ), + }} /> diff --git a/src/components/default/auth/forms/client/profile/avatar-upload.tsx b/src/components/default/auth/forms/client/profile/avatar-upload.tsx old mode 100644 new mode 100755 index 6e7812b..11d535b --- a/src/components/default/auth/forms/client/profile/avatar-upload.tsx +++ b/src/components/default/auth/forms/client/profile/avatar-upload.tsx @@ -1,7 +1,7 @@ 'use client'; import { useFileUpload } from '@/lib/hooks'; import { useAuth } from '@/lib/hooks/context'; -import { useSupabaseClient } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { BasedAvatar, Card, @@ -11,6 +11,7 @@ import { Loader2, Pencil, Upload } from 'lucide-react'; import type { ComponentProps, ChangeEvent } from 'react'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; +import { getAvatarUrl } from '@/lib/queries'; type AvatarUploadProps = { onAvatarUploaded: (path: string) => Promise; @@ -32,8 +33,12 @@ export const AvatarUpload = ({ }, }: AvatarUploadProps) => { const { profile, isAuthenticated } = useAuth(); - const { isUploading, fileInputRef, uploadAvatarMutation } = useFileUpload(); - const client = useSupabaseClient(); + const client = SupabaseClient()!; + const { + isUploading, + fileInputRef, + uploadAvatarMutation + } = useFileUpload(client, 'avatars'); const handleAvatarClick = () => { if (!isAuthenticated) { @@ -56,9 +61,7 @@ export const AvatarUpload = ({ `${profile?.id}.${file.name.split('.').pop()}`; const avatarUrl = await uploadAvatarMutation.mutateAsync({ - client, file, - bucket: 'avatars', resize: { maxWidth: 500, maxHeight: 500, @@ -91,7 +94,7 @@ export const AvatarUpload = ({ >
{ - const { profile, avatar, refreshUser } = useAuth(); + const { profile, refreshUser } = useAuth(); const router = useRouter(); - const client = useSupabaseClient(); + const client = SupabaseClient()!; const handleSignOut = async () => { try { - if (!client) throw new Error('Supabase client not found!'); const { error } = await signOut(client); if (error) throw new Error(error.message); await refreshUser(); @@ -36,7 +36,7 @@ export const AvatarDropdown = () => { { +type Props = { + headerProps?: ComponentProps<'header'>; + themeToggleProps?: ThemeToggleProps; +}; + +const Header = ({ + headerProps, + themeToggleProps, +}: Props) => { const { isAuthenticated } = useAuth(); const Controls = () => ( @@ -13,9 +22,10 @@ const Header = () => { {isAuthenticated && ( )} @@ -23,46 +33,50 @@ const Header = () => { ); return ( -
-
-
- - {/* Left spacer for perfect centering */} -
-
-
- - {/* Centered logo and title */} -
- - Tech Tracker Logo -

- Next Template -

- -
- - {/* Right-aligned controls */} -
- -
+
+
+ {/* Left spacer for perfect centering */} +
+
+ + {/* Centered logo and title */} +
+ + Tech Tracker Logo +

+ Next Template +

+ +
+ + {/* Right-aligned controls */} +
+ +
+
); diff --git a/src/lib/hooks/context/index.tsx b/src/lib/hooks/context/index.tsx index 474d9dc..3f951a2 100644 --- a/src/lib/hooks/context/index.tsx +++ b/src/lib/hooks/context/index.tsx @@ -1,5 +1,5 @@ export { AuthContextProvider, useAuth } from './use-auth'; export { useIsMobile } from './use-mobile'; export { QueryClientProvider, QueryErrorCodes } from './use-query'; -export { ThemeProvider, ThemeToggle } from './use-theme'; +export { ThemeProvider, ThemeToggle, type ThemeToggleProps } from './use-theme'; export { TVModeProvider, useTVMode, TVToggle } from './use-tv-mode'; diff --git a/src/lib/hooks/context/use-auth.tsx b/src/lib/hooks/context/use-auth.tsx index 0fd58cc..86a3dd2 100755 --- a/src/lib/hooks/context/use-auth.tsx +++ b/src/lib/hooks/context/use-auth.tsx @@ -1,92 +1,73 @@ 'use client'; import React, { - type ReactNode, createContext, useContext, useEffect, + useState } from 'react'; -import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useQuery as useSupabaseQuery, useUpdateMutation, } from '@supabase-cache-helpers/postgrest-react-query'; -import { QueryErrorCodes } from '@/lib/hooks/context'; -import { type User, type Profile, useSupabaseClient } from '@/utils/supabase'; +import { type User, type Profile } from '@/utils/supabase'; +import { SupabaseClient } from '@/utils/supabase'; import { toast } from 'sonner'; -import { - getAvatar, - getCurrentUser, - getProfile, - updateProfile as updateProfileQuery -} from '@/lib/queries'; type AuthContextType = { user: User | null; profile: Profile | null; - avatar: string | null; loading: boolean; isAuthenticated: boolean; - updateProfile: (data: { - full_name?: string; - email?: string; - avatar_url?: string; - provider?: string; - }) => Promise<{ data?: Profile | null; error?: { message: string } | null }>; + updateProfile: (data: Partial) => Promise; refreshUser: () => Promise; }; const AuthContext = createContext(undefined); -const AuthContextProvider = ({ children }: { children: ReactNode }) => { +export const AuthContextProvider = ({ + children, + initialUser, +}: { + children: React.ReactNode; + initialUser?: User | null; +}) => { const queryClient = useQueryClient(); - const supabase = useSupabaseClient(); - + const supabase = SupabaseClient(); if (!supabase) throw new Error('Supabase client not found!'); - // User query + // Initialize with server-side user data + const [user, setUser] = useState(initialUser ?? null); + + // User query with initial data const { data: userData, isLoading: userLoading, - error: userError, } = useQuery({ queryKey: ['auth', 'user'], queryFn: async () => { - const result = await getCurrentUser(supabase); - if (result.error) throw result.error; - return result.data.user as User | null; + const { data: { user } } = await supabase.auth.getUser(); + return user; }, - retry: false, - meta: { errCode: QueryErrorCodes.FETCH_USER_FAILED }, + initialData: initialUser, + staleTime: 5 * 60 * 1000, // 5 minutes }); - // Profile query + // Profile query using Supabase Cache Helpers const { data: profileData, isLoading: profileLoading, } = useSupabaseQuery( - getProfile(supabase, userData?.id ?? ''), + supabase + .from('profiles') + .select('*') + .eq('id', userData?.id ?? '') + .single(), { enabled: !!userData?.id, - meta: { errCode: QueryErrorCodes.FETCH_PROFILE_FAILED }, } ); - - // Avatar query - const { - data: avatarData, - } = useQuery({ - queryKey: ['auth', 'avatar', profileData?.avatar_url], - queryFn: async () => { - if (!profileData?.avatar_url) return null; - const result = await getAvatar(supabase, profileData.avatar_url); - if (result.error) throw result.error; - return result.data.signedUrl as string | null; - }, - enabled: !!profileData?.avatar_url, - meta: { errCode: QueryErrorCodes.FETCH_AVATAR_FAILED }, - }); - // Update profile mutation const updateProfileMutation = useUpdateMutation( supabase.from('profiles'), @@ -95,47 +76,31 @@ const AuthContextProvider = ({ children }: { children: ReactNode }) => { { onSuccess: () => toast.success('Profile updated successfully!'), onError: (error) => toast.error(`Failed to update profile: ${error.message}`), - meta: { errCode: QueryErrorCodes.UPDATE_PROFILE_FAILED }, - }, + } ); - //const updateProfileMutation = useMutation({ - //mutationFn: async (updates: Partial) => { - //if (!userData?.id) throw new Error('User ID is required!'); - //const result = await updateProfileQuery(supabase, userData.id, updates); - //if (result.error) throw result.error; - //return result.data; - //}, - //onSuccess: () => { - //queryClient.invalidateQueries({ queryKey: ['auth'] }) - //.catch((error) => console.error('Error invalidating auth queries:', error)); - //toast.success('Profile updated successfully!'); - //}, - //meta: { errCode: QueryErrorCodes.UPDATE_PROFILE_FAILED }, - //}); - + // Auth state listener useEffect(() => { - const { - data: { subscription }, - } = supabase.auth.onAuthStateChange(async (event, _session) => { - if (event === 'SIGNED_IN' || event === 'SIGNED_OUT' || event === 'TOKEN_REFRESHED') { - await queryClient.invalidateQueries({ queryKey: ['auth'] }); + const { data: { subscription } } = supabase.auth.onAuthStateChange( + async (event, session) => { + setUser(session?.user ?? null); + + if (event === 'SIGNED_IN' || event === 'SIGNED_OUT' || event === 'TOKEN_REFRESHED') { + await queryClient.invalidateQueries({ queryKey: ['auth'] }); + } } - }); + ); + return () => subscription.unsubscribe(); }, [supabase.auth, queryClient]); const handleUpdateProfile = async (data: Partial) => { if (!userData?.id) throw new Error('User ID is required!'); - try { - const result = await updateProfileMutation.mutateAsync({ - ...data, - id: userData.id, - }); - return { data: result, error: null }; - } catch (error) { - return { data: null, error }; - } + + await updateProfileMutation.mutateAsync({ + ...data, + id: userData.id, + }); }; const refreshUser = async () => { @@ -145,22 +110,23 @@ const AuthContextProvider = ({ children }: { children: ReactNode }) => { const value: AuthContextType = { user: userData ?? null, profile: profileData ?? null, - avatar: avatarData ?? null, loading: userLoading || profileLoading, - isAuthenticated: !!userData && !userError, + isAuthenticated: !!userData, updateProfile: handleUpdateProfile, refreshUser, }; - return {children}; + return ( + + {children} + + ); }; -const useAuth = () => { +export const useAuth = () => { const context = useContext(AuthContext); - if (!context || context === undefined) { + if (!context) { throw new Error('useAuth must be used within an AuthContextProvider'); } return context; }; - -export { AuthContextProvider, useAuth }; diff --git a/src/lib/hooks/context/use-query.tsx b/src/lib/hooks/context/use-query.tsx index 8226e47..e25fc1e 100644 --- a/src/lib/hooks/context/use-query.tsx +++ b/src/lib/hooks/context/use-query.tsx @@ -66,7 +66,10 @@ const QueryClientProvider = ({ children }: { children: React.ReactNode }) => { defaultOptions: { queries: { refetchOnWindowFocus: true, - staleTime: 60 * 1000, + // Supabase cache helpers recommends Infinity. + // React Query Recommends 1 minute. + staleTime: 10 * (60 * 1000), // We'll be in between with 10 minutes + gcTime: Infinity, }, }, }) diff --git a/src/lib/hooks/context/use-theme.tsx b/src/lib/hooks/context/use-theme.tsx index 1c32f58..ea37d15 100644 --- a/src/lib/hooks/context/use-theme.tsx +++ b/src/lib/hooks/context/use-theme.tsx @@ -71,4 +71,4 @@ const ThemeToggle = ({ ); }; -export { ThemeProvider, ThemeToggle }; +export { ThemeProvider, ThemeToggle, type ThemeToggleProps }; diff --git a/src/lib/hooks/use-file-upload.ts b/src/lib/hooks/use-file-upload.ts index 8019cb1..9543f03 100644 --- a/src/lib/hooks/use-file-upload.ts +++ b/src/lib/hooks/use-file-upload.ts @@ -1,77 +1,98 @@ 'use client'; -import { useState, useRef } from 'react'; +import { useState, useRef, useCallback } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { getSignedUrl, resizeImage, uploadFile } from '@/lib/queries'; +import { useUpload } from '@supabase-cache-helpers/storage-react-query'; +import { getSignedUrl, resizeImage } from '@/lib/queries'; import { useAuth, QueryErrorCodes } from '@/lib/hooks/context'; -import type { SupabaseClient, User, Profile } from '@/utils/supabase'; +import type { SBClientWithDatabase, User, Profile } from '@/utils/supabase'; import { toast } from 'sonner'; type UploadToStorageProps = { - client: SupabaseClient; + client: SBClientWithDatabase; file: File; bucket: string; resize?: false | { maxWidth?: number; maxHeight?: number; quality?: number; - }, - replace?: false | string, + }; + replace?: false | string; }; -const useFileUpload = () => { +const useFileUpload = (client: SBClientWithDatabase, bucket: string) => { const [isUploading, setIsUploading] = useState(false); const fileInputRef = useRef(null); const { profile, isAuthenticated } = useAuth(); const queryClient = useQueryClient(); - const uploadToStorage = async ({ - client, + // Initialize the upload hook at the top level + const { mutateAsync: upload } = useUpload( + client.storage.from(bucket), + { + buildFileName: ({ fileName, path }) => path ?? fileName, + } + ); + + const uploadToStorage = useCallback(async ({ file, - bucket, resize = false, replace = false, - }: UploadToStorageProps) => { + }: Omit) => { try { if (!isAuthenticated) throw new Error('Error: User is not authenticated!'); + setIsUploading(true); + let fileToUpload = file; if (resize && file.type.startsWith('image/')) - fileToUpload = await resizeImage({file, options: resize}); - const path = replace || `${Date.now()}-${profile?.id}.${file.name.split('.').pop()}`; - const { data, error} = await uploadFile({ - client, - bucket, - path, - file: fileToUpload, - options: { - contentType: file.type, - ...(replace && {upsert: true}) - }, + fileToUpload = await resizeImage({ file, options: resize }); + + const fileName = replace || `${Date.now()}-${profile?.id}.${file.name.split('.').pop()}`; + + // Create a file object with the custom path + const fileWithPath = Object.assign(fileToUpload, { + webkitRelativePath: fileName, }); - if (error) throw new Error(`Error uploading file: ${error.message}`); + + const uploadResult = await upload({ files: [fileWithPath]}); + + if (!uploadResult || uploadResult.length === 0) { + throw new Error('Upload failed: No result returned'); + } + + const uploadedFile = uploadResult[0]; + if (!uploadedFile || uploadedFile.error) { + throw new Error(`Error uploading file: ${uploadedFile?.error.message ?? 'No uploaded file'}`); + } + + // Get signed URL for the uploaded file const { data: urlData, error: urlError } = await getSignedUrl({ client, bucket, - path: data.path, + path: uploadedFile.data.path, }); - if (urlError) throw new Error(`Error getting signed URL: ${urlError.message}`); - return {urlData, error: null}; + + if (urlError) { + throw new Error(`Error getting signed URL: ${urlError.message}`); + } + + return { urlData, error: null }; } catch (error) { return { data: null, error }; } finally { setIsUploading(false); if (fileInputRef.current) fileInputRef.current.value = ''; } - }; + }, [client, bucket, upload, isAuthenticated, profile?.id]); const uploadMutation = useMutation({ mutationFn: uploadToStorage, onSuccess: (result) => { if (result.error) { - toast.error(`Upload failed: ${result.error as string}`) + toast.error(`Upload failed: ${result.error as string}`); } else { - toast.success(`File uploaded successfully!`); + toast.success('File uploaded successfully!'); } }, onError: (error) => { @@ -81,15 +102,15 @@ const useFileUpload = () => { }); const uploadAvatarMutation = useMutation({ - mutationFn: async (props: UploadToStorageProps) => { + mutationFn: async (props: Omit) => { const { data, error } = await uploadToStorage(props); if (error) throw new Error(`Error uploading avatar: ${error as string}`); return data; }, onSuccess: (avatarUrl) => { - queryClient.invalidateQueries({ queryKey: ['auth'] }); + queryClient.invalidateQueries({ queryKey: ['auth'] }) + .catch((error) => console.error('Error invalidating auth query:', error)); queryClient.setQueryData(['auth, user'], (oldUser: User) => oldUser); - if (profile?.id) { queryClient.setQueryData(['profiles', profile.id], (oldProfile: Profile) => ({ ...oldProfile, @@ -97,14 +118,13 @@ const useFileUpload = () => { updated_at: new Date().toISOString(), })); } - toast.success('Avatar uploaded sucessfully!'); + toast.success('Avatar uploaded successfully!'); }, onError: (error) => { toast.error(`Avatar upload failed: ${error instanceof Error ? error.message : error}`); }, meta: { errCode: QueryErrorCodes.UPLOAD_PHOTO_FAILED }, - }) - + }); return { isUploading: isUploading || uploadMutation.isPending || uploadAvatarMutation.isPending, diff --git a/src/lib/queries/auth.ts b/src/lib/queries/auth.ts index 96c5413..b56d9a4 100644 --- a/src/lib/queries/auth.ts +++ b/src/lib/queries/auth.ts @@ -1,7 +1,6 @@ -import { type SupabaseClient, type Profile } from '@/utils/supabase'; -import { getSignedUrl } from '@/lib/queries'; +import { type Profile, type SBClientWithDatabase, type UserRecord } from '@/utils/supabase'; -const signUp = (client: SupabaseClient, formData: FormData) => { +const signUp = (client: SBClientWithDatabase, formData: FormData) => { const full_name = formData.get('name') as string; const email = formData.get('email') as string; const password = formData.get('password') as string; @@ -20,13 +19,13 @@ const signUp = (client: SupabaseClient, formData: FormData) => { }); }; -const signIn = (client: SupabaseClient, formData: FormData) => { +const signIn = (client: SBClientWithDatabase, formData: FormData) => { const email = formData.get('email') as string; const password = formData.get('password') as string; return client.auth.signInWithPassword({ email, password }); }; -const signInWithMicrosoft = (client: SupabaseClient) => { +const signInWithMicrosoft = (client: SBClientWithDatabase) => { const origin = process.env.NEXT_PUBLIC_SITE_URL!; return client.auth.signInWithOAuth({ provider: 'azure', @@ -37,7 +36,7 @@ const signInWithMicrosoft = (client: SupabaseClient) => { }); }; -const signInWithApple = (client: SupabaseClient) => { +const signInWithApple = (client: SBClientWithDatabase) => { const origin = process.env.NEXT_PUBLIC_SITE_URL!; return client.auth.signInWithOAuth({ provider: 'apple', @@ -48,7 +47,7 @@ const signInWithApple = (client: SupabaseClient) => { }); }; -const forgotPassword = (client: SupabaseClient, formData: FormData) => { +const forgotPassword = (client: SBClientWithDatabase, formData: FormData) => { const email = formData.get('email') as string; const origin = process.env.NEXT_PUBLIC_SITE_URL!; return client.auth.resetPasswordForEmail(email, { @@ -56,20 +55,20 @@ const forgotPassword = (client: SupabaseClient, formData: FormData) => { }); }; -const resetPassword = (client: SupabaseClient, formData: FormData) => { +const resetPassword = (client: SBClientWithDatabase, formData: FormData) => { const password = formData.get('password') as string; return client.auth.updateUser({ password }); }; -const signOut = (client: SupabaseClient) => { +const signOut = (client: SBClientWithDatabase) => { return client.auth.signOut(); } -const getCurrentUser = (client: SupabaseClient) => { +const getCurrentUser = (client: SBClientWithDatabase) => { return client.auth.getUser(); }; -const getProfile = (client: SupabaseClient, userId: string) => { +const getProfile = (client: SBClientWithDatabase, userId: string) => { return client .from(`profiles`) .select(`*`) @@ -77,21 +76,29 @@ const getProfile = (client: SupabaseClient, userId: string) => { .single(); }; -const getAvatar = (client: SupabaseClient, avatarUrl: string) => { - return getSignedUrl({ - client, - bucket: 'avatars', - path: avatarUrl, - seconds: 3600, - transform: { - width: 128, - height: 128, - }, - }); +const getUserWithStatus = (client: SBClientWithDatabase, userId: string) => { + return client + .from(`profiles`) + .select(` + id, + updated_at, + email, + full_name, + avatar_url, + provider, + status:statuses!current_status_id( + text:status, + created_at, + updated_by:profiles!updated_by_id(*) + ) + `) + .eq(`id`, userId) + .throwOnError() + .single(); }; const updateProfile = ( - client: SupabaseClient, + client: SBClientWithDatabase, userId: string, updates: Partial, ) => { @@ -108,7 +115,7 @@ export { forgotPassword, getCurrentUser, getProfile, - getAvatar, + getUserWithStatus, resetPassword, signIn, signInWithApple, diff --git a/src/lib/queries/index.ts b/src/lib/queries/index.ts index 9d95d0f..077a9f6 100644 --- a/src/lib/queries/index.ts +++ b/src/lib/queries/index.ts @@ -2,7 +2,7 @@ export { forgotPassword, getCurrentUser, getProfile, - getAvatar, + getUserWithStatus, resetPassword, signIn, signInWithApple, @@ -13,7 +13,9 @@ export { } from './auth'; export { deleteFiles, + getAvatarUrl, getPublicUrl, + getSignedAvatarUrl, getSignedUrl, listFiles, resizeImage, diff --git a/src/lib/queries/storage.ts b/src/lib/queries/storage.ts old mode 100644 new mode 100755 index 96b36fc..658f575 --- a/src/lib/queries/storage.ts +++ b/src/lib/queries/storage.ts @@ -1,7 +1,7 @@ -import { type SupabaseClient, type Profile } from '@/utils/supabase'; +import { type SBClientWithDatabase } from '@/utils/supabase'; type GetStorageProps = { - client: SupabaseClient; + client: SBClientWithDatabase; bucket: string; path: string; seconds?: number; @@ -16,7 +16,7 @@ type GetStorageProps = { }; type UploadStorageProps = { - client: SupabaseClient; + client: SBClientWithDatabase; bucket: string; path: string; file: File; @@ -36,6 +36,22 @@ type ResizeImageProps = { }; }; +const getAvatarUrl = ( + client: SBClientWithDatabase, + path: string, +) => { + return getPublicUrl({ + client, + bucket: 'avatars', + path, + transform: { + width: 128, + height: 128, + quality: 0.8, + } + }).data.publicUrl; +}; + const getPublicUrl = ({ client, bucket, @@ -48,6 +64,22 @@ const getPublicUrl = ({ .getPublicUrl(path, { download, transform}); }; +const getSignedAvatarUrl = ( + client: SBClientWithDatabase, + avatarUrl: string +) => { + return getSignedUrl({ + client, + bucket: 'avatars', + path: avatarUrl, + seconds: 3600, + transform: { + width: 128, + height: 128, + }, + }); +}; + const getSignedUrl = ({ client, bucket, @@ -92,7 +124,7 @@ const deleteFiles = ({ bucket, path, }: { - client: SupabaseClient; + client: SBClientWithDatabase; bucket: string; path: string[]; }) => { @@ -105,7 +137,7 @@ const listFiles = ({ path = '', options = {}, }: { - client: SupabaseClient; + client: SBClientWithDatabase; bucket: string; path?: string; options?: { @@ -169,7 +201,9 @@ const resizeImage = async ({ export { deleteFiles, + getAvatarUrl, getPublicUrl, + getSignedAvatarUrl, getSignedUrl, listFiles, resizeImage, diff --git a/src/utils/supabase/client.ts b/src/utils/supabase/client.ts index 09b1b47..f01dc5e 100644 --- a/src/utils/supabase/client.ts +++ b/src/utils/supabase/client.ts @@ -1,12 +1,10 @@ 'use client'; - import { createBrowserClient } from '@supabase/ssr'; -import type { Database, SupabaseClient } from '@/utils/supabase'; -import { useMemo } from 'react'; +import type { Database, SBClientWithDatabase } from '@/utils/supabase'; -let client: SupabaseClient | undefined; +let client: SBClientWithDatabase | undefined; -const getSupbaseClient = (): SupabaseClient | undefined => { +const getSupbaseClient = (): SBClientWithDatabase | undefined => { if (client) return client; client = createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, @@ -15,8 +13,6 @@ const getSupbaseClient = (): SupabaseClient | undefined => { return client; }; -const useSupabaseClient = () => { - return useMemo(getSupbaseClient, []); -}; +const SupabaseClient = () => getSupbaseClient(); -export { useSupabaseClient }; +export { SupabaseClient }; diff --git a/src/utils/supabase/index.ts b/src/utils/supabase/index.ts index 189b3a3..12de9d4 100644 --- a/src/utils/supabase/index.ts +++ b/src/utils/supabase/index.ts @@ -1,5 +1,5 @@ -export { useSupabaseClient } from './client'; -export { updateSession } from './middleware'; +export { SupabaseClient } from './client'; export { SupabaseServer } from './server'; +export { updateSession } from './middleware'; export type { Database } from './database.types'; export type * from './types'; diff --git a/src/utils/supabase/server.ts b/src/utils/supabase/server.ts index 24fd6f2..c713782 100644 --- a/src/utils/supabase/server.ts +++ b/src/utils/supabase/server.ts @@ -1,11 +1,10 @@ 'use server'; - import 'server-only'; import { createServerClient } from '@supabase/ssr'; -import type { Database } from '@/utils/supabase'; +import type { Database, SBClientWithDatabase } from '@/utils/supabase'; import { cookies } from 'next/headers'; -export const SupabaseServer = async () => { +const SupabaseServer = async () => { const cookieStore = await cookies(); return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, @@ -26,5 +25,7 @@ export const SupabaseServer = async () => { }, }, }, - ); + ) as SBClientWithDatabase; }; + +export { SupabaseServer }; diff --git a/src/utils/supabase/types.ts b/src/utils/supabase/types.ts index ab07c50..2dc08cc 100644 --- a/src/utils/supabase/types.ts +++ b/src/utils/supabase/types.ts @@ -1,7 +1,7 @@ import type { Database } from '@/utils/supabase/database.types'; import type { SupabaseClient as SBClient } from '@supabase/supabase-js' -export type SupabaseClient = SBClient; +export type SBClientWithDatabase = SBClient; export type { User } from '@supabase/supabase-js'; @@ -10,6 +10,20 @@ export type Result = { error: { message: string } | null; }; +export type UserRecord = { + id: string, + updated_at: string | null, + email: string | null, + full_name: string | null, + avatar_url: string | null, + provider: string | null, + status: { + status: string, + created_at: string, + updated_by: Profile | null, + } +}; + export type AsyncReturnType Promise> = T extends (...args: any) => Promise ? R : never;