diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index 2582262d..e3a0e5c6 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -276,7 +276,7 @@ function LoginPageContent() {

-
+

{showResetPassword ? tAuth('email_sent_hint_reset') : tAuth('email_sent_hint_login')}

@@ -327,7 +327,7 @@ function LoginPageContent() {

-
+
@@ -382,7 +382,7 @@ function LoginPageContent() {

-
+
{callbackError === 'auth_error' && (

diff --git a/app/(auth)/mfa/enroll/page.tsx b/app/(auth)/mfa/enroll/page.tsx index eed9c2f8..33ab7808 100644 --- a/app/(auth)/mfa/enroll/page.tsx +++ b/app/(auth)/mfa/enroll/page.tsx @@ -188,7 +188,7 @@ function MfaEnrollContent() {

-
+

@@ -242,7 +242,7 @@ function MfaEnrollContent() {

-
+
{/* QR Code */}
-
+
diff --git a/app/(auth)/register/page.tsx b/app/(auth)/register/page.tsx index 0fe8221f..ab4d685e 100644 --- a/app/(auth)/register/page.tsx +++ b/app/(auth)/register/page.tsx @@ -140,7 +140,7 @@ function RegisterPageContent() { }) if (error) { - console.error('[register] BankID verifyOtp failed', error) + console.error('[register] BankID verifyOtp failed', error.message) toast({ title: t('register_failed_complete'), description: getErrorMessage(error, { context: 'auth', locale: errorLocale }), @@ -152,7 +152,7 @@ function RegisterPageContent() { router.push('/select-company') router.refresh() } catch (error) { - console.error('[register] BankID signup error', error) + console.error('[register] BankID signup error', error instanceof Error ? error.message : String(error)) toast({ title: t('register_failed_title'), description: getErrorMessage(error, { context: 'auth', locale: errorLocale }), @@ -201,14 +201,6 @@ function RegisterPageContent() { } try { - console.log('[register] attempting signUp', { - email: emailValue, - hasPassword: !!passwordValue, - passwordLength: passwordValue.length, - redirectTo: `${window.location.origin}/auth/callback`, - supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL, - }) - const { data, error } = await supabase.auth.signUp({ email: emailValue, password: passwordValue, @@ -218,15 +210,7 @@ function RegisterPageContent() { }) if (error) { - console.error('[register] signUp error', { - message: error.message, - code: error.code, - status: error.status, - name: error.name, - stack: error.stack, - cause: error.cause, - fullError: JSON.stringify(error, Object.getOwnPropertyNames(error)), - }) + console.error('[register] signUp error', error.message) toast({ title: t('register_failed_title'), description: getErrorMessage(error, { context: 'auth', locale: errorLocale }), @@ -235,16 +219,6 @@ function RegisterPageContent() { return } - console.log('[register] signUp response', { - userId: data.user?.id, - email: data.user?.email, - isAnonymous: data.user?.is_anonymous, - identities: data.user?.identities?.length, - hasSession: !!data.session, - confirmationSentAt: data.user?.confirmation_sent_at, - provider: data.user?.app_metadata?.provider, - }) - // If auto-confirmed (local dev), process invite immediately and redirect if (data.session) { const cookieMatch = document.cookie.match(/gnubok-invite-token=([^;]+)/) @@ -260,19 +234,11 @@ function RegisterPageContent() { if (res.ok) { document.cookie = 'gnubok-invite-token=; path=/; max-age=0' - console.log('[register] invite accepted after auto-confirm — redirecting') window.location.href = '/' return } - - // Log the error response so we can diagnose invite failures - const errBody = await res.json().catch(() => ({})) - console.error('[register] invite acceptance returned non-ok', { - status: res.status, - error: errBody.error, - }) } catch (err) { - console.error('[register] invite acceptance failed:', err) + console.error('[register] invite acceptance failed:', err instanceof Error ? err.message : String(err)) } } @@ -294,13 +260,7 @@ function RegisterPageContent() { setEmail(emailValue) setIsRegistered(true) } catch (error) { - console.error('[register] unexpected exception', { - error, - message: error instanceof Error ? error.message : String(error), - stack: error instanceof Error ? error.stack : undefined, - type: typeof error, - constructor: error?.constructor?.name, - }) + console.error('[register] unexpected exception', error instanceof Error ? error.message : String(error)) toast({ title: t('register_failed_title'), description: getErrorMessage(error, { context: 'auth', locale: errorLocale }), @@ -329,7 +289,7 @@ function RegisterPageContent() {

-
+

{t('duplicate_hint')}

@@ -377,7 +337,7 @@ function RegisterPageContent() {

-
+

{t('confirm_email_hint')}

@@ -416,7 +376,7 @@ function RegisterPageContent() {

-
+
{bankIdEnabled && !bankIdUser && ( <>
diff --git a/app/(auth)/reset-password/page.tsx b/app/(auth)/reset-password/page.tsx index aa589f05..446c1ac2 100644 --- a/app/(auth)/reset-password/page.tsx +++ b/app/(auth)/reset-password/page.tsx @@ -40,7 +40,7 @@ export default function ResetPasswordPage() { if (password !== confirmPassword) { toast({ title: t('mismatch_title'), - description: t('weak_description'), + description: t('mismatch_description'), variant: 'destructive', }) setIsLoading(false) @@ -102,7 +102,7 @@ export default function ResetPasswordPage() {

-
+
diff --git a/app/(dashboard)/articles/[id]/page.tsx b/app/(dashboard)/articles/[id]/page.tsx index ab4f3e1c..39461828 100644 --- a/app/(dashboard)/articles/[id]/page.tsx +++ b/app/(dashboard)/articles/[id]/page.tsx @@ -189,7 +189,7 @@ export default function ArticleDetailPage({
-

{article.name}

+

{article.name}

{t(ARTICLE_TYPE_KEY[article.type])} {article.article_number && ( diff --git a/app/(dashboard)/bookkeeping/[id]/page.tsx b/app/(dashboard)/bookkeeping/[id]/page.tsx index f5c2d4d0..458d8dfb 100644 --- a/app/(dashboard)/bookkeeping/[id]/page.tsx +++ b/app/(dashboard)/bookkeeping/[id]/page.tsx @@ -255,7 +255,7 @@ export default function JournalEntryDetailPage({ params }: { params: Promise<{ i
-

+

{formatVoucher(entry)}

@@ -366,7 +366,7 @@ export default function JournalEntryDetailPage({ params }: { params: Promise<{ i {entry.committed_at && (
{t('field_posted_at')} - {new Date(entry.committed_at).toLocaleDateString('sv-SE')} + {formatDate(entry.committed_at)}
)}
diff --git a/app/(dashboard)/bookkeeping/year-end/periodisering/page.tsx b/app/(dashboard)/bookkeeping/year-end/periodisering/page.tsx index c7151a86..ff74a7c8 100644 --- a/app/(dashboard)/bookkeeping/year-end/periodisering/page.tsx +++ b/app/(dashboard)/bookkeeping/year-end/periodisering/page.tsx @@ -808,7 +808,7 @@ function ManualEntryEditor({

{template.name}

-
diff --git a/app/(dashboard)/customers/[id]/page.tsx b/app/(dashboard)/customers/[id]/page.tsx index a7c7b6f3..7c8824d3 100644 --- a/app/(dashboard)/customers/[id]/page.tsx +++ b/app/(dashboard)/customers/[id]/page.tsx @@ -203,7 +203,7 @@ export default function CustomerDetailPage({
-

{customer.name}

+

{customer.name}

{t(CUSTOMER_TYPE_KEY[customer.customer_type])}
diff --git a/app/(dashboard)/deadlines/page.tsx b/app/(dashboard)/deadlines/page.tsx index dbd418ac..db3c87bf 100644 --- a/app/(dashboard)/deadlines/page.tsx +++ b/app/(dashboard)/deadlines/page.tsx @@ -10,6 +10,7 @@ import { DeadlineList } from '@/components/deadlines/DeadlineList' import { PageHeader } from '@/components/ui/page-header' import { AlertTriangle, ArrowRight } from 'lucide-react' import { useCompany } from '@/contexts/CompanyContext' +import { formatCurrency } from '@/lib/utils' import type { Deadline } from '@/types' const supabase = createClient() @@ -224,7 +225,7 @@ export default function DeadlinesPage() { } return ( -
+
{/* Overdue invoices alert */} @@ -235,8 +236,8 @@ export default function DeadlinesPage() {

{t('overdue_invoices', { count: overdueInvoices.count })} - - {overdueInvoices.total.toLocaleString('sv-SE')} kr + + {formatCurrency(overdueInvoices.total)}

diff --git a/app/(dashboard)/error.tsx b/app/(dashboard)/error.tsx index 08adf3e7..38a962c4 100644 --- a/app/(dashboard)/error.tsx +++ b/app/(dashboard)/error.tsx @@ -17,7 +17,7 @@ export default function DashboardError({ return (
-

Nagot gick fel

+

Något gick fel

Ett oväntat fel uppstod. Försök igen eller{' '} kontakta support{' '} diff --git a/app/(dashboard)/help/page.tsx b/app/(dashboard)/help/page.tsx index e886b386..d496ffd1 100644 --- a/app/(dashboard)/help/page.tsx +++ b/app/(dashboard)/help/page.tsx @@ -210,12 +210,12 @@ const glossaryTerms: GlossaryTerm[] = [ ] const categoryConfig = { - skatt: { labelKey: 'category_skatt', icon: Calculator, color: 'bg-orange-500/10 text-orange-600' }, - moms: { labelKey: 'category_moms', icon: Receipt, color: 'bg-blue-500/10 text-blue-600' }, - faktura: { labelKey: 'category_faktura', icon: FileText, color: 'bg-success/10 text-success' }, - bokföring: { labelKey: 'category_bokforing', icon: BookOpen, color: 'bg-purple-500/10 text-purple-600' }, - bank: { labelKey: 'category_bank', icon: Building2, color: 'bg-pink-500/10 text-pink-600' }, - företag: { labelKey: 'category_foretag', icon: Building2, color: 'bg-cyan-500/10 text-cyan-600' }, + skatt: { labelKey: 'category_skatt', icon: Calculator, color: 'bg-secondary text-muted-foreground' }, + moms: { labelKey: 'category_moms', icon: Receipt, color: 'bg-secondary text-muted-foreground' }, + faktura: { labelKey: 'category_faktura', icon: FileText, color: 'bg-secondary text-muted-foreground' }, + bokföring: { labelKey: 'category_bokforing', icon: BookOpen, color: 'bg-secondary text-muted-foreground' }, + bank: { labelKey: 'category_bank', icon: Building2, color: 'bg-secondary text-muted-foreground' }, + företag: { labelKey: 'category_foretag', icon: Building2, color: 'bg-secondary text-muted-foreground' }, } function TermCard({ term, isExpanded, onToggle }: { term: GlossaryTerm; isExpanded: boolean; onToggle: () => void }) { @@ -224,7 +224,7 @@ function TermCard({ term, isExpanded, onToggle }: { term: GlossaryTerm; isExpand const CategoryIcon = config.icon return ( - +

-

{t('title')}

+

{t('title')}

{t('subtitle', { number: invoice.invoice_number ?? '' })}

diff --git a/app/(dashboard)/kpi/page.tsx b/app/(dashboard)/kpi/page.tsx index e1b238b3..2c390256 100644 --- a/app/(dashboard)/kpi/page.tsx +++ b/app/(dashboard)/kpi/page.tsx @@ -82,7 +82,7 @@ export default function KpiPage() { return (
-

{t('title')}

+

{t('title')}

{[1, 2, 3, 4].map((i) => ( -
+
@@ -17,7 +17,7 @@ export default function DashboardLoading() { {/* Income / Expenses */}
{[1, 2].map((i) => ( -
+
@@ -27,12 +27,12 @@ export default function DashboardLoading() { {/* Alerts + deadlines */}
-
+
-
+
{[1, 2, 3].map((i) => (
diff --git a/app/(dashboard)/salary/employees/[id]/page.tsx b/app/(dashboard)/salary/employees/[id]/page.tsx index e73d074a..d3eec73f 100644 --- a/app/(dashboard)/salary/employees/[id]/page.tsx +++ b/app/(dashboard)/salary/employees/[id]/page.tsx @@ -144,7 +144,7 @@ export default function EmployeeDetailPage({ params }: { params: Promise<{ id: s
-

+

{employee.first_name} {employee.last_name}

diff --git a/app/(dashboard)/salary/employees/new/page.tsx b/app/(dashboard)/salary/employees/new/page.tsx index 00018c35..c6206a3d 100644 --- a/app/(dashboard)/salary/employees/new/page.tsx +++ b/app/(dashboard)/salary/employees/new/page.tsx @@ -92,7 +92,7 @@ export default function NewEmployeePage() { -

Ny anställd

+

Ny anställd

diff --git a/app/(dashboard)/salary/employees/page.tsx b/app/(dashboard)/salary/employees/page.tsx index 08c8f923..25ef1783 100644 --- a/app/(dashboard)/salary/employees/page.tsx +++ b/app/(dashboard)/salary/employees/page.tsx @@ -45,7 +45,7 @@ export default function EmployeesPage() {
-

{t('title')}

+

{t('title')}

{t('registered_count', { count: employees.length })}

diff --git a/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx b/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx index 527a4204..13324de6 100644 --- a/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx +++ b/app/(dashboard)/salary/runs/[id]/employees/[employeeId]/page.tsx @@ -168,7 +168,7 @@ export default function SalaryRunEmployeeDetailPage({
-

+

{employee.first_name} {employee.last_name}

@@ -312,7 +312,7 @@ function SummaryCard({ label, value, accent, overridden }: { label: string; valu function AbsenceCount({ label, days }: { label: string; days: number }) { return ( -

+
{label}
{days} dagar
diff --git a/app/(dashboard)/salary/runs/[id]/page.tsx b/app/(dashboard)/salary/runs/[id]/page.tsx index 88bc5069..84911301 100644 --- a/app/(dashboard)/salary/runs/[id]/page.tsx +++ b/app/(dashboard)/salary/runs/[id]/page.tsx @@ -387,7 +387,7 @@ export default function SalaryRunDetailPage({ params }: { params: Promise<{ id:
-

+

Lönekörning {periodLabel}

@@ -426,7 +426,7 @@ export default function SalaryRunDetailPage({ params }: { params: Promise<{ id:

{label}

-

+

{formatCurrency(value)}

diff --git a/app/(dashboard)/salary/runs/new/page.tsx b/app/(dashboard)/salary/runs/new/page.tsx index 97e47090..fe22bbec 100644 --- a/app/(dashboard)/salary/runs/new/page.tsx +++ b/app/(dashboard)/salary/runs/new/page.tsx @@ -61,7 +61,7 @@ export default function NewSalaryRunPage() { -

Ny lönekörning

+

Ny lönekörning

diff --git a/app/(dashboard)/supplier-invoices/[id]/page.tsx b/app/(dashboard)/supplier-invoices/[id]/page.tsx index a83310fb..a0ab53ab 100644 --- a/app/(dashboard)/supplier-invoices/[id]/page.tsx +++ b/app/(dashboard)/supplier-invoices/[id]/page.tsx @@ -581,7 +581,7 @@ export default function SupplierInvoiceDetailPage() { {invoice.delivery_date && (
{t('delivery_date_label')} - {invoice.delivery_date} + {formatDate(invoice.delivery_date)}
)} {invoice.payment_reference && ( diff --git a/app/(dashboard)/supplier-invoices/new/page.tsx b/app/(dashboard)/supplier-invoices/new/page.tsx index 300d954f..c1e54d47 100644 --- a/app/(dashboard)/supplier-invoices/new/page.tsx +++ b/app/(dashboard)/supplier-invoices/new/page.tsx @@ -1439,7 +1439,7 @@ export default function NewSupplierInvoicePage() { {/* Valuta & moms — kept inline with the line items because they drive how each row is interpreted. Hidden defaults (SEK + normal moms) collapse to nothing so most users don't see this. */} -
+
-

{supplier.name}

+

{supplier.name}

{supplierTypeLabels[supplier.supplier_type]} {supplier.org_number && t('org_number_inline', { number: supplier.org_number })} @@ -189,7 +189,7 @@ export default function SupplierDetailPage() { {t('outstanding')} -

{formatAmount(supplier.stats?.total_outstanding || 0)} kr

+

{formatAmount(supplier.stats?.total_outstanding || 0)} kr

@@ -197,7 +197,7 @@ export default function SupplierDetailPage() { {t('total_paid')} -

{formatAmount(supplier.stats?.total_paid || 0)} kr

+

{formatAmount(supplier.stats?.total_paid || 0)} kr

@@ -205,7 +205,7 @@ export default function SupplierDetailPage() { {t('invoice_count')} -

{supplier.stats?.invoice_count || 0}

+

{supplier.stats?.invoice_count || 0}

diff --git a/app/(dashboard)/suppliers/page.tsx b/app/(dashboard)/suppliers/page.tsx index 364d4d93..881d0cdf 100644 --- a/app/(dashboard)/suppliers/page.tsx +++ b/app/(dashboard)/suppliers/page.tsx @@ -8,6 +8,7 @@ import { Card, CardContent } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' import { EmptyState } from '@/components/ui/empty-state' +import { Skeleton } from '@/components/ui/skeleton' import { ReportExportMenu } from '@/components/reports/ReportExportMenu' import { useToast } from '@/components/ui/use-toast' import { Plus, Search, Building2, Lock } from 'lucide-react' @@ -114,7 +115,7 @@ export default function SuppliersPage() {
-

{t('title')}

+

{t('title')}

{t('subtitle')}

@@ -168,13 +169,13 @@ export default function SuppliersPage() { {isLoading ? (
{[1, 2, 3].map((i) => ( - + -
-
+ +
-
-
+ + ))} @@ -206,7 +207,7 @@ export default function SuppliersPage() { const location = formatLocation(supplier) return ( - +

@@ -217,7 +218,7 @@ export default function SuppliersPage() {

-
+
{supplier.org_number && (
{t('label_org_number')}
diff --git a/app/(dashboard)/transactions/page.tsx b/app/(dashboard)/transactions/page.tsx index ff6c46d7..33877330 100644 --- a/app/(dashboard)/transactions/page.tsx +++ b/app/(dashboard)/transactions/page.tsx @@ -2061,7 +2061,7 @@ export default function TransactionsPage() { } return ( -
+
{/* Status bar */} - )} @@ -449,7 +449,7 @@ export function BankIdAuth({ mode, onComplete }: BankIdAuthProps) { {isMobile() && (
-

Oppnar BankID-appen...

+

Öppnar BankID-appen...

)} diff --git a/components/bookkeeping/CorrectionChain.tsx b/components/bookkeeping/CorrectionChain.tsx index 2be6db95..bf8dac98 100644 --- a/components/bookkeeping/CorrectionChain.tsx +++ b/components/bookkeeping/CorrectionChain.tsx @@ -5,7 +5,7 @@ import { useTranslations } from 'next-intl' import { Badge } from '@/components/ui/badge' import { Info } from 'lucide-react' import JournalEntryStatusBadge from '@/components/bookkeeping/JournalEntryStatusBadge' -import { formatDate } from '@/lib/utils' +import { formatDate, formatCurrency } from '@/lib/utils' import { formatVoucher } from '@/lib/bookkeeping/voucher-series-resolver' import type { JournalEntry, JournalEntryLine } from '@/types' @@ -89,7 +89,7 @@ export default function CorrectionChain({ currentEntryId, chain }: Props) { )} - {total.toLocaleString('sv-SE', { minimumFractionDigits: 2 })} kr + {formatCurrency(total)}
{entry.description && ( diff --git a/components/bookkeeping/DocumentUploadZone.tsx b/components/bookkeeping/DocumentUploadZone.tsx index 8aeb29f2..535ca0dc 100644 --- a/components/bookkeeping/DocumentUploadZone.tsx +++ b/components/bookkeeping/DocumentUploadZone.tsx @@ -207,7 +207,7 @@ export default function DocumentUploadZone({
{ e.stopPropagation() diff --git a/components/bookkeeping/JournalEntryReviewContent.tsx b/components/bookkeeping/JournalEntryReviewContent.tsx index 0eb87ee0..cab9524f 100644 --- a/components/bookkeeping/JournalEntryReviewContent.tsx +++ b/components/bookkeeping/JournalEntryReviewContent.tsx @@ -3,6 +3,7 @@ import { Badge } from '@/components/ui/badge' import { AccountNumber } from '@/components/ui/account-number' import { CheckCircle2, Paperclip } from 'lucide-react' +import { formatDate } from '@/lib/utils' interface ReviewLine { account_number: string @@ -58,7 +59,7 @@ export function JournalEntryReviewContent({ {!hideDate && (
Datum -

{entryDate}

+

{formatDate(entryDate)}

)} {voucherSeries && ( @@ -84,7 +85,7 @@ export function JournalEntryReviewContent({ {(showBalanceBadge || (attachmentCount != null && attachmentCount > 0)) && (
{showBalanceBadge && ( - + Debet = Kredit @@ -92,7 +93,7 @@ export function JournalEntryReviewContent({ {attachmentCount != null && attachmentCount > 0 && ( - {attachmentCount} {attachmentCount === 1 ? 'underlag' : 'underlag'} + {attachmentCount} underlag )}
diff --git a/components/bookkeeping/year-end/AccrualsStep.tsx b/components/bookkeeping/year-end/AccrualsStep.tsx index ec6feba6..b9c08aff 100644 --- a/components/bookkeeping/year-end/AccrualsStep.tsx +++ b/components/bookkeeping/year-end/AccrualsStep.tsx @@ -308,7 +308,7 @@ function ManualEntryEditor({ {entry.kind === 'manual_prepaid_expense' && 'Förutbetald kostnad'} {entry.kind === 'manual_accrued_expense' && 'Upplupen kostnad'}

-
diff --git a/components/dashboard/AgentSetupBanner.tsx b/components/dashboard/AgentSetupBanner.tsx index 9c46f300..00568615 100644 --- a/components/dashboard/AgentSetupBanner.tsx +++ b/components/dashboard/AgentSetupBanner.tsx @@ -18,7 +18,7 @@ export default function AgentSetupBanner({ companyName }: Props) { href="/onboarding/agent" className="group block rounded-lg border border-border bg-card hover:bg-secondary/60 transition-colors duration-150 mb-8" > -
+
diff --git a/components/dashboard/CompanySwitcher.tsx b/components/dashboard/CompanySwitcher.tsx index f7afb267..e6f211b6 100644 --- a/components/dashboard/CompanySwitcher.tsx +++ b/components/dashboard/CompanySwitcher.tsx @@ -120,7 +120,7 @@ export default function CompanySwitcher() { return ( {t('add_company')} @@ -133,7 +133,7 @@ export default function CompanySwitcher() { @@ -270,7 +269,7 @@ export default function WelcomeOnboarding({
{/* Greeting header */}
-

+

{greeting}{firstName ? `, ${firstName}` : ''}

@@ -319,7 +318,7 @@ export default function WelcomeOnboarding({

-

+

{stepInfo.title}

diff --git a/components/deadlines/DeadlineCard.tsx b/components/deadlines/DeadlineCard.tsx index 06f7130a..fa3e65f0 100644 --- a/components/deadlines/DeadlineCard.tsx +++ b/components/deadlines/DeadlineCard.tsx @@ -151,7 +151,7 @@ export function DeadlineCard({ {/* Date block */}

{dayNum} diff --git a/components/extensions/general/ArcimMigrationWorkspace.tsx b/components/extensions/general/ArcimMigrationWorkspace.tsx index b234c9e6..7fc4e5bc 100644 --- a/components/extensions/general/ArcimMigrationWorkspace.tsx +++ b/components/extensions/general/ArcimMigrationWorkspace.tsx @@ -395,10 +395,10 @@ function ProviderStep({ setMappings(prev => ({ ...prev, [field.key]: val }))} > - + {headers.map(h => ( @@ -218,7 +218,7 @@ export default function CsvImportWizard({

{importCount} rader importerades

- Fran {fileName} + Från {fileName}