fix: rpc function

This commit is contained in:
2026-07-14 16:50:54 -04:00
parent cc6ea9ec5e
commit da9f96b272
10 changed files with 110 additions and 132 deletions
-85
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+85
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>glm-card-generator</title> <title>glm-card-generator</title>
<script type="module" crossorigin src="/empleado-id/assets/index-DB5K4uXE.js"></script> <script type="module" crossorigin src="/empleado-id/assets/index-DjTKszDz.js"></script>
<link rel="stylesheet" crossorigin href="/empleado-id/assets/index-DZtAAsdo.css"> <link rel="stylesheet" crossorigin href="/empleado-id/assets/index-OsvWWXE6.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
-1
View File
@@ -19,7 +19,6 @@ function AuthProvider({ children }) {
useEffect(() => { useEffect(() => {
if (!supabase) { if (!supabase) {
console.warn("Supabase no configurado - falta VITE_SUPABASE_ANON_KEY");
setLoading(false); setLoading(false);
return; return;
} }
+8 -13
View File
@@ -32,7 +32,7 @@ const convertBinaryToBlobUrl = (data) => {
return URL.createObjectURL(blob); return URL.createObjectURL(blob);
} }
} catch (e) { } catch (e) {
console.error("Error convirtiendo formato binario a Blob URL:", e); // ignore
} }
return null; return null;
}; };
@@ -86,7 +86,6 @@ export default function IdCardGenerator() {
setPhotoSrc(editedUrl); setPhotoSrc(editedUrl);
setPhotoFile(new File([editedBlob], file.name, { type: editedBlob.type || 'image/jpeg' })); setPhotoFile(new File([editedBlob], file.name, { type: editedBlob.type || 'image/jpeg' }));
} catch (error) { } catch (error) {
console.error('Error al procesar la foto con IA en n8n:', error);
alert('No se pudo procesar la foto con IA. Se usará la foto original para la vista previa.'); alert('No se pudo procesar la foto con IA. Se usará la foto original para la vista previa.');
} finally { } finally {
setPhotoProcessing(false); setPhotoProcessing(false);
@@ -162,7 +161,6 @@ export default function IdCardGenerator() {
const resData = await response.json(); const resData = await response.json();
return Array.isArray(resData) ? resData : (resData.empleados || resData.data || []); return Array.isArray(resData) ? resData : (resData.empleados || resData.data || []);
} catch (error) { } catch (error) {
console.error('Error de comunicación con n8n:', error);
throw error; throw error;
} }
}; };
@@ -172,14 +170,16 @@ export default function IdCardGenerator() {
if (!cleanCedula) return; if (!cleanCedula) return;
try { try {
// Se usa el cliente extraído directamente del array renderizado
const clienteProyectoValue = currentEmployee?.selectedClient || 'Generico'; const clienteProyectoValue = currentEmployee?.selectedClient || 'Generico';
await saveClienteProyecto(cleanCedula, clienteProyectoValue);
console.log(`[Supabase DB] Guardado: ${cleanCedula}${clienteProyectoValue}`);
// 1) Guardar cédula + cliente_proyecto en carnet_empleados_creados_glm
await saveClienteProyecto(cleanCedula, clienteProyectoValue);
// 2) Subir foto al storage
const customFile = new File([blobData], `${cleanCedula}.jpg`, { type: 'image/jpeg' }); const customFile = new File([blobData], `${cleanCedula}.jpg`, { type: 'image/jpeg' });
const remoteStorageUrl = await uploadEmployeePhoto(cleanCedula, customFile); const remoteStorageUrl = await uploadEmployeePhoto(cleanCedula, customFile);
// 3) Guardar URL de foto
if (remoteStorageUrl) { if (remoteStorageUrl) {
await supabase.rpc("save_employee_photo", { await supabase.rpc("save_employee_photo", {
p_employee_number: cleanCedula, p_employee_number: cleanCedula,
@@ -187,7 +187,7 @@ export default function IdCardGenerator() {
}); });
} }
} catch (error) { } catch (error) {
console.error(`[Supabase Sync Fallido] Cédula ${cleanCedula}:`, error); // silent
} }
}; };
@@ -257,13 +257,11 @@ export default function IdCardGenerator() {
setBulkDownloadStatus({ processing: false, text: '⬇ Descargar' }); setBulkDownloadStatus({ processing: false, text: '⬇ Descargar' });
} catch (innerErr) { } catch (innerErr) {
console.error(innerErr);
setBulkStatusText('❌ Error de lectura. Revisa el formato de columnas.'); setBulkStatusText('❌ Error de lectura. Revisa el formato de columnas.');
} }
}; };
reader.readAsBinaryString(file); reader.readAsBinaryString(file);
} catch (err) { } catch (err) {
console.error(err);
setBulkStatusText('❌ Error cargando el motor XLSX.'); setBulkStatusText('❌ Error cargando el motor XLSX.');
} }
}; };
@@ -301,18 +299,16 @@ export default function IdCardGenerator() {
employees: employeesReadyForRender, employees: employeesReadyForRender,
baseUrl, baseUrl,
onStateChange: null, onStateChange: null,
// CORRECCIÓN AQUÍ: Buscamos al empleado en nuestro arreglo usando la cédula que nos devuelve script.jsx
onProcessEmployeePhoto: (cedula, blobData) => { onProcessEmployeePhoto: (cedula, blobData) => {
const currentEmp = employeesReadyForRender.find(emp => emp.employeeId === cedula); const currentEmp = employeesReadyForRender.find(emp => emp.employeeId === cedula);
return handleBulkSupabaseSync(cedula, blobData, currentEmp); return handleBulkSupabaseSync(cedula, blobData, currentEmp);
} }
}); });
setBulkStatusText('🎉 ¡Lote de carnets guardado correctamente!'); setBulkStatusText(` ¡Lote completado! ${employeesReadyForRender.length} carnets procesados.`);
setBulkEmployees([]); setBulkEmployees([]);
} catch (error) { } catch (error) {
console.error(error);
setBulkStatusText(`❌ Error al procesar: ${error.message || error}`); setBulkStatusText(`❌ Error al procesar: ${error.message || error}`);
} finally { } finally {
setBulkDownloadStatus({ processing: false, text: '⬇ Descargar' }); setBulkDownloadStatus({ processing: false, text: '⬇ Descargar' });
@@ -340,7 +336,6 @@ export default function IdCardGenerator() {
onStateChange: setDownloadStatus onStateChange: setDownloadStatus
}); });
} catch (err) { } catch (err) {
console.error(err);
alert(err.message); alert(err.message);
setDownloadStatus({ processing: false, text: '⬇ Descargar' }); setDownloadStatus({ processing: false, text: '⬇ Descargar' });
} }
+3 -6
View File
@@ -16,15 +16,12 @@ export default function EmployeeCard() {
async function loadEmployee() { async function loadEmployee() {
const { data, error } = await supabase const { data, error } = await supabase
.from("empleados_glm") .rpc("get_carnet_publico", { p_cedula: employeeNumber });
.select("photo_url, name, job_title, country, status")
.eq("cedula", employeeNumber)
.single();
if (error || !data) { if (error || !data || data.length === 0) {
setNotFound(true); setNotFound(true);
} else { } else {
setEmployee(data); setEmployee(data[0]);
} }
setLoading(false); setLoading(false);
+5 -6
View File
@@ -57,7 +57,7 @@ export function convertDriveUrlToDirect(url) {
return `https://drive.google.com/thumbnail?id=${match[1]}&sz=w1000`; return `https://drive.google.com/thumbnail?id=${match[1]}&sz=w1000`;
} }
} catch (e) { } catch (e) {
console.error("Error convirtiendo la URL de Drive:", e); // ignore
} }
return url; return url;
} }
@@ -70,7 +70,7 @@ export async function fetchImageAsBlob(url) {
const response = await fetch(url); const response = await fetch(url);
if (response.ok) return await response.blob(); if (response.ok) return await response.blob();
} catch (e) { } catch (e) {
console.error("Error al obtener Blob local de URL blob/data:", e); // ignore
} }
return null; return null;
} }
@@ -80,7 +80,7 @@ export async function fetchImageAsBlob(url) {
const response = await fetch(url); const response = await fetch(url);
if (response.ok) return await response.blob(); if (response.ok) return await response.blob();
} catch { } catch {
console.warn("No se pudo obtener el Blob directo de Drive debido a restricciones CORS."); // CORS blocked
} }
return null; return null;
} }
@@ -91,7 +91,6 @@ export async function fetchImageAsBlob(url) {
if (!response.ok) throw new Error("Error en respuesta de red proxy"); if (!response.ok) throw new Error("Error en respuesta de red proxy");
return await response.blob(); return await response.blob();
} catch (e) { } catch (e) {
console.error("Error haciendo fetch con bypass CORS a la imagen externa:", e);
try { try {
const response = await fetch(url, { mode: 'cors' }); const response = await fetch(url, { mode: 'cors' });
return await response.blob(); return await response.blob();
@@ -269,7 +268,7 @@ export async function downloadIDCards(config) {
const backCanvas = await html2canvasLib(vBack, renderOpts); const backCanvas = await html2canvasLib(vBack, renderOpts);
executeFileDownload(backCanvas.toDataURL('image/png'), `${cleanName}Reverso.png`); executeFileDownload(backCanvas.toDataURL('image/png'), `${cleanName}Reverso.png`);
} catch (error) { } catch (error) {
console.error('Error generando las vistas en alta resolución:', error); // silent
} finally { } finally {
if (sandbox.parentNode) document.body.removeChild(sandbox); if (sandbox.parentNode) document.body.removeChild(sandbox);
if (onStateChange) onStateChange({ processing: false, text: '⬇ Descargar' }); if (onStateChange) onStateChange({ processing: false, text: '⬇ Descargar' });
@@ -334,7 +333,7 @@ export async function downloadBulkIDCards({ employees, baseUrl, onStateChange, o
} }
} }
} catch (err) { } catch (err) {
console.error(`Error guardando foto en Supabase para Cédula: ${strictCleanId}`, err); // silent
} }
} }
+6 -18
View File
@@ -12,29 +12,17 @@ export async function saveClienteProyecto(employeeNumber, clienteProyecto) {
const cleanCedula = String(employeeNumber || '').replace(/[-\s]/g, ''); const cleanCedula = String(employeeNumber || '').replace(/[-\s]/g, '');
const valorCliente = clienteProyecto || 'Generico'; const valorCliente = clienteProyecto || 'Generico';
console.log(`[Supabase] → saveClienteProyecto llamada con: cedula="${cleanCedula}", cliente_proyecto="${valorCliente}"`);
if (!cleanCedula) { if (!cleanCedula) {
console.warn('[Supabase] saveClienteProyecto abortada: cédula vacía.'); throw new Error('Cédula vacía, no se puede guardar.');
return;
} }
// CORRECCIÓN: El objeto debe llevar la cédula para que upsert funcione por conflicto const { error } = await supabase.rpc('upsert_carnet_cliente', {
const { data, error } = await supabase p_cedula: cleanCedula,
.from('carnet_empleados_creados_glm') p_cliente_proyecto: valorCliente
.upsert( });
{
cedula: cleanCedula,
cliente_proyecto: valorCliente
},
{ onConflict: 'cedula' }
)
.select();
if (error) { if (error) {
console.error(`[Supabase] ❌ Error guardando cliente_proyecto para cédula ${cleanCedula}:`, error); throw error;
} else {
console.log(`[Supabase] ✅ Guardado exitoso carnet_empleados_creados_glm:`, data);
} }
} }