Spaces:
Sleeping
Sleeping
| import { useState, useEffect } from 'react'; | |
| const COLORS = [ | |
| { name: 'blue', label: 'Azul', class: 'bg-blue-500' }, | |
| { name: 'green', label: 'Verde', class: 'bg-green-500' }, | |
| { name: 'red', label: 'Rojo', class: 'bg-red-500' }, | |
| { name: 'purple', label: 'Morado', class: 'bg-purple-500' }, | |
| { name: 'orange', label: 'Naranja', class: 'bg-orange-500' }, | |
| { name: 'pink', label: 'Rosa', class: 'bg-pink-500' }, | |
| ]; | |
| export default function EventModal({ isOpen, onClose, onSave, selectedDate, editEvent }) { | |
| const [title, setTitle] = useState(''); | |
| const [description, setDescription] = useState(''); | |
| const [time, setTime] = useState(''); | |
| const [color, setColor] = useState('blue'); | |
| const [date, setDate] = useState(''); | |
| useEffect(() => { | |
| if (editEvent) { | |
| setTitle(editEvent.title); | |
| setDescription(editEvent.description || ''); | |
| setTime(editEvent.time || ''); | |
| setColor(editEvent.color); | |
| setDate(editEvent.date); | |
| } else { | |
| setTitle(''); | |
| setDescription(''); | |
| setTime(''); | |
| setColor('blue'); | |
| setDate(selectedDate || ''); | |
| } | |
| }, [editEvent, selectedDate, isOpen]); | |
| const handleSubmit = (e) => { | |
| e.preventDefault(); | |
| if (!title.trim() || !date) return; | |
| onSave({ | |
| id: editEvent?.id || null, | |
| title: title.trim(), | |
| description: description.trim(), | |
| time, | |
| color, | |
| date, | |
| }); | |
| onClose(); | |
| }; | |
| if (!isOpen) return null; | |
| return ( | |
| <div className="fixed inset-0 z-50 overflow-y-auto"> | |
| <div className="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0"> | |
| {/* Backdrop */} | |
| <div | |
| className="fixed inset-0 bg-slate-900 bg-opacity-50 transition-opacity" | |
| onClick={onClose} | |
| ></div> | |
| {/* Modal */} | |
| <div className="relative bg-white rounded-2xl shadow-2xl max-w-md w-full mx-auto z-10 transform transition-all"> | |
| <div className="p-6"> | |
| {/* Header */} | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="text-xl font-bold text-slate-800"> | |
| {editEvent ? 'Editar Evento' : 'Nuevo Evento'} | |
| </h3> | |
| <button | |
| onClick={onClose} | |
| className="p-2 hover:bg-slate-100 rounded-lg transition-colors duration-200" | |
| > | |
| <svg className="w-5 h-5 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /> | |
| </svg> | |
| </button> | |
| </div> | |
| {/* Form */} | |
| <form onSubmit={handleSubmit} className="space-y-4"> | |
| <div> | |
| <label className="block text-sm font-medium text-slate-700 mb-1"> | |
| Título del evento * | |
| </label> | |
| <input | |
| type="text" | |
| value={title} | |
| onChange={(e) => setTitle(e.target.value)} | |
| className="input-field" | |
| placeholder="Ej: Reunión de trabajo" | |
| required | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-sm font-medium text-slate-700 mb-1"> | |
| Fecha * | |
| </label> | |
| <input | |
| type="date" | |
| value={date} | |
| onChange={(e) => setDate(e.target.value)} | |
| className="input-field" | |
| required | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-sm font-medium text-slate-700 mb-1"> | |
| Hora | |
| </label> | |
| <input | |
| type="time" | |
| value={time} | |
| onChange={(e) => setTime(e.target.value)} | |
| className="input-field" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-sm font-medium text-slate-700 mb-1"> | |
| Descripción | |
| </label> | |
| <textarea | |
| value={description} | |
| onChange={(e) => setDescription(e.target.value)} | |
| className="input-field resize-none" | |
| rows={3} | |
| placeholder="Añade detalles sobre el evento..." | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-sm font-medium text-slate-700 mb-2"> | |
| Color | |
| </label> | |
| <div className="flex gap-2"> | |
| {COLORS.map((c) => ( | |
| <button | |
| key={c.name} | |
| type="button" | |
| onClick={() => setColor(c.name)} | |
| className={`w-8 h-8 rounded-full ${c.class} transition-all duration-200 | |
| ${color === c.name | |
| ? 'ring-2 ring-offset-2 ring-slate-400 scale-110' | |
| : 'hover:scale-105' | |
| } | |
| `} | |
| title={c.label} | |
| /> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Actions */} | |
| <div className="flex gap-3 pt-4"> | |
| <button | |
| type="button" | |
| onClick={onClose} | |
| className="btn-secondary flex-1" | |
| > | |
| Cancelar | |
| </button> | |
| <button | |
| type="submit" | |
| className="btn-primary flex-1" | |
| > | |
| {editEvent ? 'Guardar Cambios' : 'Crear Evento'} | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |