mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-05-18 20:08:19 +00:00
89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
import { cx } from '@/utils/cx';
|
|
import { formatCurrency } from '@/lib/format';
|
|
import type { Campaign } from '@/types/entities';
|
|
|
|
interface KpiStripProps {
|
|
campaign: Campaign;
|
|
}
|
|
|
|
type KpiItem = {
|
|
label: string;
|
|
value: string;
|
|
subText: string;
|
|
subColor: string;
|
|
};
|
|
|
|
export const KpiStrip = ({ campaign }: KpiStripProps) => {
|
|
const leadCount = campaign.leadCount ?? 0;
|
|
const contactedCount = campaign.contactedCount ?? 0;
|
|
const convertedCount = campaign.convertedCount ?? 0;
|
|
const spentMicros = campaign.amountSpent?.amountMicros ?? 0;
|
|
const budgetMicros = campaign.budget?.amountMicros ?? 0;
|
|
const currencyCode = campaign.amountSpent?.currencyCode ?? 'INR';
|
|
|
|
const contactRate = leadCount > 0 ? ((contactedCount / leadCount) * 100).toFixed(1) : '0.0';
|
|
const conversionRate = leadCount > 0 ? ((convertedCount / leadCount) * 100).toFixed(1) : '0.0';
|
|
const budgetPercent = budgetMicros > 0 ? ((spentMicros / budgetMicros) * 100).toFixed(0) : '--';
|
|
const costPerLead = leadCount > 0 ? formatCurrency(spentMicros / leadCount, currencyCode) : '--';
|
|
const cac = convertedCount > 0 ? formatCurrency(spentMicros / convertedCount, currencyCode) : '--';
|
|
|
|
const items: KpiItem[] = [
|
|
{
|
|
label: 'Total Leads',
|
|
value: String(leadCount),
|
|
subText: `${campaign.impressionCount ?? 0} impressions`,
|
|
subColor: 'text-tertiary',
|
|
},
|
|
{
|
|
label: 'Contacted',
|
|
value: String(contactedCount),
|
|
subText: `${contactRate}% contact rate`,
|
|
subColor: 'text-success-primary',
|
|
},
|
|
{
|
|
label: 'Converted',
|
|
value: String(convertedCount),
|
|
subText: `${conversionRate}% conversion`,
|
|
subColor: 'text-success-primary',
|
|
},
|
|
{
|
|
label: 'Spent',
|
|
value: formatCurrency(spentMicros, currencyCode),
|
|
subText: `${budgetPercent}% of budget`,
|
|
subColor: Number(budgetPercent) > 90 ? 'text-error-primary' : 'text-warning-primary',
|
|
},
|
|
{
|
|
label: 'Cost / Lead',
|
|
value: costPerLead,
|
|
subText: 'avg per lead',
|
|
subColor: 'text-tertiary',
|
|
},
|
|
{
|
|
label: 'CAC',
|
|
value: cac,
|
|
subText: 'per conversion',
|
|
subColor: 'text-tertiary',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="flex items-stretch border-b border-secondary bg-primary px-7 py-4">
|
|
{items.map((item, index) => (
|
|
<div
|
|
key={item.label}
|
|
className={cx(
|
|
'flex flex-1 flex-col justify-center px-4',
|
|
index === 0 && 'pl-0',
|
|
index === items.length - 1 && 'pr-0',
|
|
index < items.length - 1 && 'border-r border-tertiary',
|
|
)}
|
|
>
|
|
<p className="text-xl font-bold text-primary">{item.value}</p>
|
|
<p className="text-xs font-medium uppercase text-quaternary">{item.label}</p>
|
|
<p className={cx('mt-0.5 text-xs', item.subColor)}>{item.subText}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|