import React, { useEffect, useRef } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useNostrPublish } from '@/hooks/useNostrPublish'; import { useToast } from '@/hooks/useToast'; import { Button } from '@/components/ui/button'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Switch } from '@/components/ui/switch'; import { Loader2, Upload } from 'lucide-react'; import { NSchema as n, type NostrMetadata } from '@nostrify/nostrify'; import { useQueryClient } from '@tanstack/react-query'; import { useUploadFile } from '@/hooks/useUploadFile'; export const EditProfileForm: React.FC = () => { const queryClient = useQueryClient(); const { user, metadata } = useCurrentUser(); const { mutateAsync: publishEvent, isPending } = useNostrPublish(); const { mutateAsync: uploadFile, isPending: isUploading } = useUploadFile(); const { toast } = useToast(); // Initialize the form with default values const form = useForm({ resolver: zodResolver(n.metadata()), defaultValues: { name: '', about: '', picture: '', banner: '', website: '', nip05: '', bot: false, }, }); // Update form values when user data is loaded useEffect(() => { if (metadata) { form.reset({ name: metadata.name || '', about: metadata.about || '', picture: metadata.picture || '', banner: metadata.banner || '', website: metadata.website || '', nip05: metadata.nip05 || '', bot: metadata.bot || false, }); } }, [metadata, form]); // Handle file uploads for profile picture and banner const uploadPicture = async (file: File, field: 'picture' | 'banner') => { try { // The first tuple in the array contains the URL const [[_, url]] = await uploadFile(file); form.setValue(field, url); toast({ title: 'Success', description: `${field === 'picture' ? 'Profile picture' : 'Banner'} uploaded successfully`, }); } catch (error) { console.error(`Failed to upload ${field}:`, error); toast({ title: 'Error', description: `Failed to upload ${field === 'picture' ? 'profile picture' : 'banner'}. Please try again.`, variant: 'destructive', }); } }; const onSubmit = async (values: NostrMetadata) => { if (!user) { toast({ title: 'Error', description: 'You must be logged in to update your profile', variant: 'destructive', }); return; } try { // Combine existing metadata with new values const data = { ...metadata, ...values }; // Clean up empty values for (const key in data) { if (data[key] === '') { delete data[key]; } } // Publish the metadata event (kind 0) await publishEvent({ kind: 0, content: JSON.stringify(data), }); // Invalidate queries to refresh the data queryClient.invalidateQueries({ queryKey: ['logins'] }); queryClient.invalidateQueries({ queryKey: ['author', user.pubkey] }); toast({ title: 'Success', description: 'Your profile has been updated', }); } catch (error) { console.error('Failed to update profile:', error); toast({ title: 'Error', description: 'Failed to update your profile. Please try again.', variant: 'destructive', }); } }; return (
( Name This is your display name that will be displayed to others. )} /> ( Bio