Files
btpxpress-frontend/utils/formatters.ts
2025-10-01 01:39:07 +00:00

176 lines
5.3 KiB
TypeScript

/**
* Utilitaires de formatage pour l'application BTP Xpress
*/
/**
* Formate un montant en devise avec le symbole Euro
* @param amount - Le montant à formater
* @param currency - La devise (par défaut EUR)
* @returns Le montant formaté avec le symbole de devise
*/
export const formatCurrency = (amount: number, currency: string = 'EUR'): string => {
return new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency: currency,
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount);
};
/**
* Formate un nombre avec des séparateurs de milliers
* @param value - Le nombre à formater
* @returns Le nombre formaté avec séparateurs
*/
export const formatNumber = (value: number): string => {
return new Intl.NumberFormat('fr-FR').format(value);
};
/**
* Formate une date en français
* @param date - La date à formater
* @param options - Options de formatage
* @returns La date formatée
*/
export const formatDate = (date: string | Date, options?: Intl.DateTimeFormatOptions): string => {
const dateObj = typeof date === 'string' ? new Date(date) : date;
const defaultOptions: Intl.DateTimeFormatOptions = {
day: '2-digit',
month: '2-digit',
year: 'numeric'
};
return new Intl.DateTimeFormat('fr-FR', options || defaultOptions).format(dateObj);
};
/**
* Formate une date et heure en français
* @param datetime - La date/heure à formater
* @returns La date/heure formatée
*/
export const formatDateTime = (datetime: string | Date): string => {
const dateObj = typeof datetime === 'string' ? new Date(datetime) : datetime;
return new Intl.DateTimeFormat('fr-FR', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
}).format(dateObj);
};
/**
* Formate un pourcentage
* @param value - La valeur à formater (entre 0 et 1 ou 0 et 100)
* @param isDecimal - Si true, la valeur est entre 0 et 1, sinon entre 0 et 100
* @returns Le pourcentage formaté
*/
export const formatPercentage = (value: number, isDecimal: boolean = false): string => {
const percentage = isDecimal ? value * 100 : value;
return new Intl.NumberFormat('fr-FR', {
style: 'percent',
minimumFractionDigits: 0,
maximumFractionDigits: 2
}).format(isDecimal ? value : value / 100);
};
/**
* Formate une durée en jours
* @param days - Le nombre de jours
* @returns La durée formatée
*/
export const formatDuration = (days: number): string => {
if (days === 0) return 'Aujourd\'hui';
if (days === 1) return '1 jour';
if (days === -1) return 'Il y a 1 jour';
if (days > 0) return `${days} jours`;
return `Il y a ${Math.abs(days)} jour${Math.abs(days) > 1 ? 's' : ''}`;
};
/**
* Formate la taille d'un fichier
* @param bytes - La taille en bytes
* @returns La taille formatée
*/
export const formatFileSize = (bytes: number): string => {
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return '0 B';
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
};
/**
* Formate un nom complet à partir du prénom et nom
* @param prenom - Le prénom
* @param nom - Le nom
* @returns Le nom complet formaté
*/
export const formatFullName = (prenom: string, nom: string): string => {
return `${prenom} ${nom}`.trim();
};
/**
* Formate une adresse complète
* @param adresse - L'adresse
* @param codePostal - Le code postal
* @param ville - La ville
* @returns L'adresse complète formatée
*/
export const formatAddress = (adresse?: string, codePostal?: string, ville?: string): string => {
const parts = [adresse, codePostal, ville].filter(part => part && part.trim());
return parts.join(', ');
};
/**
* Formate un numéro de téléphone français
* @param telephone - Le numéro de téléphone
* @returns Le numéro formaté
*/
export const formatPhoneNumber = (telephone: string): string => {
// Supprime tous les caractères non numériques
const cleaned = telephone.replace(/\D/g, '');
// Vérifie si c'est un numéro français (10 chiffres)
if (cleaned.length === 10) {
return cleaned.replace(/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/, '$1 $2 $3 $4 $5');
}
// Retourne le numéro tel quel si ce n'est pas un format français standard
return telephone;
};
/**
* Tronque un texte à une longueur donnée
* @param text - Le texte à tronquer
* @param maxLength - La longueur maximale
* @returns Le texte tronqué
*/
export const truncateText = (text: string, maxLength: number): string => {
if (text.length <= maxLength) return text;
return text.substring(0, maxLength - 3) + '...';
};
/**
* Capitalise la première lettre d'une chaîne
* @param str - La chaîne à capitaliser
* @returns La chaîne capitalisée
*/
export const capitalize = (str: string): string => {
if (!str) return '';
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
};
/**
* Formate un statut pour l'affichage
* @param status - Le statut brut
* @returns Le statut formaté
*/
export const formatStatus = (status: string): string => {
return status
.split('_')
.map(word => capitalize(word))
.join(' ');
};