Files
accounted/components/onboarding/Step6ConnectBank.tsx
T
Jakob WennbergandClaude Opus 4.6 f3ec634a46 feat: open-source under AGPL-3.0, redesign UI to grayscale palette, add uncategorize API, fix VAT account names
Add LICENSE (AGPL-3.0-or-later), CONTRIBUTING.md, SECURITY.md, DCO, and NOTICE files.
Rewrite README for open-source audience with self-hosting instructions.
Redesign color palette to grayscale chrome theme across all components.
Add transaction uncategorize API route with tests.
Fix VAT account name mismatches in migration 052.
Improve import page with SIE file support and loading skeleton.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:18:11 +01:00

209 lines
6.9 KiB
TypeScript

'use client'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { InfoTooltip } from '@/components/ui/info-tooltip'
import { Loader2, ArrowLeft, Landmark, SkipForward } from 'lucide-react'
const manualBankSchema = z.object({
bank_name: z.string().optional(),
clearing_number: z.string().optional(),
account_number: z.string().optional(),
iban: z.string().optional(),
bic: z.string().optional(),
})
type ManualBankData = z.infer<typeof manualBankSchema>
interface Step6Props {
initialData?: Partial<ManualBankData>
onComplete: (data?: ManualBankData) => void
onBack: () => void
onSkip: () => void
isSaving: boolean
}
export default function Step6ConnectBank({
initialData,
onBack,
onSkip,
onComplete,
isSaving,
}: Step6Props) {
const {
register,
handleSubmit,
} = useForm<ManualBankData>({
resolver: zodResolver(manualBankSchema),
mode: 'onTouched',
defaultValues: {
bank_name: initialData?.bank_name || '',
clearing_number: initialData?.clearing_number || '',
account_number: initialData?.account_number || '',
iban: initialData?.iban || '',
bic: initialData?.bic || '',
},
})
const onManualSubmit = (data: ManualBankData) => {
onComplete(data)
}
return (
<div className="space-y-6">
<div className="text-center">
<h1 className="text-3xl font-bold tracking-tight">Bankuppgifter</h1>
<p className="text-muted-foreground mt-2">
Ange dina bankuppgifter så visas de på dina fakturor.
Du kan importera transaktioner från din bank efteråt.
</p>
</div>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Landmark className="h-5 w-5" />
Bankuppgifter för fakturor
</CardTitle>
<CardDescription>
Dessa uppgifter visas på dina fakturor så att kunder kan betala dig.
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit(onManualSubmit)} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="bank_name">Bank</Label>
<Input
id="bank_name"
placeholder="t.ex. Nordea, SEB, Swedbank"
{...register('bank_name')}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<InfoTooltip
content={
<div className="space-y-2">
<p className="font-medium">Vad är clearingnummer?</p>
<p>De första 4-5 siffrorna i ditt kontonummer som identifierar din bank.</p>
<ul className="text-xs text-muted-foreground space-y-1">
<li>Nordea: 3300</li>
<li>SEB: 5000</li>
<li>Swedbank: 8XXX</li>
<li>Handelsbanken: 6XXX</li>
<li>Avanza: 9550/9551</li>
</ul>
</div>
}
side="top"
>
<Label htmlFor="clearing_number">Clearingnummer</Label>
</InfoTooltip>
<Input
id="clearing_number"
placeholder="XXXX"
{...register('clearing_number')}
/>
</div>
<div className="space-y-2">
<Label htmlFor="account_number">Kontonummer</Label>
<Input
id="account_number"
placeholder="XXX XXX XXX"
{...register('account_number')}
/>
</div>
</div>
<div className="pt-4 border-t">
<h4 className="font-medium mb-4">Internationella betalningar (valfritt)</h4>
<div className="space-y-4">
<div className="space-y-2">
<InfoTooltip
content={
<div className="space-y-2">
<p className="font-medium">Vad är IBAN?</p>
<p>Internationellt bankkontonummer. Svenska IBAN börjar med SE och har 24 tecken totalt.</p>
</div>
}
side="right"
>
<Label htmlFor="iban">IBAN</Label>
</InfoTooltip>
<Input
id="iban"
placeholder="SE00 0000 0000 0000 0000 0000"
{...register('iban')}
/>
</div>
<div className="space-y-2">
<InfoTooltip
content={
<div className="space-y-2">
<p className="font-medium">Vad är BIC/SWIFT?</p>
<p>Bankens internationella id-kod. Används tillsammans med IBAN för utlandsbetalningar.</p>
</div>
}
side="right"
>
<Label htmlFor="bic">BIC/SWIFT</Label>
</InfoTooltip>
<Input
id="bic"
placeholder="XXXXSESS"
{...register('bic')}
/>
</div>
</div>
</div>
<div className="bg-muted/50 rounded-lg p-4">
<p className="text-sm text-muted-foreground">
Du kan importera kontoutdrag (CSV, XML) från din bank under <strong>Import</strong>-sidan
efter att du slutfört registreringen.
</p>
</div>
<Button type="submit" className="w-full" disabled={isSaving}>
{isSaving ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Sparar...
</>
) : (
'Spara och slutför'
)}
</Button>
</form>
<div className="flex justify-between pt-4">
<Button
type="button"
variant="ghost"
onClick={onBack}
>
<ArrowLeft className="mr-2 h-4 w-4" />
Tillbaka
</Button>
<Button
type="button"
variant="outline"
onClick={onSkip}
>
<SkipForward className="mr-2 h-4 w-4" />
Hoppa över
</Button>
</div>
</CardContent>
</Card>
</div>
)
}