Checkpoint: Application Budget Renouvellement SI 2027 Itinova — Version complète avec dashboard KPIs, grille des 75 établissements, panneau de détail par établissement avec tableau de synthèse et liste des équipements filtrables.
This commit is contained in:
72
client/src/lib/format.ts
Normal file
72
client/src/lib/format.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
// Utilitaires de formatage — Budget SI 2027 Itinova
|
||||
|
||||
/**
|
||||
* Formate un montant en euros avec séparateur de milliers
|
||||
*/
|
||||
export function formatEuros(amount: number): string {
|
||||
return new Intl.NumberFormat('fr-FR', {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate un nombre avec séparateur de milliers
|
||||
*/
|
||||
export function formatNumber(n: number): string {
|
||||
return new Intl.NumberFormat('fr-FR').format(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne la couleur de vétusté selon l'âge
|
||||
*/
|
||||
export function getVetusteColor(ageAns: number | null, type: 'fixe' | 'portable'): string {
|
||||
if (ageAns === null) return 'text-muted-foreground';
|
||||
const seuil = type === 'fixe' ? 5 : 4;
|
||||
if (ageAns >= seuil + 2) return 'text-red-600';
|
||||
if (ageAns >= seuil) return 'text-orange-500';
|
||||
if (ageAns >= seuil - 1) return 'text-yellow-600';
|
||||
return 'text-green-600';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne la classe de badge de vétusté
|
||||
*/
|
||||
export function getVetusteBadgeClass(ageAns: number | null, type: 'fixe' | 'portable'): string {
|
||||
if (ageAns === null) return 'bg-gray-100 text-gray-500';
|
||||
const seuil = type === 'fixe' ? 5 : 4;
|
||||
if (ageAns >= seuil + 2) return 'bg-red-100 text-red-700 border border-red-200';
|
||||
if (ageAns >= seuil) return 'bg-orange-100 text-orange-700 border border-orange-200';
|
||||
if (ageAns >= seuil - 1) return 'bg-yellow-100 text-yellow-700 border border-yellow-200';
|
||||
return 'bg-green-100 text-green-700 border border-green-200';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le libellé de vétusté
|
||||
*/
|
||||
export function getVetusteLabel(ageAns: number | null, type: 'fixe' | 'portable'): string {
|
||||
if (ageAns === null) return 'Date inconnue';
|
||||
const seuil = type === 'fixe' ? 5 : 4;
|
||||
if (ageAns >= seuil) return `À renouveler (${ageAns.toFixed(1)} ans)`;
|
||||
return `${ageAns.toFixed(1)} ans`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcule le pourcentage de vétusté pour la barre de progression
|
||||
*/
|
||||
export function getVetustePercent(nbRenouveler: number, nbTotal: number): number {
|
||||
if (nbTotal === 0) return 0;
|
||||
return Math.round((nbRenouveler / nbTotal) * 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne la couleur de la barre de vétusté selon le pourcentage
|
||||
*/
|
||||
export function getBarColor(percent: number): string {
|
||||
if (percent >= 70) return 'bg-red-500';
|
||||
if (percent >= 40) return 'bg-orange-400';
|
||||
if (percent >= 20) return 'bg-yellow-400';
|
||||
return 'bg-green-500';
|
||||
}
|
||||
Reference in New Issue
Block a user