160 lines
5.0 KiB
TypeScript
160 lines
5.0 KiB
TypeScript
'use client';
|
|
import ImageUploader from '@/components/banner-uploader';
|
|
import Button from '@/components/button';
|
|
import Input from '@/components/input';
|
|
import Select from '@/components/select';
|
|
import { CreateEventoType } from '@/types/create-evento';
|
|
import { GetEventoWithCuestionarios } from '@/types/evento';
|
|
import axiosInstance from '@/utils/api-config';
|
|
import { getAxiosError } from '@/utils/errors-utils';
|
|
import { commands } from '@uiw/react-md-editor';
|
|
import dynamic from 'next/dynamic';
|
|
import React, { useState } from 'react';
|
|
import toast from 'react-hot-toast';
|
|
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
|
|
|
|
interface EditEventoProps {
|
|
evento: GetEventoWithCuestionarios;
|
|
handleChange: (field: keyof CreateEventoType, value: string | Date) => void;
|
|
handleOnChange: (eventoActualizado: GetEventoWithCuestionarios) => void;
|
|
}
|
|
|
|
export default function EditEvento({
|
|
evento,
|
|
handleChange,
|
|
handleOnChange,
|
|
}: EditEventoProps) {
|
|
const toDateInputValue = (isoString: string) => isoString.slice(0, 10);
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [nuevoBanner, setNuevoBanner] = useState<File | null>(null);
|
|
|
|
const handleOnSave = async () => {
|
|
setLoading(true);
|
|
try {
|
|
// 1. Subir nuevo banner si fue cambiado
|
|
if (nuevoBanner) {
|
|
const formData = new FormData();
|
|
formData.append('banner', nuevoBanner);
|
|
|
|
await axiosInstance.post(
|
|
`/evento/${evento.id_evento}/banner`,
|
|
formData,
|
|
{
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
// 2. Actualizar el evento (sin incluir 'banner')
|
|
const res = await axiosInstance.patch(`/evento/${evento.id_evento}`, {
|
|
nombre_evento: evento.nombre_evento,
|
|
descripcion_evento: evento.descripcion_evento,
|
|
tipo_evento: evento.tipo_evento,
|
|
fecha_inicio: evento.fecha_inicio,
|
|
fecha_fin: evento.fecha_fin,
|
|
});
|
|
|
|
toast.success('Evento actualizado correctamente');
|
|
handleOnChange(res.data); // Actualiza en el padre
|
|
} catch (error) {
|
|
const msg = getAxiosError(error);
|
|
toast.error(`Error al actualizar el evento: ${msg.message}`);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="row border p-3 rounded my-4">
|
|
<h2>Editar Información del Evento</h2>
|
|
<p>Modifica los datos del evento que desees actualizar.</p>
|
|
|
|
<ImageUploader
|
|
label="Banner del evento"
|
|
defaultBanner={
|
|
evento.banner
|
|
? `${process.env.NEXT_PUBLIC_API_URL}/banners/${evento.banner}`
|
|
: undefined
|
|
}
|
|
onChange={(file) => {
|
|
setNuevoBanner(file);
|
|
}}
|
|
/>
|
|
|
|
<Input
|
|
label="Nombre del evento"
|
|
required
|
|
value={evento.nombre_evento}
|
|
onChange={(e) => handleChange('nombre_evento', e.target.value)}
|
|
/>
|
|
|
|
<div className="mb-4">
|
|
<label className="form-label">Descripción del evento</label>
|
|
<div data-color-mode="light">
|
|
<MDEditor
|
|
value={evento.descripcion_evento ?? ''}
|
|
onChange={(value) => {
|
|
const texto = value || '';
|
|
if (texto.length <= 500) {
|
|
handleChange('descripcion_evento', texto);
|
|
}
|
|
}}
|
|
height={250}
|
|
commands={[commands.bold, commands.italic, commands.hr]}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<Select
|
|
label="Tipo de evento"
|
|
value={evento.tipo_evento}
|
|
placeholder="Selecciona un tipo de evento"
|
|
onChange={(e) => handleChange('tipo_evento', e.target.value)}
|
|
options={[
|
|
{ label: 'Conferencia', value: 'conferencia' },
|
|
{ label: 'Taller', value: 'taller' },
|
|
{ label: 'Seminario', value: 'seminario' },
|
|
{ label: 'Curso', value: 'curso' },
|
|
{ label: 'Webinar', value: 'webinar' },
|
|
{ label: 'Reunión', value: 'reunion' },
|
|
{ label: 'Feria', value: 'feria' },
|
|
{ label: 'Concierto', value: 'concierto' },
|
|
{ label: 'Exposición', value: 'exposicion' },
|
|
{ label: 'Deportivo', value: 'deportivo' },
|
|
{ label: 'Cultural', value: 'cultural' },
|
|
{ label: 'Otro', value: 'otro' },
|
|
]}
|
|
/>
|
|
|
|
<div className="col-md-6">
|
|
<Input
|
|
label="Fecha de inicio"
|
|
type="date"
|
|
className={{ container: 'mb-3' }}
|
|
value={toDateInputValue(evento.fecha_inicio)}
|
|
onChange={(e) => handleChange('fecha_inicio', e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-md-6">
|
|
<Input
|
|
label="Fecha de fin"
|
|
type="date"
|
|
className={{ container: 'mb-3' }}
|
|
value={toDateInputValue(evento.fecha_fin)}
|
|
onChange={(e) => handleChange('fecha_fin', e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<Button icon="save" disabled={loading} onClick={handleOnSave}>
|
|
{loading ? 'Guardando...' : 'Guardar Cambios'}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|