import { routes, getAvatarUrl, booleanStatusCatalog, statusIntBadgeBgCatalogCss, statusIntBadgeBgCatalog } from '@vuexy-admin/assets/js/bootstrap-table/globalConfig'; export const userActionFormatter = (value, row, index) => { if (!row.id) return ''; const showUrl = routes['admin.user.show'].replace(':id', row.id); const editUrl = routes['admin.user.edit'].replace(':id', row.id); const deleteUrl = routes['admin.user.delete'].replace(':id', row.id); return `
`.trim(); }; export const userLoginActionFormatter = (value, row, index) => { if (!row.user_id) return ''; //const showUrl = routes['admin.user-login.show'].replace(':id', row.user_id); const showUrl = '#'; return `
`.trim(); }; export const dynamicBooleanFormatter = (value, row, index, options = {}) => { const { tag = 'default', customOptions = {} } = options; const catalogConfig = booleanStatusCatalog[tag] || {}; const finalOptions = { ...catalogConfig, ...customOptions, // Permite sobreescribir la configuración predeterminada ...options // Permite pasar opciones rápidas }; const { trueIcon = '', falseIcon = '', trueText = 'Sí', falseText = 'No', trueClass = 'badge bg-label-success', falseClass = 'badge bg-label-danger', iconClass = 'text-green-800' } = finalOptions; const trueElement = !trueIcon && !trueText ? '' : `${trueIcon ? ` ` : ''}${trueText}`; const falseElement = !falseIcon && !falseText ? '' : `${falseIcon ? ` ` : ''}${falseText}`; return value? trueElement : falseElement; }; export const dynamicBadgeFormatter = (value, row, index, options = {}) => { if (!value) return ''; const { color = 'primary', // Valor por defecto textColor = '', // Permite agregar color de texto si es necesario additionalClass = '' // Permite añadir clases adicionales } = options; return `${value}`; }; export const statusIntBadgeBgFormatter = (value, row, index) => { return value ? `${statusIntBadgeBgCatalog[value]}` : ''; } export const textNowrapFormatter = (value, row, index) => { if (!value) return ''; return `${value}`; } export const textXsFormatter = (value, row, index) => { if (!value) return ''; return `${value}`; }; export const dateClassicFormatter = (value) => { if (!value) return ''; const date = new Date(value); if (isNaN(date)) return value; const fecha = date.toLocaleDateString('es-MX', { day: '2-digit', month: '2-digit', year: 'numeric' }); const hora = value.length == 19? date.toLocaleTimeString('es-MX', { hour: '2-digit', minute: '2-digit' }): false; let fechaHora = hora ? ` ${fecha} ` : ` ${fecha} `; if (hora) { fechaHora += ` ${hora} `.trim(); } return fechaHora.trim(); }; export const dateLimeFormatter = (value) => { if (!value) return ''; const date = new Date(value); if (isNaN(date)) return value; const fecha = date.toLocaleDateString('es-MX', { day: '2-digit', month: '2-digit', year: 'numeric' }); const hora = value.length == 19? date.toLocaleTimeString('es-MX', { hour: '2-digit', minute: '2-digit' }): false; let fechaHora = hora ? ` ${fecha} ` : ` ${fecha} `; if (hora) { fechaHora += ` ${hora} `.trim(); } return fechaHora.trim(); }; export const dateBadgeBlueFormatter = (value) => { if (!value) return ''; const date = new Date(value); if (isNaN(date)) return value; const fecha = date.toLocaleDateString('es-MX', { day: '2-digit', month: '2-digit', year: 'numeric' }); const hora = value.length == 19? date.toLocaleTimeString('es-MX', { hour: '2-digit', minute: '2-digit' }): false; let fechaHora = hora ? ` ${fecha} ` : ` ${fecha} `; if (hora) { fechaHora += ` ${hora} `.trim(); } return fechaHora.trim(); }; export const dateBadgeAmberFormatter = (value) => { if (!value) return ''; const date = new Date(value); if (isNaN(date)) return value; const fecha = date.toLocaleDateString('es-MX', { day: '2-digit', month: '2-digit', year: 'numeric' }); const hora = value.length == 19? date.toLocaleTimeString('es-MX', { hour: '2-digit', minute: '2-digit' }): false; let fechaHora = hora ? ` ${fecha} ` : ` ${fecha} `; if (hora) { fechaHora += ` ${hora} `.trim(); } return fechaHora.trim(); }; export const emailFormatter = (value, row, index) => { if (!value) return ''; return ` ${value} `.trim(); }; /** * Formatter para mostrar duración de sesión del usuario. * * @param {string} row.created_at - Fecha de inicio de sesión. * @param {string|null} row.logout_at - Fecha de cierre de sesión o null si aún activa. * @returns {string} Duración de la sesión formateada o estado de sesión activa. */ export const sessionDurationFormatter = (value, row, index) => { if (!row.created_at) return '-'; const start = new Date(row.created_at); const end = row.logout_at ? new Date(row.logout_at) : new Date(); const diffMs = end - start; if (diffMs < 0) return 'Invalido'; const diffSeconds = Math.floor(diffMs / 1000); const hours = Math.floor(diffSeconds / 3600); const minutes = Math.floor((diffSeconds % 3600) / 60); const seconds = diffSeconds % 60; const formattedTime = [ hours ? `${hours}h` : '', minutes ? `${minutes}m` : '', `${seconds}s` ].filter(Boolean).join(' '); return row.logout_at ? `${formattedTime}` : `🟢 Sesión activa (${formattedTime})`; }; /** * @param {int} row.id - Identificador del usuario * @param {string} row.full_name - Nombre completo del usuario * @param {string} row.profile_photo_path - Ruta de la foto de perfil * @param {string} row.email - Correo electrónico del usuario * @returns {string} HTML con el perfil del usuario */ export const userIdProfileFormatter = (value, row, index) => { if (!row.id) return ''; const avatar = getAvatarUrl(row.full_name, row.profile_photo_path); const email = row.email ? row.email : 'Sin correo'; const profileUrl = routes['admin.user.show'].replace(':id', row.id); return formatterProfileElement(row.id, row.full_name, avatar, email, profileUrl); }; const formatterProfileElement = (id, name, avatar, email, profileUrl) => { return `
Avatar
${name} ${email}
`.trim(); }; /** * @param {int} row.user_id - Identificador del usuario * @param {string} row.user_name - Nombre del usuario * @param {string} row.user_profile_photo_path - Ruta de la foto de perfil * @param {string} row.user_email - Correo electrónico del usuario * @returns {string} HTML con el perfil del usuario */ export const userProfileFormatter = (value, row, index) => { if (!row.user_id) return ''; const profileUrl = routes['admin.user.show'].replace(':id', row.user_id); const avatar = getAvatarUrl(row.user_name, row.user_profile_photo_path); const email = row.user_email ? row.user_email : 'Sin correo'; return `
Avatar
${row.user_name} ${email}
`.trim(); }; export const creatorProfileFormatter = (value, row, index) => { if (!row.created_by) return ''; const profileUrl = routes['admin.user.show'].replace(':id', row.created_by); const avatar = getAvatarUrl(row.creator_name, row.creator_profile_photo_path); const email = row.creator_email ? row.creator_email : 'Sin correo'; return `
Avatar
${row.creator_name} ${email}
`.trim(); }; export const updaterProfileFormatter = (value, row, index) => { if (!row.updated_by) return ''; const profileUrl = routes['admin.user.show'].replace(':id', row.updated_by); const avatar = getAvatarUrl(row.updater_name, row.updater_profile_photo_path); const email = row.updater_email ? row.updater_email : 'Sin correo'; return `
Avatar
${row.updater_name} ${email}
`.trim(); }; /** * Convierte bytes en un formato legible por humanos. * * @param {int} value - Valor en bytes * @returns {string} Tamaño en formato legible */ export const bytesToHumanReadable = (value, row, index) => { if (!value || value === 0) return; const precision = 2; // define aquí la precisión que desees const units = ['B', 'KB', 'MB', 'GB', 'TB']; const base = Math.floor(Math.log(value) / Math.log(1024)); return (value / Math.pow(1024, base)).toFixed(precision) + ' ' + units[base]; }; export const userRoleFormatter = (value, row, index) => { if (!value) return ''; const rolesStyles = window.userRoleStyles || {}; return value.split('|').map(role => { const trimmedRole = role.trim(); const color = rolesStyles[trimmedRole] || 'secondary'; // fallback si no existe return `${trimmedRole}`; }).join(''); }; export const booleanStatusFormatter = (value, row, index) => { return `${value ? 'Activo' : 'Inactivo'}`; };