trello_fake/types/user.ts

227 lines
5.3 KiB
TypeScript

/**
* Tipos para usuarios de Dolibarr
*/
// Respuesta cruda de la API de Dolibarr para usuarios
export interface DolibarrUser {
id: string;
ref: string;
login: string;
entity: string;
// Información personal
firstname: string | null;
lastname: string;
gender: string | null;
birth: string;
civility_id: string | null;
civility_code: string | null;
// Contacto
email: string | null;
email_oauth2: string | null;
personal_email: string | null;
office_phone: string | null;
office_fax: string | null;
user_mobile: string | null;
personal_mobile: string | null;
// Dirección
address: string | null;
zip: string | null;
town: string | null;
country_id: string;
country_code: string;
state_id: string;
// Trabajo
employee: string;
job: string | null;
salary: string | null;
salaryextra: string | null;
weeklyhours: string | null;
thm: string | null; // taux horaire moyen
tjm: string | null; // taux journalier moyen
dateemployment: string;
dateemploymentend: string;
ref_employee: string | null;
fk_establishment: string;
label_establishment: string | null;
// Estado y permisos
status: string;
statut: string;
admin: string;
// Empresa/Tercero asociado
socid: string | null;
// Sesión y actividad
datelastlogin: number | null;
datepreviouslogin: string;
iplastlogin: string | null;
ippreviouslogin: string | null;
datestartvalidity: string;
dateendvalidity: string;
// Otros
photo: string | null;
lang: string | null;
color: string | null;
signature: string | null;
national_registration_number: string | null;
// Metadatos
date_creation: string | null;
date_modification: string | null;
datec: string;
datem: number | null;
// Social
socialnetworks: Record<string, string> | string[];
// Configuración
rights: DolibarrUserRights;
conf: Record<string, unknown>;
array_options: Record<string, unknown> | unknown[];
}
export interface DolibarrUserRights {
user?: {
user?: Record<string, unknown>;
self?: Record<string, unknown>;
user_advance?: Record<string, unknown>;
self_advance?: Record<string, unknown>;
group_advance?: Record<string, unknown>;
};
[key: string]: unknown;
}
// Tipo UI para mostrar en la aplicación
export interface UserProfile {
id: string;
login: string;
// Nombre completo
firstname: string;
lastname: string;
fullName: string;
initials: string;
// Contacto
email: string | null;
personalEmail: string | null;
phone: string | null;
mobile: string | null;
// Ubicación
address: string | null;
city: string | null;
postalCode: string | null;
country: string | null;
// Trabajo
job: string | null;
isEmployee: boolean;
employmentStartDate: Date | null;
employmentEndDate: Date | null;
establishment: string | null;
// Estado
isActive: boolean;
isAdmin: boolean;
// Actividad
lastLogin: Date | null;
lastLoginIp: string | null;
// Otros
photo: string | null;
language: string | null;
// Datos crudos para campos adicionales
raw: DolibarrUser;
}
/**
* Mapea respuesta de Dolibarr a tipo UI
*/
export function mapDolibarrUser(raw: DolibarrUser): UserProfile {
const firstname = raw.firstname || '';
const lastname = raw.lastname || '';
const fullName = [firstname, lastname].filter(Boolean).join(' ') || raw.login;
// Generar iniciales
const initials = firstname && lastname
? `${firstname.charAt(0)}${lastname.charAt(0)}`.toUpperCase()
: fullName.substring(0, 2).toUpperCase();
return {
id: raw.id,
login: raw.login,
firstname,
lastname,
fullName,
initials,
email: raw.email,
personalEmail: raw.personal_email,
phone: raw.office_phone,
mobile: raw.user_mobile || raw.personal_mobile,
address: raw.address,
city: raw.town,
postalCode: raw.zip,
country: raw.country_code || null,
job: raw.job,
isEmployee: raw.employee === '1',
employmentStartDate: raw.dateemployment ? new Date(raw.dateemployment) : null,
employmentEndDate: raw.dateemploymentend ? new Date(raw.dateemploymentend) : null,
establishment: raw.label_establishment,
isActive: raw.status === '1',
isAdmin: raw.admin === '1',
lastLogin: raw.datelastlogin ? new Date(raw.datelastlogin * 1000) : null,
lastLoginIp: raw.iplastlogin,
photo: raw.photo,
language: raw.lang,
raw,
};
}
/**
* Helper para obtener nombre a mostrar
*/
export function getDisplayName(user: UserProfile): string {
return user.fullName || user.login;
}
/**
* Helper para formatear fecha de último login
*/
export function formatLastLogin(date: Date | null): string {
if (!date) return 'Nunca';
const now = new Date();
const diffMs = now.getTime() - date.getTime();
const diffMins = Math.floor(diffMs / 60000);
const diffHours = Math.floor(diffMs / 3600000);
const diffDays = Math.floor(diffMs / 86400000);
if (diffMins < 1) return 'Hace un momento';
if (diffMins < 60) return `Hace ${diffMins} minuto${diffMins !== 1 ? 's' : ''}`;
if (diffHours < 24) return `Hace ${diffHours} hora${diffHours !== 1 ? 's' : ''}`;
if (diffDays < 7) return `Hace ${diffDays} día${diffDays !== 1 ? 's' : ''}`;
return date.toLocaleDateString('es-ES', {
day: 'numeric',
month: 'short',
year: 'numeric',
});
}