'use client' import { useTranslations } from 'next-intl' import { Button } from '@/components/ui/button' import { DetailSection } from '@/components/ui/detail-section' import { TH_CLASS, TD_CLASS } from '@/components/ui/dry-table' import { Calculator, Loader2 } from 'lucide-react' import { cn, formatCurrency } from '@/lib/utils' export interface EntryPreviewLine { account_number: string line_description: string debit_amount: number | null credit_amount: number | null } export interface EntryPreview { description: string lines: EntryPreviewLine[] } export interface PreviewData { // True when the entries are the ACTUAL posted verifikat of a booked run // (the preview route returns those instead of a recomputed projection, // which could contradict vouchers booked under earlier rules). booked?: boolean salaryEntry: EntryPreview | null avgifterEntry: EntryPreview | null vacationEntry: EntryPreview | null pensionEntry?: EntryPreview | null } interface RunJournalPreviewProps { preview: PreviewData // When provided (draft + write access), a "Beräkna om" button renders on // the kicker line: recalculation sits on the output it refreshes. onRecalculate?: () => void recalculating?: boolean } export function RunJournalPreview({ preview, onRecalculate, recalculating }: RunJournalPreviewProps) { const t = useTranslations('salary_run') const entries = [ preview.salaryEntry, preview.avgifterEntry, preview.vacationEntry, preview.pensionEntry, ].filter(Boolean) as EntryPreview[] return ( {recalculating ? ( ) : ( )} {t('action_recalculate')} ) : undefined } > {entries.length === 0 ? (

{t('journal_preview_nollkorning')}

) : (
{entries.map((entry, idx) => (

{entry.description}

{entry.lines.map((line, li) => ( ))}
{t('journal_th_account')} {t('journal_th_description')} {t('journal_th_debit')} {t('journal_th_credit')}
{line.account_number} {line.line_description} {line.debit_amount ? formatCurrency(line.debit_amount) : ''} {line.credit_amount ? formatCurrency(line.credit_amount) : ''}
))}
)}
) }