cambios en la interfaz de organizaciones

This commit is contained in:
2026-02-23 12:40:30 -04:00
parent e149500735
commit 0efd5a11bd
12 changed files with 2427 additions and 265 deletions

View File

@@ -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>