mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:45: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>
|
<h2 className="text-lg font-bold text-white">Estimated Annual Impact</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-6">
|
{(() => {
|
||||||
<div>
|
const revenueResult = didResults?.metrics?.['revenue'];
|
||||||
<div className="flex justify-between text-[10px] uppercase font-black tracking-widest mb-2.5">
|
if (!revenueResult) {
|
||||||
<span className="text-emerald-400 opacity-80">Optimistic Forecast</span>
|
return <div className="text-sm text-slate-500 italic">Run analysis to see projected impact</div>;
|
||||||
<span className="text-emerald-400">$65,000</span>
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
<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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user