mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
Карточки сводки резали суммы («252…», «100.0…»): на десктопе их было 8 в ряд (слишком узко), а дельта стояла в той же строке и доедала место. - Дельта переехала ПОД значение — значение получает всю ширину карточки. - Сетка сводки: убрал xl:grid-cols-8, максимум 4 в ряд (карточки шире).
50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
import { type ReactNode } from 'react';
|
|
|
|
import { TREND_STYLES } from './constants';
|
|
|
|
const DEFAULT_VALUE_CLASS = 'text-dark-100';
|
|
|
|
export interface StatCardDelta {
|
|
/** Signed percent change vs the comparison period. */
|
|
percent: number;
|
|
trend: 'up' | 'down' | 'stable';
|
|
}
|
|
|
|
interface StatCardProps {
|
|
label: string;
|
|
value: string | number;
|
|
icon?: ReactNode;
|
|
valueClassName?: string;
|
|
/** Optional period-over-period change shown next to the value. */
|
|
delta?: StatCardDelta | null;
|
|
}
|
|
|
|
export function StatCard({
|
|
label,
|
|
value,
|
|
icon,
|
|
valueClassName = DEFAULT_VALUE_CLASS,
|
|
delta,
|
|
}: StatCardProps) {
|
|
const trendStyle = delta ? (TREND_STYLES[delta.trend] ?? TREND_STYLES.stable) : null;
|
|
|
|
return (
|
|
<div className="rounded-xl bg-dark-800/30 p-3">
|
|
<div className="flex items-center gap-1.5 text-sm text-dark-500">
|
|
{icon}
|
|
<span>{label}</span>
|
|
</div>
|
|
<div className="mt-1">
|
|
<div className={`truncate text-base font-semibold sm:text-lg ${valueClassName}`}>
|
|
{value}
|
|
</div>
|
|
{trendStyle && (
|
|
<div className={`mt-0.5 text-xs font-medium ${trendStyle.className}`}>
|
|
{trendStyle.arrow} {Math.abs(delta!.percent)}%
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|