92 lines
3.0 KiB
JavaScript
92 lines
3.0 KiB
JavaScript
// Helper para mostrar N/A si el valor es nulo/vacío/inválido
|
|
function displayValue(value) {
|
|
if (value === null || value === undefined || value === '' || value === 'null') return 'N/A';
|
|
return value;
|
|
}
|
|
|
|
export function ClientItem(client, onView) {
|
|
const fragment = document.createDocumentFragment();
|
|
|
|
const item = document.createElement('tr');
|
|
item.className = 'client-item';
|
|
|
|
const contactsCount = client.contacts ? client.contacts.length : 0;
|
|
|
|
// Obtener texto de estado
|
|
const getStatusText = (status) => {
|
|
const statusMap = { '0': 'Inactivo', '1': 'Activo' };
|
|
return statusMap[status] || 'N/A';
|
|
};
|
|
|
|
const getStatusClass = (status) => {
|
|
const classMap = { '0': 'status-inactive', '1': 'status-active' };
|
|
return classMap[status] || 'status-unknown';
|
|
};
|
|
|
|
// Obtener iniciales para el avatar
|
|
const getInitials = () => {
|
|
if (!client.name) return '?';
|
|
const words = client.name.split(' ');
|
|
if (words.length >= 2) {
|
|
return (words[0][0] + words[1][0]).toUpperCase();
|
|
}
|
|
return client.name.substring(0, 2).toUpperCase();
|
|
};
|
|
|
|
// Generar color consistente basado en el nombre
|
|
const getAvatarColor = () => {
|
|
const colors = [
|
|
'#3b82f6', '#10b981', '#f59e0b', '#ef4444',
|
|
'#8b5cf6', '#ec4899', '#06b6d4', '#84cc16',
|
|
];
|
|
let hash = 0;
|
|
const name = client.name || '';
|
|
for (let i = 0; i < name.length; i++) {
|
|
hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
}
|
|
return colors[Math.abs(hash) % colors.length];
|
|
};
|
|
|
|
item.innerHTML = /*html*/`
|
|
<td class="client-avatar-cell">
|
|
<div class="client-avatar" style="background-color: ${getAvatarColor()}">
|
|
${getInitials()}
|
|
</div>
|
|
</td>
|
|
<td class="client-name">
|
|
<div class="client-name-wrapper">
|
|
<span class="client-company-name">${displayValue(client.name)}</span>
|
|
<span class="client-code">${displayValue(client.codeClient)}</span>
|
|
</div>
|
|
</td>
|
|
<td class="client-type">${displayValue(client.typentCode)}</td>
|
|
<td class="client-status">
|
|
<span class="status-badge-client ${getStatusClass(client.status)}">${getStatusText(client.status)}</span>
|
|
</td>
|
|
<td class="client-email">
|
|
<span class="email-text" title="${displayValue(client.email)}">${displayValue(client.email)}</span>
|
|
</td>
|
|
<td class="client-phone">${displayValue(client.phone)}</td>
|
|
<td class="client-actions">
|
|
<button class="btn-action btn-view" data-client-id="${client.id}" title="Ver detalles">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
|
<circle cx="12" cy="12" r="3"/>
|
|
</svg>
|
|
</button>
|
|
</td>
|
|
`;
|
|
|
|
fragment.appendChild(item);
|
|
|
|
// Event listener para el botón de ver
|
|
const viewBtn = item.querySelector('.btn-view');
|
|
viewBtn.addEventListener('click', () => {
|
|
if (onView) {
|
|
onView(client.id);
|
|
}
|
|
});
|
|
|
|
return fragment;
|
|
}
|