'use client' import { useState, useEffect } from 'react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { ChevronDown, ChevronRight } from 'lucide-react' import type { JournalEntry, JournalEntryLine } from '@/types' interface Props { periodId?: string } export default function JournalEntryList({ periodId }: Props) { const [entries, setEntries] = useState([]) const [loading, setLoading] = useState(true) const [expandedId, setExpandedId] = useState(null) const [count, setCount] = useState(0) const [page, setPage] = useState(0) const pageSize = 20 useEffect(() => { fetchEntries() }, [periodId, page]) async function fetchEntries() { setLoading(true) const params = new URLSearchParams({ limit: String(pageSize), offset: String(page * pageSize), }) if (periodId) params.set('period_id', periodId) const res = await fetch(`/api/bookkeeping/journal-entries?${params}`) const { data, count: total } = await res.json() setEntries(data || []) setCount(total || 0) setLoading(false) } const toggleExpand = (id: string) => { setExpandedId(expandedId === id ? null : id) } const statusLabel = (status: string) => { switch (status) { case 'posted': return Bokförd case 'draft': return Utkast case 'reversed': return Makulerad default: return {status} } } const sourceLabel = (source: string) => { const labels: Record = { manual: 'Manuell', bank_transaction: 'Banktransaktion', invoice_created: 'Faktura', invoice_paid: 'Betalning', credit_note: 'Kreditfaktura', salary_payment: 'Lön', opening_balance: 'Ingående balans', year_end: 'Årsbokslut', } return labels[source] || source } if (loading) { return ( Laddar verifikationer... ) } if (entries.length === 0) { return ( Inga verifikationer hittades. ) } return (
{entries.map((entry) => { const isExpanded = expandedId === entry.id const lines = (entry.lines || []) as JournalEntryLine[] return ( {isExpanded && lines.length > 0 && ( {lines .sort((a, b) => a.sort_order - b.sort_order) .map((line) => ( ))}
Konto Beskrivning Debet Kredit
{line.account_number} {line.line_description || ''} {Number(line.debit_amount) > 0 ? Number(line.debit_amount).toLocaleString('sv-SE', { minimumFractionDigits: 2, }) : ''} {Number(line.credit_amount) > 0 ? Number(line.credit_amount).toLocaleString('sv-SE', { minimumFractionDigits: 2, }) : ''}
Summa {lines .reduce((sum, l) => sum + (Number(l.debit_amount) || 0), 0) .toLocaleString('sv-SE', { minimumFractionDigits: 2 })} {lines .reduce((sum, l) => sum + (Number(l.credit_amount) || 0), 0) .toLocaleString('sv-SE', { minimumFractionDigits: 2 })}
)}
) })}
{/* Pagination */} {count > pageSize && (
Sida {page + 1} av {Math.ceil(count / pageSize)}
)}
) }