mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:05:23 +02:00
Implement dynamic annual impact projection in Experiment view
This commit is contained in:
@@ -675,35 +675,73 @@ const ExperimentDetailView: React.FC<{
|
||||
<h2 className="text-lg font-bold text-white">Estimated Annual Impact</h2>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
||||
<span className="text-emerald-400 opacity-80">Optimistic Forecast</span>
|
||||
<span className="text-emerald-400">$65,000</span>
|
||||
{(() => {
|
||||
const revenueResult = didResults?.metrics?.['revenue'];
|
||||
if (!revenueResult) {
|
||||
return <div className="text-sm text-slate-500 italic">Run analysis to see projected impact</div>;
|
||||
}
|
||||
|
||||
const weeklyIncremental = revenueResult.did_estimate;
|
||||
// Annual projection: weekly increment * 52 weeks
|
||||
const expectedAnnual = weeklyIncremental * 52;
|
||||
|
||||
// If the impact is negative, we show 0 or the actual loss depending on design choice.
|
||||
// Given the visual context "Forecast", we'll show the actual projection but cap at 0 for progress bars.
|
||||
const optimisticAnnual = expectedAnnual > 0 ? expectedAnnual * 1.5 : expectedAnnual * 0.5;
|
||||
const conservativeAnnual = expectedAnnual > 0 ? expectedAnnual * 0.5 : expectedAnnual * 1.5;
|
||||
|
||||
const formatImpact = (val: number) => {
|
||||
return val.toLocaleString('de-DE', {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
maximumFractionDigits: 0
|
||||
});
|
||||
};
|
||||
|
||||
const maxVal = Math.max(Math.abs(optimisticAnnual), Math.abs(expectedAnnual), 10000);
|
||||
const getWidth = (val: number) => `${Math.max(5, Math.min(100, (Math.abs(val) / maxVal) * 100))}%`;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
||||
<span className="text-emerald-400 opacity-80">Optimistic Forecast</span>
|
||||
<span className="text-emerald-400">{formatImpact(optimisticAnnual)}</span>
|
||||
</div>
|
||||
<div className="h-2.5 w-full bg-[#1e293b] rounded-full overflow-hidden leading-none">
|
||||
<div
|
||||
className={`h-full ${optimisticAnnual >= 0 ? 'bg-[#10b981]' : 'bg-red-500'} rounded-full transition-all duration-1000`}
|
||||
style={{ width: getWidth(optimisticAnnual) }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
||||
<span className="text-indigo-400 opacity-80">Expected Gain</span>
|
||||
<span className="text-indigo-400">{formatImpact(expectedAnnual)}</span>
|
||||
</div>
|
||||
<div className="h-2.5 w-full bg-[#1e293b] rounded-full overflow-hidden leading-none">
|
||||
<div
|
||||
className={`h-full ${expectedAnnual >= 0 ? 'bg-[#6366f1]' : 'bg-red-400'} rounded-full transition-all duration-1000`}
|
||||
style={{ width: getWidth(expectedAnnual) }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
||||
<span className="text-[#64748b]">Conservative Baseline</span>
|
||||
<span className="text-[#64748b]">{formatImpact(conservativeAnnual)}</span>
|
||||
</div>
|
||||
<div className="h-2.5 w-full bg-[#1e293b] rounded-full overflow-hidden leading-none">
|
||||
<div
|
||||
className={`h-full ${conservativeAnnual >= 0 ? 'bg-[#475569]' : 'bg-red-900'} rounded-full transition-all duration-1000`}
|
||||
style={{ width: getWidth(conservativeAnnual) }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-2.5 w-full bg-[#1e293b] rounded-full overflow-hidden leading-none">
|
||||
<div className="h-full bg-[#10b981] rounded-full w-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
||||
<span className="text-indigo-400 opacity-80">Expected Gain</span>
|
||||
<span className="text-indigo-400">$42,000</span>
|
||||
</div>
|
||||
<div className="h-2.5 w-full bg-[#1e293b] rounded-full overflow-hidden leading-none">
|
||||
<div className="h-full bg-[#6366f1] rounded-full w-[65%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
||||
<span className="text-[#64748b]">Conservative Baseline</span>
|
||||
<span className="text-[#64748b]">$18,000</span>
|
||||
</div>
|
||||
<div className="h-2.5 w-full bg-[#1e293b] rounded-full overflow-hidden leading-none">
|
||||
<div className="h-full bg-[#475569] rounded-full w-[25%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user