first commit

This commit is contained in:
2026-08-05 15:26:50 +05:30
parent c000e5dc95
commit 2c8c394795
126 changed files with 10824 additions and 302 deletions

View File

@@ -0,0 +1,41 @@
'use client';
import {ChartCard} from '@/components/charts/ChartCard';
import {BarChartView} from '@/components/charts/BarChartView';
import {formatCompact} from '@/lib/format';
import type {RewardUsagePoint} from '@/lib/api/contracts';
import type {Resource} from '@/lib/api/useResource';
/**
* Claimed vs used, per reward.
*
* The gap between the two bars is the whole point: a reward claimed 700 times
* and redeemed 130 is an outstanding liability and a broken offer, not a
* success. Plotting the usage *rate* alone would hide the volume; plotting
* volume alone would hide the failure. So both bars, side by side.
*/
export function RewardUsageChart({
resource,
}: {
resource: Resource<RewardUsagePoint[]>;
}) {
return (
<ChartCard
title="Reward usage"
subtitle="Claimed vs actually redeemed — the gap is unspent liability"
resource={resource}
>
{(rows) => (
<BarChartView
data={rows}
xKey="name"
yFormat={formatCompact}
series={[
{key: 'claimed', label: 'Claimed'},
{key: 'used', label: 'Redeemed'},
]}
/>
)}
</ChartCard>
);
}