176 lines
5.3 KiB
TypeScript
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(' ');
|
|
}; |