veza/apps/web/src/utils/format.ts

193 lines
4.7 KiB
TypeScript
Raw Normal View History

/**
* Utilitaires pour le formatage des données
*/
export function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
2025-12-13 02:34:34 +00:00
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
}
export function formatNumber(num: number): string {
if (num < 1000) {
return num.toString();
}
if (num < 1000000) {
2025-12-13 02:34:34 +00:00
return `${(num / 1000).toFixed(1)}K`;
}
if (num < 1000000000) {
2025-12-13 02:34:34 +00:00
return `${(num / 1000000).toFixed(1)}M`;
}
2025-12-13 02:34:34 +00:00
return `${(num / 1000000000).toFixed(1)}B`;
}
2025-12-13 02:34:34 +00:00
export function formatCurrency(
amount: number,
currency: string = 'EUR',
): string {
return new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency,
}).format(amount);
}
export function formatPercentage(value: number, decimals: number = 1): string {
return `${(value * 100).toFixed(decimals)}%`;
}
2025-12-13 02:34:34 +00:00
export function truncate(
text: string,
maxLength: number,
suffix: string = '...',
): string {
if (text.length <= maxLength) {
return text;
}
return text.substring(0, maxLength - suffix.length) + suffix;
}
export function capitalize(text: string): string {
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
}
export function capitalizeWords(text: string): string {
return text.split(' ').map(capitalize).join(' ');
}
export function slugify(text: string): string {
return text
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, '')
.replace(/[\s_-]+/g, '-')
.replace(/^-+|-+$/g, '');
}
export function initials(name: string): string {
return name
.split(' ')
2025-12-13 02:34:34 +00:00
.map((word) => word.charAt(0).toUpperCase())
.join('')
.substring(0, 2);
}
export function formatUsername(username: string): string {
return `@${username}`;
}
export function formatEmail(email: string): string {
const [localPart, domain] = email.split('@');
if (localPart.length > 3) {
return `${localPart.substring(0, 3)}***@${domain}`;
}
return email;
}
export function formatPhoneNumber(phone: string): string {
// Format français: 06 12 34 56 78
const cleaned = phone.replace(/\D/g, '');
if (cleaned.length === 10) {
2025-12-13 02:34:34 +00:00
return cleaned.replace(
/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/,
'$1 $2 $3 $4 $5',
);
}
return phone;
}
export function formatBytes(bytes: number, decimals: number = 2): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
2025-12-13 02:34:34 +00:00
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
}
export function formatDuration(seconds: number): string {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = Math.floor(seconds % 60);
if (hours > 0) {
return `${hours}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
}
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
}
export function formatTimeAgo(date: Date | string): string {
const now = new Date();
const past = new Date(date);
const diffInSeconds = Math.floor((now.getTime() - past.getTime()) / 1000);
if (diffInSeconds < 60) {
2025-12-13 02:34:34 +00:00
return "À l'instant";
}
const diffInMinutes = Math.floor(diffInSeconds / 60);
if (diffInMinutes < 60) {
return `Il y a ${diffInMinutes} min`;
}
const diffInHours = Math.floor(diffInMinutes / 60);
if (diffInHours < 24) {
return `Il y a ${diffInHours}h`;
}
const diffInDays = Math.floor(diffInHours / 24);
if (diffInDays < 7) {
return `Il y a ${diffInDays}j`;
}
const diffInWeeks = Math.floor(diffInDays / 7);
if (diffInWeeks < 4) {
return `Il y a ${diffInWeeks} sem`;
}
const diffInMonths = Math.floor(diffInDays / 30);
if (diffInMonths < 12) {
return `Il y a ${diffInMonths} mois`;
}
const diffInYears = Math.floor(diffInDays / 365);
return `Il y a ${diffInYears} an${diffInYears > 1 ? 's' : ''}`;
}
2025-12-13 02:34:34 +00:00
export function formatList(
items: string[],
conjunction: string = 'et',
): string {
if (items.length === 0) return '';
if (items.length === 1) return items[0];
if (items.length === 2) return `${items[0]} ${conjunction} ${items[1]}`;
2025-12-13 02:34:34 +00:00
const lastItem = items[items.length - 1];
const otherItems = items.slice(0, -1);
2025-12-13 02:34:34 +00:00
return `${otherItems.join(', ')} ${conjunction} ${lastItem}`;
}
2025-12-13 02:34:34 +00:00
export function formatPlural(
count: number,
singular: string,
plural?: string,
): string {
if (count === 0 || count === 1) {
return `${count} ${singular}`;
}
2025-12-13 02:34:34 +00:00
return `${count} ${plural || `${singular}s`}`;
}