feat: Se añadio los campos division, departamento y pais
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -7,7 +7,7 @@
|
||||
href="https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_white_background.jpg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>glm-card-generator</title>
|
||||
<script type="module" crossorigin src="/empleado-id/assets/index-EuHkvm43.js"></script>
|
||||
<script type="module" crossorigin src="/empleado-id/assets/index-C9T6gjmL.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/empleado-id/assets/index-DRjn2cG3.css">
|
||||
</head>
|
||||
|
||||
|
||||
Binary file not shown.
@@ -46,6 +46,8 @@ export default function IdCardGenerator() {
|
||||
// --- Estados formulario individual ───
|
||||
const [name, setName] = useState('');
|
||||
const [role, setRole] = useState('');
|
||||
const [department, setDepartment] = useState('');
|
||||
const [country, setCountry] = useState('');
|
||||
const [language, setLanguage] = useState('Esp');
|
||||
const [selectedClient, setSelectedClient] = useState('Generico');
|
||||
const [employeeId, setEmployeeId] = useState('');
|
||||
@@ -58,23 +60,25 @@ export default function IdCardGenerator() {
|
||||
// --- Estados Reporte de Errores/Ayuda ───
|
||||
const [showReportModal, setShowReportModal] = useState(false);
|
||||
const [reportMessage, setReportMessage] = useState('');
|
||||
const [reportEmail, setReportEmail] = useState('');
|
||||
const [reportSending, setReportSending] = useState(false);
|
||||
const [reportSent, setReportSent] = useState(false);
|
||||
const reportCloseTimeoutRef = useRef(null);
|
||||
const [fabAttention, setFabAttention] = useState(false);
|
||||
const fabAttentionTimeoutRef = useRef(null);
|
||||
|
||||
// Bloquea el botón Descargar hasta que nombre, puesto e ID estén llenos
|
||||
const isFormComplete = name.trim() && role.trim() && employeeId.trim();
|
||||
// Bloquea el botón Descargar hasta que nombre, departamento, puesto, país, ID y foto estén llenos
|
||||
const isFormComplete = name.trim() && department.trim() && role.trim() && country.trim() && employeeId.trim() && photoFile;
|
||||
|
||||
// --- Estados Lote / Excel Masivo ───
|
||||
const [bulkEmployees, setBulkEmployees] = useState([]);
|
||||
const [bulkStatusText, setBulkStatusText] = useState('');
|
||||
const [bulkDownloadStatus, setBulkDownloadStatus] = useState({ processing: false, text: '⬇ Descargar' });
|
||||
const [bulkCountry, setBulkCountry] = useState('');
|
||||
const [showTooltip, setShowTooltip] = useState(false);
|
||||
|
||||
const handleSendReport = async () => {
|
||||
if (!reportMessage.trim() || reportSending) {
|
||||
if (!reportMessage.trim() || !reportEmail.trim() || reportSending) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -89,6 +93,7 @@ export default function IdCardGenerator() {
|
||||
body: JSON.stringify({
|
||||
subject: 'Reporte - Generador de ID',
|
||||
body: reportMessage.trim(),
|
||||
email: reportEmail.trim(),
|
||||
fecha: new Date().toISOString()
|
||||
})
|
||||
});
|
||||
@@ -98,6 +103,7 @@ export default function IdCardGenerator() {
|
||||
}
|
||||
|
||||
setReportMessage('');
|
||||
setReportEmail('');
|
||||
setReportSent(true);
|
||||
reportCloseTimeoutRef.current = setTimeout(() => {
|
||||
setShowReportModal(false);
|
||||
@@ -250,10 +256,12 @@ export default function IdCardGenerator() {
|
||||
if (!cleanCedula) return;
|
||||
|
||||
try {
|
||||
const clienteProyectoValue = currentEmployee?.selectedClient || 'Generico';
|
||||
const divisionValue = currentEmployee?.division || '';
|
||||
const departamentoValue = currentEmployee?.department || '';
|
||||
const posicionValue = currentEmployee?.position || '';
|
||||
const paisValue = bulkCountry || '';
|
||||
|
||||
// 1) Guardar cédula + cliente_proyecto en carnet_empleados_creados_glm
|
||||
await saveClienteProyecto(cleanCedula, clienteProyectoValue);
|
||||
await saveClienteProyecto(cleanCedula, divisionValue, departamentoValue, posicionValue, paisValue);
|
||||
|
||||
} catch (error) {
|
||||
// silent
|
||||
@@ -314,12 +322,16 @@ export default function IdCardGenerator() {
|
||||
return {
|
||||
name: String(row.nombre || '').trim(),
|
||||
role: String(row.puesto || '').trim(),
|
||||
department: String(row.departamento || '').trim(),
|
||||
position: String(row.posicion || '').trim(),
|
||||
division: String(row.division || '').trim(),
|
||||
country: String(row.pais || '').trim(),
|
||||
selectedClient: rawClient,
|
||||
language: rawLang,
|
||||
employeeId: cleanedCedula,
|
||||
fotoUrl: String(row.foto_url || '').trim()
|
||||
};
|
||||
}).filter(emp => emp.name && emp.role && emp.employeeId);
|
||||
}).filter(emp => emp.name && emp.employeeId);
|
||||
|
||||
setBulkEmployees(formatted);
|
||||
setBulkStatusText(`✅ ¡Cargados ${formatted.length} colaboradores! Listo para procesar.`);
|
||||
@@ -361,6 +373,10 @@ export default function IdCardGenerator() {
|
||||
return {
|
||||
name: n8nEmp.name || originalEmp.name,
|
||||
role: n8nEmp.role || originalEmp.role,
|
||||
department: n8nEmp.department || originalEmp.department || '',
|
||||
position: n8nEmp.position || originalEmp.position || '',
|
||||
division: n8nEmp.division || originalEmp.division || '',
|
||||
country: n8nEmp.country || originalEmp.country || '',
|
||||
selectedClient: validClient,
|
||||
language: validLang,
|
||||
employeeId: n8nEmp.employeeId || originalEmp.employeeId,
|
||||
@@ -442,21 +458,34 @@ export default function IdCardGenerator() {
|
||||
// Guardar cédula + cliente_proyecto en carnet_empleados_creados_glm al completar descarga
|
||||
const cleanCedula = String(employeeId || '').replace(/[-\s]/g, '');
|
||||
if (cleanCedula) {
|
||||
await saveClienteProyecto(cleanCedula, selectedClient);
|
||||
try {
|
||||
await saveClienteProyecto(cleanCedula, selectedClient, department, role, country);
|
||||
} catch (saveError) {
|
||||
console.error('Error al guardar en Supabase:', saveError);
|
||||
// No lanzamos el error para que la descarga se complete
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error al generar el carnet:', err);
|
||||
console.error('Detalles del error:', {
|
||||
name: err?.name,
|
||||
message: err?.message,
|
||||
stack: err?.stack,
|
||||
friendly: err?.friendly
|
||||
});
|
||||
triggerFabAttention();
|
||||
alert(err?.friendly
|
||||
? err.message
|
||||
: 'Algo salió mal al generar el carnet. Inténtalo de nuevo; si sigue fallando, avísanos con el botón de ayuda.');
|
||||
: `Algo salió mal al generar el carnet. Error: ${err?.message || 'Desconocido'}`);
|
||||
setDownloadStatus({ processing: false, text: '⬇ Descargar' });
|
||||
}
|
||||
};
|
||||
|
||||
const validateForm = () => {
|
||||
if (!name.trim()) { alert("Escribe el nombre del colaborador para continuar."); return false; }
|
||||
if (!department.trim()) { alert("Escribe el departamento del colaborador para continuar."); return false; }
|
||||
if (!role.trim()) { alert("Escribe el puesto del colaborador para continuar."); return false; }
|
||||
if (!country.trim()) { alert("Selecciona el país del colaborador para continuar."); return false; }
|
||||
if (!employeeId.trim()) { alert("Escribe el ID o cédula del colaborador para continuar."); return false; }
|
||||
if (!photoFile) { alert("Sube la foto del colaborador para continuar."); return false; }
|
||||
return true;
|
||||
@@ -502,7 +531,7 @@ export default function IdCardGenerator() {
|
||||
fontWeight: 'normal', textTransform: 'none'
|
||||
}}>
|
||||
Formato de columnas requeridas en el Excel: <br />
|
||||
<b style={{ color: '#6CC24A' }}>nombre, puesto, cliente/proyecto, cedula, lenguaje, foto_url</b>.<br />
|
||||
<b style={{ color: '#6CC24A' }}>nombre, puesto, departamento, division, posicion, pais, cliente/proyecto, cedula, lenguaje, foto_url</b>.<br />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -542,6 +571,24 @@ export default function IdCardGenerator() {
|
||||
{bulkStatusText}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="field" style={{ marginTop: '12px' }}>
|
||||
<label>País</label>
|
||||
<select value={bulkCountry} onChange={(e) => setBulkCountry(e.target.value)}>
|
||||
<option value="">Selecciona un país</option>
|
||||
<option value="Republica Dominicana">República Dominicana</option>
|
||||
<option value="Guatemala">Guatemala</option>
|
||||
<option value="El Salvador">El Salvador</option>
|
||||
<option value="Honduras">Honduras</option>
|
||||
<option value="Nicaragua">Nicaragua</option>
|
||||
<option value="Costa Rica">Costa Rica</option>
|
||||
<option value="Mexico">México</option>
|
||||
<option value="Colombia">Colombia</option>
|
||||
<option value="Jamaica">Jamaica</option>
|
||||
<option value="Panama">Panamá</option>
|
||||
<option value="Trinidad and Tobago">Trinidad and Tobago</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divider"></div>
|
||||
@@ -550,9 +597,9 @@ export default function IdCardGenerator() {
|
||||
<div className="panel-section-title">Exportar Lote</div>
|
||||
<button
|
||||
className="export-btn blue"
|
||||
disabled={bulkDownloadStatus.processing || bulkEmployees.length === 0}
|
||||
disabled={bulkDownloadStatus.processing || bulkEmployees.length === 0 || !bulkCountry.trim()}
|
||||
onClick={triggerBulkDownload}
|
||||
style={{ opacity: bulkEmployees.length === 0 ? 0.6 : 1 }}
|
||||
style={{ opacity: (bulkEmployees.length === 0 || !bulkCountry.trim()) ? 0.6 : 1 }}
|
||||
>
|
||||
{bulkDownloadStatus.text}
|
||||
</button>
|
||||
@@ -572,10 +619,31 @@ export default function IdCardGenerator() {
|
||||
<label>Nombre</label>
|
||||
<input type="text" placeholder="Ej: Alexi Zabala" value={name} onChange={(e) => setName(e.target.value)} />
|
||||
</div>
|
||||
<div className="field">
|
||||
<label>Departamento</label>
|
||||
<input type="text" placeholder="Ej: Mercadeo" value={department} onChange={(e) => setDepartment(e.target.value)} />
|
||||
</div>
|
||||
<div className="field">
|
||||
<label>Puesto</label>
|
||||
<input type="text" placeholder="Ej: Mercaderista" value={role} onChange={(e) => setRole(e.target.value)} />
|
||||
</div>
|
||||
<div className="field">
|
||||
<label>País</label>
|
||||
<select value={country} onChange={(e) => setCountry(e.target.value)}>
|
||||
<option value="">Selecciona un país</option>
|
||||
<option value="Republica Dominicana">República Dominicana</option>
|
||||
<option value="Guatemala">Guatemala</option>
|
||||
<option value="El Salvador">El Salvador</option>
|
||||
<option value="Honduras">Honduras</option>
|
||||
<option value="Nicaragua">Nicaragua</option>
|
||||
<option value="Costa Rica">Costa Rica</option>
|
||||
<option value="Mexico">México</option>
|
||||
<option value="Colombia">Colombia</option>
|
||||
<option value="Jamaica">Jamaica</option>
|
||||
<option value="Panama">Panamá</option>
|
||||
<option value="Trinidad and Tobago">Trinidad and Tobago</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="upload-btn" onClick={() => !photoProcessing && fileInputRef.current.click()} style={{ opacity: photoProcessing ? 0.6 : 1, cursor: photoProcessing ? 'wait' : 'pointer' }}>
|
||||
{photoProcessing ? '⏳ Procesando foto con IA...' : 'Subir foto del colaborador'}
|
||||
</div>
|
||||
@@ -708,6 +776,7 @@ export default function IdCardGenerator() {
|
||||
setFabAttention(false);
|
||||
clearTimeout(reportCloseTimeoutRef.current);
|
||||
setReportMessage('');
|
||||
setReportEmail('');
|
||||
setReportSent(false);
|
||||
setShowReportModal(true);
|
||||
}}
|
||||
@@ -745,6 +814,15 @@ export default function IdCardGenerator() {
|
||||
</button>
|
||||
</div>
|
||||
<div className="report-modal-body">
|
||||
<p className="report-modal-hint" style={{ marginBottom: '8px' }}>Correo electrónico</p>
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Ej: correo@ejemplo.com"
|
||||
value={reportEmail}
|
||||
onChange={(e) => setReportEmail(e.target.value)}
|
||||
disabled={reportSending}
|
||||
style={{ width: '100%', padding: '8px 12px', border: '1px solid #cbd5e1', borderRadius: '6px', fontSize: '13px', boxSizing: 'border-box' }}
|
||||
/>
|
||||
<p className="report-modal-hint">Describe el problema o tu solicitud:</p>
|
||||
<textarea
|
||||
className="report-modal-textarea"
|
||||
@@ -756,10 +834,10 @@ export default function IdCardGenerator() {
|
||||
/>
|
||||
</div>
|
||||
<div className="report-modal-footer">
|
||||
<button className="report-modal-cancel" onClick={() => { setShowReportModal(false); setReportMessage(''); }} disabled={reportSending}>
|
||||
<button className="report-modal-cancel" onClick={() => { setShowReportModal(false); setReportMessage(''); setReportEmail(''); }} disabled={reportSending}>
|
||||
Cancelar
|
||||
</button>
|
||||
<button className="report-modal-send" onClick={handleSendReport} disabled={!reportMessage.trim() || reportSending}>
|
||||
<button className="report-modal-send" onClick={handleSendReport} disabled={!reportMessage.trim() || !reportEmail.trim() || reportSending}>
|
||||
{reportSending ? '🔄 Enviando...' : 'Enviar'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { supabase } from "./supabase";
|
||||
|
||||
/**
|
||||
* Registra el cliente/proyecto de un carnet descargado en la tabla
|
||||
* Registra los datos de un carnet descargado en la tabla
|
||||
* "carnet_empleados_creados_glm".
|
||||
*
|
||||
* @param {string} employeeNumber - Número de cédula limpio (sin guiones/espacios)
|
||||
* @param {string} clienteProyecto - Nombre del cliente/proyecto seleccionado
|
||||
* @param {string} division - Cliente/Proyecto seleccionado
|
||||
* @param {string} departamento - Departamento del empleado
|
||||
* @param {string} posicion - Puesto del empleado
|
||||
* @param {string} pais - País del empleado
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function saveClienteProyecto(employeeNumber, clienteProyecto) {
|
||||
export async function saveClienteProyecto(employeeNumber, division = '', departamento = '', posicion = '', pais = '') {
|
||||
const cleanCedula = String(employeeNumber || '').replace(/[-\s]/g, '');
|
||||
const valorCliente = clienteProyecto || 'Generico';
|
||||
|
||||
if (!cleanCedula) {
|
||||
throw new Error('Cédula vacía, no se puede guardar.');
|
||||
@@ -18,7 +20,11 @@ export async function saveClienteProyecto(employeeNumber, clienteProyecto) {
|
||||
|
||||
const { error } = await supabase.rpc('upsert_carnet_cliente', {
|
||||
p_cedula: cleanCedula,
|
||||
p_cliente_proyecto: valorCliente
|
||||
p_cliente_proyecto: division || 'Generico',
|
||||
p_division: division,
|
||||
p_departamento: departamento,
|
||||
p_posicion: posicion,
|
||||
p_pais: pais
|
||||
});
|
||||
|
||||
if (error) {
|
||||
|
||||
Reference in New Issue
Block a user