Exportar excel con imagen y ahora guarda las imagenes como .png

This commit is contained in:
2026-02-05 18:09:05 -04:00
parent 63c39e399e
commit f1bdce317f
13 changed files with 250 additions and 332 deletions

View File

@@ -1,5 +1,5 @@
'use server';
import { safeFetchApi } from '@/lib';
import { safeFetchApi } from '@/lib/fetch.api';
import { loginResponseSchema, UserFormValue } from '../schemas/login';
type LoginActionSuccess = {
@@ -20,9 +20,9 @@ type LoginActionSuccess = {
}
type LoginActionError = {
type: 'API_ERROR' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR'; // **Asegúrate de que el tipo de `type` sea este aquí**
message: string;
details?: any;
type: 'API_ERROR' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR'; // **Asegúrate de que el tipo de `type` sea este aquí**
message: string;
details?: any;
};
// Si SignInAction también puede devolver null, asegúralo en su tipo de retorno
@@ -37,7 +37,7 @@ export const SignInAction = async (payload: UserFormValue): Promise<LoginActionR
);
if (error) {
return {
type: error.type as 'API_ERROR' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR',
type: error.type as 'API_ERROR' | 'VALIDATION_ERROR' | 'UNKNOWN_ERROR',
message: error.message,
details: error.details
};

View File

@@ -90,7 +90,7 @@ export const createTrainingAction = async (
payloadToSend = rest as any;
}
console.log(payloadToSend);
// console.log(payloadToSend);
const [error, data] = await safeFetchApi(
TrainingMutate,

View File

@@ -166,7 +166,7 @@ export function CreateTrainingForm({
mode: 'onChange',
});
// Cascading Select Logic
const ecoSector = useWatch({ control: form.control, name: 'ecoSector' });
const productiveSector = useWatch({
@@ -217,7 +217,7 @@ export function CreateTrainingForm({
const coorMunicipalityOptions =
Array.isArray(dataCoorMunicipality?.data) &&
dataCoorMunicipality.data.length > 0
dataCoorMunicipality.data.length > 0
? dataCoorMunicipality.data
: [{ id: 0, stateId: 0, name: 'Sin Municipios' }];
@@ -268,7 +268,7 @@ export function CreateTrainingForm({
// 1. Definimos las claves que NO queremos enviar en el bucle general
// 'files' se procesa aparte.
// 'photo1/2/3' son strings (urls viejas) que no queremos reenviar como texto.
const excludedKeys = ['files', 'photo1', 'photo2', 'photo3', 'coorState', 'coorMunicipality', 'coorParish'];
const excludedKeys = ['files', 'photo1', 'photo2', 'photo3', 'coorState', 'coorMunicipality', 'coorParish'];
Object.entries(formData).forEach(([key, value]) => {
// 2. Condición actualizada: Si la key está en la lista de excluidos, la saltamos
@@ -287,17 +287,17 @@ export function CreateTrainingForm({
}
});
// 2. Mapeo manual y conversión a numérico
// if (formData.state) {
// data.append('state', Number(formData.state).toString());
// }
// if (formData.municipality) {
// data.append('municipality', Number(formData.municipality).toString());
// }
// if (formData.parish) {
// data.append('parish', Number(formData.parish).toString());
// }
// 2. Mapeo manual y conversión a numérico
// if (formData.state) {
// data.append('state', Number(formData.state).toString());
// }
// if (formData.municipality) {
// data.append('municipality', Number(formData.municipality).toString());
// }
// if (formData.parish) {
// data.append('parish', Number(formData.parish).toString());
// }
if (defaultValues?.id) {
data.append('id', defaultValues.id.toString());
}
@@ -305,24 +305,24 @@ export function CreateTrainingForm({
// 4. Aquí se agregan las NUEVAS fotos (binary) si el usuario seleccionó alguna
selectedFiles.forEach((file) => {
data.append('files', file);
});
console.log(data);
console.log(file);
});
const mutation = defaultValues?.id ? updateTraining : createTraining;
// mutation(data as any, {
// onSuccess: () => {
// form.reset();
// setSelectedFiles([]);
// onSuccess?.();
// },
// onError: (e) => {
// console.error(e);
// form.setError('root', {
// type: 'manual',
// message: 'Error al guardar el registro',
// });
// },
// });
mutation(data as any, {
onSuccess: () => {
form.reset();
setSelectedFiles([]);
onSuccess?.();
},
onError: (e) => {
console.error(e);
form.setError('root', {
type: 'manual',
message: 'Error al guardar el registro',
});
},
});
};
return (
@@ -417,7 +417,7 @@ export function CreateTrainingForm({
</FormItem>
)}
/>
<FormField
<FormField
control={form.control}
name="state"
render={({ field }) => (
@@ -921,7 +921,7 @@ export function CreateTrainingForm({
<CardTitle>3. Detalles de la ubicación</CardTitle>
</CardHeader>
<CardContent className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
<FormField
control={form.control}
name="ospAddress"

View File

@@ -77,7 +77,7 @@ export const CellAction: React.FC<CellActionProps> = ({ data, apiUrl }) => {
</Tooltip>
</TooltipProvider>
{/* <TooltipProvider>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
@@ -92,7 +92,7 @@ export const CellAction: React.FC<CellActionProps> = ({ data, apiUrl }) => {
<p>Exportar Excel</p>
</TooltipContent>
</Tooltip>
</TooltipProvider> */}
</TooltipProvider>
<TooltipProvider>
<Tooltip>