The sync endpoint returns 401 for six distinct auth states (handleSkvError):
NOT_CONNECTED, SESSION_EXPIRED, REFRESH_EXHAUSTED, MISSING_SCOPE,
TOKEN_CORRUPTED, TOKEN_REVOKED. The page treated every 401 as "Skatteverket
är inte anslutet" — directly contradicting Inställningar, which reads the
stored token metadata and truthfully shows "Ansluten" for all but the first.
- syncNow now checks the structured error code: only NOT_CONNECTED flips to
the not-connected empty state. Every other auth failure renders the
server's actual Swedish message as a persistent banner with an "Anslut
igen" CTA, keeping the stored saldo/transactions visible.
- SkatteverketConnectPanel moves to the top of /settings/tax — the
skattekonto and momsdeklaration pages send users there specifically to
(re)connect, and below the tax form it sat out of view.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: enhance supplier invoice payment process and settings handling
- Implemented linking of invoice documents to journal entries for cash payments in the supplier invoice payment process.
- Refactored settings fetching logic to improve loading states and error handling across various settings components.
- Introduced a new SettingsLoadError component to handle cases where settings fetch fails or returns no data.
- Updated useSettings hook to manage loading and error states more effectively, allowing for retries on failure.
- Enhanced tests for supplier invoice creation to ensure document IDs are persisted correctly for cash method payments.
* feat(salary): enable monthly salary edits in draft runs and handle zero-total declarations
* feat(reports,settings): report library + focused report routes, settings modal
Reports
- Replace the monolithic /reports tab-switcher with a calm, grouped report
library landing (ReportLibrary + RecentReportsShelf) driven by a new
lib/reports/catalog.ts.
- Each report opens a focused /reports/[slug] route (FocusedReport) with a
shared fiscal-year selector, optional date-range, and URL-based account
drill-down into the general ledger.
- Extract every report view into components/reports/views, add a reusable
ReportExportMenu, and remove the old ReportsNav.
Settings
- Add an intercepting @settingsModal parallel route so in-app navigation to
/settings opens as a modal over the current page; hard loads still resolve
to the full page.
- Share one SettingsShell (rail + content) between page and modal, extract each
section into components/settings/sections/*Content, add a settings hotkey and
command-palette entry, and remove the old SettingsSidebar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(reports,settings): remove dead salary-journal entry, fix border token
Addresses PR review feedback (#629):
- Remove the unreachable `salary-journal` report from the catalog. It had
needsEmployees + no route + no FocusedView handler and `hasEmployees` was
never plumbed through, so it never appeared in the library and a direct
/reports/salary-journal URL rendered a blank frame. The report was never on
the old page and has no view component; the API + generator stay in place for
a proper follow-up. Drops its two now-unused i18n keys.
- Replace opacity-suffixed `border-border/8` section dividers with full-opacity
`border-border` across the extracted settings section components, per the
design system (no opacity-suffixed border tokens on surfaces).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ci: re-trigger checks (pg-real hit a Docker Hub registry timeout)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>