import { useState, useCallback } from 'react'; import { useStore } from '@nanostores/react'; import { classNames } from '~/utils/classNames'; import { profileStore, updateProfile } from '~/lib/stores/profile'; import { toast } from 'react-toastify'; import { debounce } from '~/utils/debounce'; export default function ProfileTab() { const profile = useStore(profileStore); const [isUploading, setIsUploading] = useState(false); // Create debounced update functions const debouncedUpdate = useCallback( debounce((field: 'username' | 'bio', value: string) => { updateProfile({ [field]: value }); toast.success(`${field.charAt(0).toUpperCase() + field.slice(1)} updated`); }, 1000), [], ); const handleAvatarUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) { return; } try { setIsUploading(true); // Convert the file to base64 const reader = new FileReader(); reader.onloadend = () => { const base64String = reader.result as string; updateProfile({ avatar: base64String }); setIsUploading(false); toast.success('Profile picture updated'); }; reader.onerror = () => { console.error('Error reading file:', reader.error); setIsUploading(false); toast.error('Failed to update profile picture'); }; reader.readAsDataURL(file); } catch (error) { console.error('Error uploading avatar:', error); setIsUploading(false); toast.error('Failed to update profile picture'); } }; const handleProfileUpdate = (field: 'username' | 'bio', value: string) => { // Update the store immediately for UI responsiveness updateProfile({ [field]: value }); // Debounce the toast notification debouncedUpdate(field, value); }; return (
{/* Personal Information Section */}
{/* Avatar Upload */}
{profile.avatar ? ( Profile ) : (
)}