A
Anonymous

User Profile Edit Form - Copy this React, Tailwind Component to your project

import { useEffect, useRef, useState } from 'react'; import { useStore } from '../../lib/store'; import { Camera, X } from 'lucide-react'; interface EditProfileModalProps { onClose: () => void; } export function EditProfileModal({ onClose }: EditProfileModalProps) { const user = useStore((state) => state.user); const updateProfile = useStore((state) => state.updateProfile); const [loading, setLoading] = useState(false); const modalRef = useRef<HTMLDivElement>(null); const [error, setError] = useState<string | null>(null); const [formData, setFormData] = useState({ name: user?.name || '', bio: user?.bio || '', website: user?.website || '', location: user?.location || '', }); useEffect(() => { function handleClickOutside(event: MouseEvent) { if (modalRef.current && !modalRef.current.contains(event.target as Node)) { onClose(); } } document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, [onClose]); const handleAvatarChange = (e: React.ChangeEvent<HTMLInputElement>) => { const file = e.target.files?.[0]; if (file) { console.log('Avatar seleccionado:', file); // Aquí iría la lógica para subir la imagen } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setError(null); try { await updateProfile(formData); onClose(); } catch (error) { console.error('Failed to update profile:', error); setError('Failed to update profile. Please try again.'); } finally { setLoading(false); } }; return ( <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> <div ref={modalRef} className="bg-white rounded-lg shadow-xl w-full max-w-md mx-4"> <div className="p-4 border-b flex justify-between items-center"> <h2 className="text-lg font-semibold">Edit Profile</h2> <button onClick={onClose} className="text-gray-500 hover:text-gray-700"> <X className="w-5 h-5" /> </button> </div> <form onSubmit={handleSubmit} className="p-6 space-y-6"> {error && <p className="text-red-500 text-sm">{error}</p>} <div className="flex items-center gap-6"> <div className="relative"> <img src={user?.avatar || '/placeholder-avatar.png'} alt={user?.name || 'Avatar'} className="w-24 h-24 rounded-full object-cover" /> <label className="absolute bottom-0 right-0 bg-blue-500 text-white p-2 rounded-full hover:bg-blue-600 cursor-pointer"> <Camera className="w-4 h-4" /> <input type="file" accept="image/*" onChange={handleAvatarChange} className="hidden" /> </label> </div> </div> {/* Campos de texto */} {['name', 'bio', 'website', 'location'].map((field) => ( <div key={field}> <label className="block text-sm font-medium text-gray-700"> {field.charAt(0).toUpperCase() + field.slice(1)} </label> <input type={field === 'website' ? 'url' : 'text'} value={formData[field as keyof typeof formData]} onChange={(e) => setFormData({ ...formData, [field]: e.target.value }) } className="mt-1 block w-full rounded-lg border border-gray-300 px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" /> </div> ))} {/* Botones */} <div className="flex gap-3 pt-4"> <button type="button" onClick={onClose} className="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50" > Cancel </button> <button type="submit" disabled={loading} className="flex-1 bg-blue-500 text-white rounded-lg px-4 py-2 hover:bg-blue-600 disabled:opacity-50" > {loading ? 'Saving...' : 'Save Changes'} </button> </div> </form> </div> </div> ); } use the data types and methods!

Prompt

About

UserProfileEditForm - A sleek interface for users to update their profiles, featuring form validation, responsive design, and user-fr. Free code available!

Share

Last updated 1 month ago