Files
thrilltrack-explorer/src-old/hooks/useAvatarUpload.ts

85 lines
1.9 KiB
TypeScript

import { useState, useCallback } from 'react';
import { supabase } from '@/lib/supabaseClient';
import { handleError, handleSuccess } from '@/lib/errorHandler';
export type AvatarUploadState = {
url: string;
imageId: string;
isUploading: boolean;
};
export const useAvatarUpload = (
initialUrl: string = '',
initialImageId: string = '',
username: string
) => {
const [state, setState] = useState<AvatarUploadState>({
url: initialUrl,
imageId: initialImageId,
isUploading: false
});
const uploadAvatar = useCallback(async (
urls: string[],
imageId?: string
) => {
if (!urls[0]) return { success: false };
const newUrl = urls[0];
const newImageId = imageId || '';
// Optimistic update
setState(prev => ({
...prev,
url: newUrl,
imageId: newImageId,
isUploading: true
}));
try {
const { error } = await supabase.rpc('update_profile', {
p_username: username,
p_avatar_url: newUrl,
p_avatar_image_id: newImageId
});
if (error) throw error;
setState(prev => ({ ...prev, isUploading: false }));
handleSuccess('Avatar updated', 'Your avatar has been successfully updated.');
return { success: true };
} catch (error: unknown) {
// Rollback on error
setState({
url: initialUrl,
imageId: initialImageId,
isUploading: false
});
handleError(error, {
action: 'Avatar upload failed',
metadata: { username }
});
return { success: false, error };
}
}, [username, initialUrl, initialImageId]);
const resetAvatar = useCallback(() => {
setState({
url: initialUrl,
imageId: initialImageId,
isUploading: false
});
}, [initialUrl, initialImageId]);
return {
avatarUrl: state.url,
avatarImageId: state.imageId,
isUploading: state.isUploading,
uploadAvatar,
resetAvatar
};
};