'use client'; import { useFileUpload } from '@/lib/hooks'; import { useAuth } from '@/lib/hooks/context'; import { useSupabaseClient } from '@/utils/supabase'; import { BasedAvatar, Card, CardContent, } from '@/components/ui'; import { Loader2, Pencil, Upload } from 'lucide-react'; import type { ComponentProps, ChangeEvent } from 'react'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; type AvatarUploadProps = { onAvatarUploaded: (path: string) => Promise; cardProps?: ComponentProps; cardContentProps?: ComponentProps; containerProps?: ComponentProps<'div'>; basedAvatarProps?: ComponentProps; iconProps?: ComponentProps; }; export const AvatarUpload = ({ onAvatarUploaded, cardProps, cardContentProps, containerProps, basedAvatarProps, iconProps = { size: 32, }, }: AvatarUploadProps) => { const { profile, isAuthenticated } = useAuth(); const { isUploading, fileInputRef, uploadAvatarMutation } = useFileUpload(); const client = useSupabaseClient(); const handleAvatarClick = () => { if (!isAuthenticated) { toast.error('You must be logged in to upload an avatar!'); return; } fileInputRef.current?.click(); }; const handleFileChange = async (e: ChangeEvent) => { try { const file = e.target.files?.[0]; if (!file) throw new Error('No file selected!'); if (!client) throw new Error('Supabase client not found!'); if (!isAuthenticated) throw new Error('User is not authenticated!'); if (!file.type.startsWith('image/')) throw new Error('File is not an image!'); if (file.size > 8 * 1024 * 1024) throw new Error('File is too large!'); const avatarPath = profile?.avatar_url ?? `${profile?.id}.${file.name.split('.').pop()}`; const avatarUrl = await uploadAvatarMutation.mutateAsync({ client, file, bucket: 'avatars', resize: { maxWidth: 500, maxHeight: 500, quality: 0.8, }, replace: avatarPath, }); if (avatarUrl) await onAvatarUploaded(avatarUrl); } catch (error) { toast.error(`Error: ${error as string}`); } }; return (
{isUploading && (
Uploading...
)} {!isAuthenticated && (

Sign in to upload an avatar.

)}
); };