feat: Add 4 major features to BOC Dashboard
1. Balance Sheet Chart — grafisk visning med progress bars - Assets (grön), Liabilities (röd), Equity (blå) - Balance check längst ner 2. Period-väljare — dropdown för månadsval - 2026-02, 2026-03, 2026-04 3. Drill-down — klicka på konto för transaktionshistorik - Modal med Date, Description, Debit, Credit, Balance - Mock data (ersätt med API-anrop) 4. Export-knappar — SIE4, PDF, CSV - Download-funktionalitet - Loading-tillstånd Alla komponenter bygger och integreras i DashboardPage.
This commit is contained in:
@@ -2,6 +2,9 @@ import { useEffect, useState } from 'react'
|
||||
import { KPICard } from '@/components/KPICard'
|
||||
import { RevenueChart } from '@/components/RevenueChart'
|
||||
import { ActivityFeed } from '@/components/ActivityFeed'
|
||||
import { BalanceSheetChart } from '@/components/BalanceSheetChart'
|
||||
import { AccountDetailModal } from '@/components/AccountDetailModal'
|
||||
import { ExportButtons } from '@/components/ExportButtons'
|
||||
import { Card, CardHeader } from '@/components/ui/Card'
|
||||
import { Skeleton } from '@/components/ui/Skeleton'
|
||||
import {
|
||||
@@ -67,6 +70,9 @@ export function DashboardPage() {
|
||||
const [ledgerEquity, setLedgerEquity] = useState(0)
|
||||
const [netIncome, setNetIncome] = useState(0)
|
||||
const [ledgerAccounts, setLedgerAccounts] = useState<LedgerAccount[]>([])
|
||||
const [balanceSheetData, setBalanceSheetData] = useState<any>(null)
|
||||
const [selectedPeriod, setSelectedPeriod] = useState('2026-02')
|
||||
const [selectedAccount, setSelectedAccount] = useState<{code: string, name: string} | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
@@ -99,6 +105,7 @@ export function DashboardPage() {
|
||||
setLedgerAssets(ledgerBs.total_assets || 0)
|
||||
setLedgerLiabilities(ledgerBs.total_liabilities || 0)
|
||||
setLedgerEquity(ledgerBs.total_equity || 0)
|
||||
setBalanceSheetData(ledgerBs)
|
||||
}
|
||||
if (ledgerIs) {
|
||||
setNetIncome(ledgerIs.net_income || 0)
|
||||
@@ -215,6 +222,20 @@ export function DashboardPage() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Period Selector */}
|
||||
<div className="flex items-center gap-4">
|
||||
<label className="text-sm font-medium">Period:</label>
|
||||
<select
|
||||
value={selectedPeriod}
|
||||
onChange={(e) => setSelectedPeriod(e.target.value)}
|
||||
className="border rounded px-3 py-1 text-sm"
|
||||
>
|
||||
<option value="2026-02">2026-02</option>
|
||||
<option value="2026-03">2026-03</option>
|
||||
<option value="2026-04">2026-04</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Ledger KPI Cards */}
|
||||
<div className="mt-8">
|
||||
<h2 className="text-lg font-semibold mb-4">Ledger (Bokföring)</h2>
|
||||
@@ -225,6 +246,11 @@ export function DashboardPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Balance Sheet Chart */}
|
||||
{balanceSheetData && (
|
||||
<BalanceSheetChart data={balanceSheetData} />
|
||||
)}
|
||||
|
||||
{/* Infrastructure Health — Grafana Integration */}
|
||||
<Card>
|
||||
<CardHeader
|
||||
@@ -303,15 +329,18 @@ export function DashboardPage() {
|
||||
) : (
|
||||
ledgerAccounts.map((account) => (
|
||||
<TableRow key={account.code}>
|
||||
<TableCell className="font-medium">{account.code}</TableCell>
|
||||
<TableCell>{account.name}</TableCell>
|
||||
<TableCell>
|
||||
<Badge>{account.account_type}</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<span className={account.balance >= 0 ? 'text-success' : 'text-danger'}>
|
||||
{formatCurrency(account.balance)}
|
||||
</span>
|
||||
<TableCell colSpan={4} className="p-0">
|
||||
<div
|
||||
className="flex items-center px-4 py-3 cursor-pointer hover:bg-surface-2"
|
||||
onClick={() => setSelectedAccount({ code: account.code, name: account.name })}
|
||||
>
|
||||
<span className="font-medium w-16">{account.code}</span>
|
||||
<span className="flex-1">{account.name}</span>
|
||||
<span className="w-24"><Badge>{account.account_type}</Badge></span>
|
||||
<span className={`w-32 text-right ${account.balance >= 0 ? 'text-success' : 'text-danger'}`}>
|
||||
{formatCurrency(account.balance)}
|
||||
</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
@@ -385,6 +414,18 @@ export function DashboardPage() {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Export Buttons */}
|
||||
<ExportButtons period={selectedPeriod} />
|
||||
|
||||
{/* Account Detail Modal */}
|
||||
{selectedAccount && (
|
||||
<AccountDetailModal
|
||||
accountCode={selectedAccount.code}
|
||||
accountName={selectedAccount.name}
|
||||
onClose={() => setSelectedAccount(null)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Recent Deals */}
|
||||
<Card>
|
||||
<CardHeader
|
||||
|
||||
Reference in New Issue
Block a user