diff --git a/app/(dashboard)/settings/page.tsx b/app/(dashboard)/settings/page.tsx index 15878845..a78c6096 100644 --- a/app/(dashboard)/settings/page.tsx +++ b/app/(dashboard)/settings/page.tsx @@ -56,6 +56,8 @@ export default function SettingsPage() { const hasMcpExtension = ENABLED_EXTENSION_IDS.has('mcp-server') const [bankConnectionError, setBankConnectionError] = useState(null) const [bankgiroError, setBankgiroError] = useState(null) + const [clearingError, setClearingError] = useState(null) + const [accountNumberError, setAccountNumberError] = useState(null) const [showDeleteDialog, setShowDeleteDialog] = useState(false) const [deleteConfirmText, setDeleteConfirmText] = useState('') const [isDeleting, setIsDeleting] = useState(false) @@ -148,10 +150,40 @@ export default function SettingsPage() { e.preventDefault() if (!settings) return - setIsSaving(true) - const formData = new FormData(e.currentTarget) + // Validate bank fields before saving + const clearingVal = (formData.get('clearing_number') as string || '').trim() + const accountVal = (formData.get('account_number') as string || '').trim() + const bankgiroVal = (formData.get('bankgiro') as string || '').trim() + + let hasErrors = false + + if (clearingVal && !/^\d{4,5}$/.test(clearingVal)) { + setClearingError('Clearingnummer måste vara 4-5 siffror') + hasErrors = true + } else { + setClearingError(null) + } + + if (accountVal && !/^\d{6,12}$/.test(accountVal)) { + setAccountNumberError('Kontonummer måste vara 6-12 siffror') + hasErrors = true + } else { + setAccountNumberError(null) + } + + if (bankgiroVal && !validateBankgiroNumber(bankgiroVal)) { + setBankgiroError('Ogiltigt bankgironummer (7-8 siffror med kontrollsiffra)') + hasErrors = true + } else { + setBankgiroError(null) + } + + if (hasErrors) return + + setIsSaving(true) + // Disabled inputs are excluded from FormData by the browser, // so only include company_name/org_number when not locked const updates: Record = { @@ -392,6 +424,8 @@ export default function SettingsPage() { @@ -400,16 +434,58 @@ export default function SettingsPage() { { + e.target.value = e.target.value.replace(/\D/g, '') + }} + onBlur={(e) => { + const val = e.target.value.trim() + if (!val) { + setClearingError(null) + return + } + if (!/^\d{4,5}$/.test(val)) { + setClearingError('Clearingnummer måste vara 4-5 siffror') + } else { + setClearingError(null) + } + }} /> + {clearingError && ( +

{clearingError}

+ )}
{ + e.target.value = e.target.value.replace(/\D/g, '') + }} + onBlur={(e) => { + const val = e.target.value.trim() + if (!val) { + setAccountNumberError(null) + return + } + if (!/^\d{6,12}$/.test(val)) { + setAccountNumberError('Kontonummer måste vara 6-12 siffror') + } else { + setAccountNumberError(null) + } + }} /> + {accountNumberError && ( +

{accountNumberError}

+ )}
diff --git a/components/bookkeeping/AccountCombobox.tsx b/components/bookkeeping/AccountCombobox.tsx index 04fbc738..8160b701 100644 --- a/components/bookkeeping/AccountCombobox.tsx +++ b/components/bookkeeping/AccountCombobox.tsx @@ -104,7 +104,6 @@ export default function AccountCombobox({ value, accounts, onChange }: AccountCo onChange(accountNumber) setSearch(accountNumber) setIsOpen(false) - inputRef.current?.blur() }, [onChange] ) diff --git a/lib/api/schemas.ts b/lib/api/schemas.ts index 7fb62a09..807220b6 100644 --- a/lib/api/schemas.ts +++ b/lib/api/schemas.ts @@ -369,10 +369,10 @@ export const UpdateSettingsSchema = z.object({ moms_period: MomsPeriodSchema.nullable().optional(), fiscal_year_start_month: z.number().int().min(1).max(12).optional(), preliminary_tax_monthly: z.number().nullable().optional(), - bank_name: z.string().optional(), - clearing_number: z.string().optional(), - account_number: z.string().optional(), - bankgiro: z.string().nullable().optional(), + bank_name: z.string().max(100, 'Banknamn får vara max 100 tecken').optional(), + clearing_number: z.string().regex(/^\d{4,5}$/, 'Clearingnummer måste vara 4-5 siffror').optional().or(z.literal('')), + account_number: z.string().regex(/^\d{6,12}$/, 'Kontonummer måste vara 6-12 siffror').optional().or(z.literal('')), + bankgiro: z.string().regex(/^(\d{3,4}-\d{4}|\d{7,8})$/, 'Ogiltigt bankgironummer (7-8 siffror)').nullable().optional().or(z.literal('')), iban: z.string().optional(), bic: z.string().optional(), accounting_method: AccountingMethodSchema.optional(),