Files
accounted/components/extensions/shared/KPICard.tsx
T
Jakob WennbergandClaude Opus 4.6 f3ec634a46 feat: open-source under AGPL-3.0, redesign UI to grayscale palette, add uncategorize API, fix VAT account names
Add LICENSE (AGPL-3.0-or-later), CONTRIBUTING.md, SECURITY.md, DCO, and NOTICE files.
Rewrite README for open-source audience with self-hosting instructions.
Redesign color palette to grayscale chrome theme across all components.
Add transaction uncategorize API route with tests.
Fix VAT account name mismatches in migration 052.
Improve import page with SIE file support and loading skeleton.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:18:11 +01:00

35 lines
1.0 KiB
TypeScript

'use client'
import { Card, CardContent } from '@/components/ui/card'
import { cn } from '@/lib/utils'
interface KPICardProps {
label: string
value: string | number
suffix?: string
trend?: { value: number; label: string }
className?: string
}
export default function KPICard({ label, value, suffix, trend, className }: KPICardProps) {
return (
<Card className={cn('', className)}>
<CardContent className="pt-6">
<p className="text-sm text-muted-foreground">{label}</p>
<div className="flex items-baseline gap-1 mt-1">
<span className="text-2xl font-semibold tracking-tight">{value}</span>
{suffix && <span className="text-sm text-muted-foreground">{suffix}</span>}
</div>
{trend && (
<p className={cn(
'text-xs mt-1',
trend.value > 0 ? 'text-success' : trend.value < 0 ? 'text-destructive' : 'text-muted-foreground'
)}>
{trend.value > 0 ? '+' : ''}{trend.value}% {trend.label}
</p>
)}
</CardContent>
</Card>
)
}