- Add collapsible-open/close keyframes and CSS animation tokens to index.css - Add dashboard.sections and dashboard.carryoverIncludes keys to en.json and de.json - Add optional subtitle/subtitleClassName props to StatCard - Extend SummaryStrip balance prop with carryoverSubtitle/carryoverIsNegative - Compute and pass carryover subtitle from DashboardContent to SummaryStrip
53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
import { StatCard } from "./StatCard"
|
|
|
|
interface SummaryStripProps {
|
|
income: { value: string; budgeted: string }
|
|
expenses: { value: string; budgeted: string }
|
|
balance: {
|
|
value: string
|
|
isPositive: boolean
|
|
carryoverSubtitle?: string
|
|
carryoverIsNegative?: boolean
|
|
}
|
|
t: (key: string) => string
|
|
}
|
|
|
|
export function SummaryStrip({
|
|
income,
|
|
expenses,
|
|
balance,
|
|
t,
|
|
}: SummaryStripProps) {
|
|
return (
|
|
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
<StatCard
|
|
title={t("dashboard.totalIncome")}
|
|
value={income.value}
|
|
valueClassName="text-income"
|
|
variance={{
|
|
amount: income.budgeted,
|
|
direction: "neutral",
|
|
label: t("budgets.budgeted"),
|
|
}}
|
|
/>
|
|
<StatCard
|
|
title={t("dashboard.totalExpenses")}
|
|
value={expenses.value}
|
|
valueClassName="text-destructive"
|
|
variance={{
|
|
amount: expenses.budgeted,
|
|
direction: "neutral",
|
|
label: t("budgets.budgeted"),
|
|
}}
|
|
/>
|
|
<StatCard
|
|
title={t("dashboard.availableBalance")}
|
|
value={balance.value}
|
|
valueClassName={balance.isPositive ? "text-on-budget" : "text-over-budget"}
|
|
subtitle={balance.carryoverSubtitle}
|
|
subtitleClassName={balance.carryoverIsNegative ? "text-over-budget" : undefined}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|