Files
accounted/components/kpi/KPIHeroCards.tsx
T
Jakob WennbergandClaude Opus 4.6 6b51d13ba7 refactor: simplify KPI to 4 metrics and update CLAUDE.md (#83)
KPI page: removed operational grid (Intäktstillväxt, Kostnadsandel,
Snittbetaltid — all usually empty or redundant). Now shows 4 cards
(Resultat, Kassa, Kundfordringar, Moms) + trend chart. Removed unused
fields from KPIReport type and simplified API route.

CLAUDE.md: documented MCP server extension, API key infrastructure,
OAuth 2.1 flow, gnubok-mcp npm package, KPI page, cookieless Supabase
client, and updated migration count (65 → 70).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 12:59:53 +01:00

74 lines
2.6 KiB
TypeScript

'use client'
import { Card, CardContent } from '@/components/ui/card'
import { formatCurrency } from '@/lib/utils'
import type { KPIReport } from '@/types'
interface KPIHeroCardsProps {
report: KPIReport
}
export function KPIHeroCards({ report }: KPIHeroCardsProps) {
return (
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{/* Net result */}
<Card>
<CardContent className="p-5">
<p className="text-xs text-muted-foreground mb-1">Resultat</p>
<p className={`font-display text-xl tabular-nums tracking-tight ${
report.netResult >= 0 ? 'text-[hsl(var(--chart-1))]' : 'text-[hsl(var(--chart-2))]'
}`}>
{formatCurrency(report.netResult)}
</p>
<p className="text-xs text-muted-foreground mt-1">netto</p>
</CardContent>
</Card>
{/* Cash position */}
<Card>
<CardContent className="p-5">
<p className="text-xs text-muted-foreground mb-1">Kassa</p>
<p className={`font-display text-xl tabular-nums tracking-tight ${
report.cashPosition > 0 ? 'text-[hsl(var(--chart-1))]' : 'text-[hsl(var(--chart-2))]'
}`}>
{formatCurrency(report.cashPosition)}
</p>
<p className="text-xs text-muted-foreground mt-1">likvida medel</p>
</CardContent>
</Card>
{/* Outstanding receivables */}
<Card>
<CardContent className="p-5">
<p className="text-xs text-muted-foreground mb-1">Kundfordringar</p>
<p className="font-display text-xl tabular-nums tracking-tight">
{formatCurrency(report.outstandingReceivables)}
</p>
{report.overdueReceivables > 0 ? (
<p className="text-xs text-[hsl(var(--chart-2))] mt-1">
varav förfallet: {formatCurrency(report.overdueReceivables)}
</p>
) : (
<p className="text-xs text-muted-foreground mt-1">utestående</p>
)}
</CardContent>
</Card>
{/* VAT liability */}
<Card>
<CardContent className="p-5">
<p className="text-xs text-muted-foreground mb-1">Moms</p>
<p className={`font-display text-xl tabular-nums tracking-tight ${
report.vatLiability > 0 ? 'text-[hsl(var(--chart-2))]' : 'text-[hsl(var(--chart-1))]'
}`}>
{formatCurrency(Math.abs(report.vatLiability))}
</p>
<p className="text-xs text-muted-foreground mt-1">
{report.vatLiability > 0 ? 'att betala' : report.vatLiability < 0 ? 'att återfå' : 'jämnt'}
</p>
</CardContent>
</Card>
</div>
)
}