'use client' import { Suspense, useState } from 'react' import Link from 'next/link' import { useRouter, useSearchParams } from 'next/navigation' import { useTranslations } from 'next-intl' import { ChevronLeft } from 'lucide-react' import { PageHeader } from '@/components/ui/page-header' import { EmptyState } from '@/components/ui/empty-state' import { Card, CardContent } from '@/components/ui/card' import { Skeleton } from '@/components/ui/skeleton' import { useCompany } from '@/contexts/CompanyContext' import { FiscalYearSelector } from '@/components/common/FiscalYearSelector' import { ReportDateRange, type DateRangeValue } from '@/components/common/ReportDateRange' import { DATE_RANGE_SLUGS, getReport } from '@/lib/reports/catalog' import { NEDeclarationView } from '@/components/reports/NEDeclarationView' import { PeriodiskSammanstallningView } from '@/components/reports/PeriodiskSammanstallningView' import { INK2DeclarationView } from '@/components/reports/INK2DeclarationView' import { BankReconciliationView } from '@/components/reports/BankReconciliationView' import { TrialBalanceView, IncomeStatementView, BalanceSheetView, ResultatrapportView, BalansrapportView, VatDeclarationView, SupplierLedgerView, GeneralLedgerView, JournalRegisterView, ARLedgerView, } from '@/components/reports/views' /** * The focused single-report experience at /reports/[slug]. Carries one report: * a back link to the library, the shared fiscal-year selector (restored from * localStorage so it matches the year picked on the landing), the report's * optional date-range control, and the report body. Drilling into an account * navigates to /reports/huvudbok?account=… — drill state lives in the URL. */ function FocusedReportInner({ slug }: { slug: string }) { const router = useRouter() const searchParams = useSearchParams() const { company } = useCompany() const t = useTranslations('reports') const [selectedPeriod, setSelectedPeriod] = useState('') const [selectedPeriodBounds, setSelectedPeriodBounds] = useState<{ start: string; end: string } | null>(null) const [dateRange, setDateRange] = useState({}) const [isReady, setIsReady] = useState(false) const report = getReport(slug) // Calendar (VAT family) and param-less reports don't need a fiscal period. const isPeriodless = report?.params === 'calendar' || report?.params === 'none' const reportName = report ? t(report.labelKey) : slug const accountFilter = searchParams.get('account') const isEnskildFirma = company?.entity_type === 'enskild_firma' const isAktiebolag = company?.entity_type === 'aktiebolag' // Drilling from a report into the general ledger is a route change, so the // account lands in the URL and the browser back button returns to the report. const navigateToAccount = (accountNumber: string) => { router.push(`/reports/huvudbok?account=${encodeURIComponent(accountNumber)}`) } return (
{t('back_to_library')} { setSelectedPeriod(id || '') setSelectedPeriodBounds( period ? { start: period.period_start, end: period.period_end } : null, ) setDateRange({}) }} includeAllOption={false} hideFuturePeriods onReady={() => setIsReady(true)} /> } /> {DATE_RANGE_SLUGS.has(slug) && selectedPeriodBounds && ( )} {!isReady && !isPeriodless ? ( ) : isPeriodless || selectedPeriod ? ( ) : ( )}
) } function FocusedView({ slug, periodId, periodBounds, dateRange, accountFilter, isEnskildFirma, isAktiebolag, onNavigateToAccount, }: { slug: string periodId: string periodBounds: { start: string; end: string } | null dateRange: DateRangeValue accountFilter: string | null isEnskildFirma: boolean isAktiebolag: boolean onNavigateToAccount: (account: string) => void }) { switch (slug) { case 'resultatrapport': return case 'balansrapport': return case 'trial-balance': return case 'income-statement': return case 'balance-sheet': return case 'vat-declaration': return case 'periodisk-sammanstallning': return case 'ne-declaration': return isEnskildFirma ? : null case 'ink2-declaration': return isAktiebolag ? : null case 'huvudbok': return case 'grundbok': return case 'kundreskontra': return case 'supplier-ledger': return case 'bank-reconciliation': return default: return null } } export function FocusedReport({ slug }: { slug: string }) { return ( }> ) }