* feat: separate AR/AP/accounting into distinct nav groups (#92) Split the flat "Finans" sidebar group into three visually distinct sections — Försäljning (AR), Inköp (AP), and Redovisning — so users coming from Fortnox immediately find customer invoicing and supplier invoices as top-level concepts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: journal entry detail view, correction chain, and account name display - Add journal entry detail page at /bookkeeping/[id] with full entry view - Add correction chain API and component showing storno relationships - Add JournalEntryStatusBadge component for entry status display - Show debit/credit account names in template picker and review dialogs - Expand client-side BAS account name mapping with additional accounts - Show account codes on transaction inbox suggestion buttons Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback — N+1 query, duplicate name, nav dedup - Batch reverse-lookup into single query per BFS iteration (was N+1) - Differentiate account 2393 from 2893 in display names - Extract shared loop for desktop/mobile nav group rendering Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import { Badge } from '@/components/ui/badge'
|
|
import type { JournalEntry } from '@/types'
|
|
|
|
const statusConfig: Record<string, { label: string; variant: 'default' | 'secondary' | 'success' | 'warning' | 'destructive' }> = {
|
|
draft: { label: 'Utkast', variant: 'secondary' },
|
|
posted: { label: 'Bokförd', variant: 'success' },
|
|
reversed: { label: 'Omförd', variant: 'warning' },
|
|
cancelled: { label: 'Makulerad', variant: 'secondary' },
|
|
}
|
|
|
|
const sourceTypeBadges: Record<string, { label: string; variant: 'default' | 'secondary' | 'success' | 'warning' | 'destructive' }> = {
|
|
storno: { label: 'Storno', variant: 'destructive' },
|
|
correction: { label: 'Rättelse', variant: 'default' },
|
|
}
|
|
|
|
export const sourceTypeLabels: Record<string, string> = {
|
|
manual: 'Manuell',
|
|
bank_transaction: 'Banktransaktion',
|
|
invoice_created: 'Faktura skapad',
|
|
invoice_paid: 'Fakturabetalning',
|
|
credit_note: 'Kreditfaktura',
|
|
salary_payment: 'Lön',
|
|
opening_balance: 'Ingående balans',
|
|
year_end: 'Årsbokslut',
|
|
storno: 'Storno',
|
|
correction: 'Rättelse',
|
|
import: 'Import',
|
|
system: 'System',
|
|
supplier_invoice_registered: 'Leverantörsfaktura',
|
|
supplier_invoice_paid: 'Leverantörsbetalning',
|
|
supplier_invoice_cash_payment: 'Kontantbetalning',
|
|
currency_revaluation: 'Valutaomvärdering',
|
|
}
|
|
|
|
interface Props {
|
|
entry: JournalEntry
|
|
showStatus?: boolean
|
|
}
|
|
|
|
export default function JournalEntryStatusBadge({ entry, showStatus = true }: Props) {
|
|
const status = statusConfig[entry.status]
|
|
const sourceType = sourceTypeBadges[entry.source_type]
|
|
|
|
return (
|
|
<span className="inline-flex items-center gap-1">
|
|
{showStatus && status && (
|
|
<Badge variant={status.variant} className="text-[10px] px-1.5 py-0">
|
|
{status.label}
|
|
</Badge>
|
|
)}
|
|
{sourceType && (
|
|
<Badge variant={sourceType.variant} className="text-[10px] px-1.5 py-0">
|
|
{sourceType.label}
|
|
</Badge>
|
|
)}
|
|
</span>
|
|
)
|
|
}
|