cambios en la interfaz de organizaciones
This commit is contained in:
@@ -45,7 +45,8 @@ import {
|
||||
CardTitle,
|
||||
} from '@repo/shadcn/components/ui/card';
|
||||
import { SelectSearchable } from '@repo/shadcn/components/ui/select-searchable';
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const OSP_TYPES = ['EPSIC', 'EPSDC', 'UPF', 'OTROS', 'COOPERATIVA'];
|
||||
const STATUS_OPTIONS = ['ACTIVA', 'INACTIVA'];
|
||||
@@ -160,6 +161,16 @@ export function CreateTrainingForm({
|
||||
mode: 'onChange',
|
||||
});
|
||||
|
||||
// 1. Extrae errors de formState
|
||||
const { formState: { errors } } = form;
|
||||
|
||||
// 2. Crea un efecto para monitorearlos
|
||||
useEffect(() => {
|
||||
if (Object.keys(errors).length > 0) {
|
||||
console.log("Campos con errores:", errors);
|
||||
}
|
||||
}, [errors]);
|
||||
|
||||
// Cascading Select Logic
|
||||
const ecoSector = useWatch({ control: form.control, name: 'ecoSector' });
|
||||
const productiveSector = useWatch({
|
||||
@@ -253,6 +264,8 @@ export function CreateTrainingForm({
|
||||
}, [defaultValues]);
|
||||
|
||||
const onSubmit = async (formData: TrainingSchema) => {
|
||||
|
||||
|
||||
const data = new FormData();
|
||||
|
||||
// 1. Definimos las claves que NO queremos enviar en el bucle general
|
||||
@@ -260,9 +273,6 @@ export function CreateTrainingForm({
|
||||
// 'photo1/2/3' son strings (urls viejas) que no queremos reenviar como texto.
|
||||
const excludedKeys = [
|
||||
'files',
|
||||
'photo1',
|
||||
'photo2',
|
||||
'photo3',
|
||||
'coorState',
|
||||
'coorMunicipality',
|
||||
'coorParish',
|
||||
@@ -1039,7 +1049,7 @@ export function CreateTrainingForm({
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full flex flex-col space-y-2">
|
||||
<FormLabel className="font-semibold">
|
||||
Correo Electrónico de la Comuna
|
||||
Correo Electrónico de la Comuna (Opcional)
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="email" {...field} />
|
||||
@@ -1141,7 +1151,7 @@ export function CreateTrainingForm({
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full flex flex-col space-y-2">
|
||||
<FormLabel className="font-semibold">
|
||||
Correo Electrónico del Consejo Comunal
|
||||
Correo Electrónico del Consejo Comunal (Opcional)
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="email" {...field} />
|
||||
@@ -1298,7 +1308,7 @@ export function CreateTrainingForm({
|
||||
name="generalObservations"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Observaciones Generales</FormLabel>
|
||||
<FormLabel>Observaciones Generales (Opcional)</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea {...field} />
|
||||
</FormControl>
|
||||
@@ -1374,19 +1384,25 @@ export function CreateTrainingForm({
|
||||
multiple
|
||||
accept="image/*"
|
||||
onChange={(e) => {
|
||||
const files = Array.from(e.target.files || []);
|
||||
const newFiles = Array.from(e.target.files || []);
|
||||
const existingCount = [
|
||||
form.watch('photo1'),
|
||||
form.watch('photo2'),
|
||||
form.watch('photo3'),
|
||||
].filter(Boolean).length;
|
||||
|
||||
if (files.length + existingCount > 3) {
|
||||
alert('Máximo 3 imágenes en total');
|
||||
if (
|
||||
newFiles.length + selectedFiles.length + existingCount >
|
||||
3
|
||||
) {
|
||||
toast.error(`Máximo 3 imágenes en total. Ya tienes ${existingCount} subidas y ${selectedFiles.length} seleccionadas para subir.`)
|
||||
e.target.value = '';
|
||||
return;
|
||||
}
|
||||
setSelectedFiles(files);
|
||||
|
||||
setSelectedFiles((prev) => [...prev, ...newFiles]);
|
||||
// Reset the input value so the same file can be selected again if removed
|
||||
e.target.value = '';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -1398,13 +1414,37 @@ export function CreateTrainingForm({
|
||||
{selectedFiles.map((file, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="relative aspect-square rounded-md overflow-hidden bg-muted"
|
||||
className="relative aspect-square rounded-md overflow-hidden bg-muted group"
|
||||
>
|
||||
<img
|
||||
src={URL.createObjectURL(file)}
|
||||
alt={`Preview ${idx + 1}`}
|
||||
className="object-cover w-full h-full"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSelectedFiles((prev) =>
|
||||
prev.filter((_, i) => i !== idx),
|
||||
);
|
||||
}}
|
||||
className="absolute top-1 right-1 bg-destructive text-destructive-foreground rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user