feat: taux de géoloc réel par frame + DU + périodeSélecteur + autoplay anim
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Affiche l'équivalent en DU pour le volume total et la moyenne par tx - Taux de géolocalisation réel par frame d'animation (via allTimestamps) - Sélecteur de période personnalisée inline à côté des boutons 24h/7j/30j - Clic sur Animer lance la lecture automatique à vitesse ×1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,6 @@ interface StatsPanelProps {
|
||||
source: 'live' | 'mock';
|
||||
currentUD: number;
|
||||
animationLabel?: string;
|
||||
// Stats de géoloc de la période complète (indépendantes de la frame courante)
|
||||
globalGeoStats?: { geoCount: number; transactionCount: number };
|
||||
}
|
||||
|
||||
const MEDALS = ['🥇', '🥈', '🥉'];
|
||||
@@ -35,7 +33,7 @@ function formatDU(g1: number, ud: number): string {
|
||||
return `≈ ${Math.round(du).toLocaleString('fr-FR')} DU`;
|
||||
}
|
||||
|
||||
export function StatsPanel({ stats, loading, periodDays, source, currentUD, animationLabel, globalGeoStats }: StatsPanelProps) {
|
||||
export function StatsPanel({ stats, loading, periodDays, source, currentUD, animationLabel }: StatsPanelProps) {
|
||||
const periodLabel = periodDays === 1 ? '24 dernières heures' : `${periodDays} derniers jours`;
|
||||
const prevStats = useRef<PeriodStats | null>(null);
|
||||
|
||||
@@ -108,20 +106,14 @@ export function StatsPanel({ stats, loading, periodDays, source, currentUD, anim
|
||||
})()}
|
||||
delta={prevTxCount !== null ? (stats.transactionCount > prevTxCount ? 'up' : stats.transactionCount < prevTxCount ? 'down' : null) : null}
|
||||
/>
|
||||
{/* Couverture géo — toujours basée sur la période complète (pas la frame) */}
|
||||
{source === 'live' && (() => {
|
||||
const geo = globalGeoStats ?? { geoCount: stats.geoCount, transactionCount: stats.transactionCount };
|
||||
const pct = geo.transactionCount > 0
|
||||
? Math.round((geo.geoCount / geo.transactionCount) * 100)
|
||||
: null;
|
||||
if (pct === null) return null;
|
||||
{/* Couverture géo — transactionCount inclut le total réel de la frame */}
|
||||
{source === 'live' && stats.transactionCount > 0 && (() => {
|
||||
const pct = Math.round((stats.geoCount / stats.transactionCount) * 100);
|
||||
return (
|
||||
<div className="bg-[#0f1016] border border-[#2e2f3a] rounded-xl p-3">
|
||||
<div className="flex justify-between items-center mb-1.5">
|
||||
<p className="text-[#4b5563] text-xs uppercase tracking-widest">
|
||||
Géolocalisées{animationLabel ? <span className="normal-case ml-1 opacity-60">(période)</span> : ''}
|
||||
</p>
|
||||
<p className="text-[#6b7280] text-xs">{geo.geoCount} / {geo.transactionCount}</p>
|
||||
<p className="text-[#4b5563] text-xs uppercase tracking-widest">Géolocalisées</p>
|
||||
<p className="text-[#6b7280] text-xs">{stats.geoCount} / {stats.transactionCount}</p>
|
||||
</div>
|
||||
<div className="w-full bg-[#1e1f2a] rounded-full h-1.5">
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user