More stuff

This commit is contained in:
2025-07-09 11:54:01 -05:00
parent 2fbb259e62
commit 04f2a48727
16 changed files with 358 additions and 66 deletions

56
src/lib/hooks/context/use-auth.tsx Normal file → Executable file
View File

@@ -6,7 +6,10 @@ import React, {
useEffect,
} from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useQuery as useSupabaseQuery } from '@supabase-cache-helpers/postgrest-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 { toast } from 'sonner';
@@ -27,7 +30,8 @@ type AuthContextType = {
full_name?: string;
email?: string;
avatar_url?: string;
}) => Promise<{ data?: Profile; error?: unknown }>;
provider?: string;
}) => Promise<{ data?: Profile | null; error?: { message: string } | null }>;
refreshUser: () => Promise<void>;
};
@@ -67,6 +71,7 @@ const AuthContextProvider = ({ children }: { children: ReactNode }) => {
}
);
// Avatar query
const {
data: avatarData,
@@ -83,20 +88,31 @@ const AuthContextProvider = ({ children }: { children: ReactNode }) => {
});
// Update profile mutation
const updateProfileMutation = useMutation({
mutationFn: async (updates: Partial<Profile>) => {
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;
const updateProfileMutation = useUpdateMutation(
supabase.from('profiles'),
['id'],
'*',
{
onSuccess: () => toast.success('Profile updated successfully!'),
onError: (error) => toast.error(`Failed to update profile: ${error.message}`),
meta: { errCode: QueryErrorCodes.UPDATE_PROFILE_FAILED },
},
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 },
});
);
//const updateProfileMutation = useMutation({
//mutationFn: async (updates: Partial<Profile>) => {
//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 },
//});
useEffect(() => {
const {
@@ -110,11 +126,15 @@ const AuthContextProvider = ({ children }: { children: ReactNode }) => {
}, [supabase.auth, queryClient]);
const handleUpdateProfile = async (data: Partial<Profile>) => {
if (!userData?.id) throw new Error('User ID is required!');
try {
const result = await updateProfileMutation.mutateAsync(data);
return { data: result };
const result = await updateProfileMutation.mutateAsync({
...data,
id: userData.id,
});
return { data: result, error: null };
} catch (error) {
return { error };
return { data: null, error };
}
};

View File

@@ -65,6 +65,7 @@ const QueryClientProvider = ({ children }: { children: React.ReactNode }) => {
}),
defaultOptions: {
queries: {
refetchOnWindowFocus: true,
staleTime: 60 * 1000,
},
},

View File

@@ -25,17 +25,12 @@ const ThemeProvider = ({
type ThemeToggleProps = {
size?: number;
buttonClassName?: ComponentProps<typeof Button>['className'];
buttonProps?: Omit<ComponentProps<typeof Button>, 'className' | 'onClick'>;
buttonProps?: Omit<ComponentProps<typeof Button>, 'onClick'>;
};
const ThemeToggle = ({
size = 1,
buttonClassName,
buttonProps = {
variant: 'outline',
size: 'icon',
},
buttonProps,
}: ThemeToggleProps) => {
const { setTheme, resolvedTheme } = useTheme();
@@ -45,7 +40,7 @@ const ThemeToggle = ({
if (!mounted) {
return (
<Button className={buttonClassName} {...buttonProps}>
<Button {...buttonProps}>
<span style={{ height: `${size}rem`, width: `${size}rem` }} />
</Button>
);
@@ -58,9 +53,11 @@ const ThemeToggle = ({
return (
<Button
className={cn('cursor-pointer', buttonClassName)}
onClick={toggleTheme}
variant='outline'
size='icon'
{...buttonProps}
onClick={toggleTheme}
className={cn('cursor-pointer', buttonProps?.className)}
>
<Sun
style={{ height: `${size}rem`, width: `${size}rem` }}

View File

@@ -3,7 +3,7 @@ import { useState, useRef } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { getSignedUrl, resizeImage, uploadFile } from '@/lib/queries';
import { useAuth, QueryErrorCodes } from '@/lib/hooks/context';
import type { SupabaseClient, Result, User, Profile } from '@/utils/supabase';
import type { SupabaseClient, User, Profile } from '@/utils/supabase';
import { toast } from 'sonner';
type UploadToStorageProps = {