From a7be1aab17e5fae1dcfc07bab4cf16a77e1568d7 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:48:40 +0100 Subject: [PATCH] feat: comprehensive UI design audit and normalization (#28) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: import system improvements, INK2 fix, and Swedish text corrections - SIE parser: Windows-1252 and CP437 encoding detection and decoding - Bank file parser: add Nordea Business (Företag) CSV format - Bank file parser: improve format detection for SEB, Länsförsäkringar, generic CSV - INK2 engine: calculate årets resultat (7222) from income statement for open fiscal years - Dashboard: parallel Supabase queries, simplified dashboard page - Fix Swedish characters (å, ä, ö) in BAS data descriptions, validation messages, AI consent disclosures - Import wizard UI improvements across all steps - Migration: add 'bas_range' match type to sie_account_mappings constraint - Extensive new tests for SIE parser encoding and bank file parser Co-Authored-By: Claude Opus 4.6 * feat: arcim migration wizard UX fixes, Sentry setup, and extension scaffolding Arcim migration wizard improvements: - Progress bar now excludes non-interactive steps (migrating/result) - Fix OAuth text to match target="_blank" behavior (new tab, not redirect) - Display month names instead of "Månad X" in preview - Fix Swedish typo "förifylla" in no-company-info message - Replace native checkboxes with shadcn Switch in options step - Add ConfirmationDialog before starting migration - Show progress percentage during migration - Add "Nästa steg" guidance and navigation links in result step - Add "Försök igen" button in error state (returns to options) - Add Bokio company ID help text (GUID from URL) - Add Fortnox integration add-on hint on connection failure Also includes: SIE import system improvements, INK2 fixes, Swedish text corrections, Sentry error tracking setup, and arcim-migration extension scaffolding. Co-Authored-By: Claude Opus 4.6 * fix: address PR review feedback - Fix OAuth error recovery blank page (restore provider from URL params) - Pass real userId to MigrationWizard instead of empty string - Remove ~50 debug console.log statements from sie-import.ts - Fix comment referencing account 3740 → 3741 Co-Authored-By: Claude Opus 4.6 * feat: comprehensive UI design audit and normalization Dashboard audit: - Fix muted-foreground contrast (4.31:1 → 5.08:1) for WCAG AA - Add prefers-reduced-motion media query for all animations - Replace border-l-2 accent anti-pattern with subtle full-border colors - Add aria-expanded to toggle buttons, role="status" to live counters - Fix touch targets on deadline buttons (28px → 36px) - Vary section spacing for rhythm (mb-12/mb-10/mb-8) - Remove unused imports and dead code Transactions audit + hardening: - Add pagination (200 per page) with "Ladda fler" button - Replace height animation with transform-only exit animation - Show batch progress in floating action bar during processing - Fix batch bar mobile overlap (bottom-20 on mobile) - Replace clickable badges with proper button elements - Add safe area padding to fullscreen swipe view - Add response.ok check to suggestion fetch - Add truncation to invoice number buttons Invoicing audit: - Remove border-l-4 accent pattern from invoice cards - Replace string concatenation with cn() utility Systemic sweep (34 files): - All page headings: font-bold → font-display font-medium (Fraunces) - All stat numbers: font-bold → font-display font-medium tabular-nums - All hard-coded blue/amber/emerald colors → design tokens - Remove all dark mode overrides (tokens handle automatically) - Tint pure white card background to 99% Design context added to CLAUDE.md with brand personality, aesthetic direction, and 5 design principles. Co-Authored-By: Claude Opus 4.6 (1M context) * fix: bookkeeping flow audit — design system, accessibility, UX - Replace raw setSelectedPeriod(e.target.value)} - className="w-full mt-1 rounded-md border border-input bg-background px-3 py-2 text-sm" - > - {periods.map((p) => ( - - ))} - + {!(embedded && initialDate) && (
@@ -514,12 +515,12 @@ export default function JournalEntryForm({ }} isSubmitting={false} title="Underlag saknas" - warningText="Ingen verifikation har bifogats. Enligt bokföringslagen (BFL) krävs underlag för varje bokföringspost." - confirmLabel="Fortsätt ändå" + warningText="Inget underlag har bifogats. Enligt bokföringslagen (BFL) krävs underlag för varje bokföringspost." + confirmLabel="Bokför utan underlag" > -
- -
+
+ +

Inget underlag bifogat

Enligt bokföringslagen (BFL 5 kap. 6-7 §§) ska varje bokföringspost ha en verifikation som diff --git a/components/bookkeeping/JournalEntryList.tsx b/components/bookkeeping/JournalEntryList.tsx index f4f5c273..a4519338 100644 --- a/components/bookkeeping/JournalEntryList.tsx +++ b/components/bookkeeping/JournalEntryList.tsx @@ -6,7 +6,7 @@ import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Label } from '@/components/ui/label' import { Switch } from '@/components/ui/switch' -import { ArrowDownNarrowWide, ArrowUpNarrowWide, ChevronDown, ChevronRight, Paperclip, AlertTriangle, X } from 'lucide-react' +import { ArrowDownNarrowWide, ArrowUpNarrowWide, ChevronDown, ChevronRight, Paperclip, AlertTriangle, Loader2, BookOpen, X } from 'lucide-react' import { Input } from '@/components/ui/input' import { AccountNumber } from '@/components/ui/account-number' import JournalEntryAttachments from '@/components/bookkeeping/JournalEntryAttachments' @@ -53,7 +53,7 @@ export default function JournalEntryList({ periodId }: Props) { const { data } = await res.json() setAttachmentCounts(data || {}) } catch { - console.error('Failed to fetch attachment counts') + // Non-critical — silently ignore } }, []) @@ -69,6 +69,10 @@ export default function JournalEntryList({ periodId }: Props) { if (dateTo) params.set('date_to', dateTo) const res = await fetch(`/api/bookkeeping/journal-entries?${params}`) + if (!res.ok) { + setLoading(false) + return + } const { data, count: total } = await res.json() const loadedEntries = data || [] setEntries(loadedEntries) @@ -95,8 +99,9 @@ export default function JournalEntryList({ periodId }: Props) { if (loading) { return ( - - Laddar verifikationer... + + +

Laddar verifikationer...

) @@ -105,8 +110,14 @@ export default function JournalEntryList({ periodId }: Props) { if (entries.length === 0) { return ( - - Inga verifikationer hittades. + +
+ +
+

Inga verifikationer

+

+ Verifikationer skapas automatiskt vid fakturering och transaktionsbokföring, eller manuellt via fliken "Ny verifikation". +

) @@ -208,6 +219,7 @@ export default function JournalEntryList({ periodId }: Props) { @@ -423,16 +416,18 @@ export default function DashboardContent({ firstName, settings, summary, onboard {alertItems.length > 0 && (

Att hantera

-
+
{visibleAlerts}
- {hasMoreAlerts && !showAllAlerts && ( + {hasMoreAlerts && ( )}
@@ -440,7 +435,7 @@ export default function DashboardContent({ firstName, settings, summary, onboard {/* Upcoming deadlines — always visible */} {summary.deadlines && summary.deadlines.length > 0 && ( -
+
)} @@ -452,27 +447,19 @@ export default function DashboardContent({ firstName, settings, summary, onboard
)} - {/* Collapsible details section */} {showMore && ( -
+
{/* Uncategorized transactions warning */} {summary.uncategorizedCount > 0 && (summary.uncategorizedIncome > 0 || summary.uncategorizedExpenses > 0) && (
diff --git a/components/dashboard/DashboardNav.tsx b/components/dashboard/DashboardNav.tsx index fe80f062..6ce26a54 100644 --- a/components/dashboard/DashboardNav.tsx +++ b/components/dashboard/DashboardNav.tsx @@ -140,7 +140,7 @@ export default function DashboardNav({ companyName, entityType, uncategorizedTra