feat(finance): add SEPA batch actions — populate, manual add, XML download
The SEPA batch detail page was a dead end: users could create a batch but had no way to add payment positions or generate the XML file. Added SepaBatchActions client component with three key workflows: 1. 'Mitglieder hinzufügen' — auto-populates batch from all active members who have a SEPA mandate and dues category (calls existing populateBatchFromMembers server action) 2. 'Einzelposition' — dialog to manually add a single debit item with Name, IBAN, Amount, and Verwendungszweck fields 3. 'XML herunterladen' — dialog for creditor info (Gläubiger-Name, IBAN, BIC, Gläubiger-ID) then generates and triggers download of the SEPA pain.008 XML file. Disabled when batch has 0 positions. Also fixed: SEPA list page crashed because a Server Component had an onClick handler on a <tr> — removed the invalid event handler. Target demographic: German association treasurers (Kassenwarte) who need a straightforward workflow for annual membership fee collection via SEPA Lastschrift.
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { ArrowLeft, Download } from 'lucide-react';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
import { createFinanceApi } from '@kit/finance/api';
|
||||
import { SepaBatchActions } from '@kit/finance/components';
|
||||
import { formatDate } from '@kit/shared/dates';
|
||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||
import { Badge } from '@kit/ui/badge';
|
||||
import { Button } from '@kit/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
|
||||
|
||||
import { AccountNotFound } from '~/components/account-not-found';
|
||||
@@ -124,10 +124,12 @@ export default async function SepaBatchDetailPage({ params }: PageProps) {
|
||||
</dl>
|
||||
|
||||
<div className="mt-6">
|
||||
<Button disabled variant="outline">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
{t('sepa.downloadXml')}
|
||||
</Button>
|
||||
<SepaBatchActions
|
||||
batchId={batchId}
|
||||
accountId={acct.id}
|
||||
batchStatus={status}
|
||||
itemCount={items.length}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -108,7 +108,7 @@ export default async function SepaPage({ params }: PageProps) {
|
||||
{batches.map((batch: Record<string, unknown>) => (
|
||||
<tr
|
||||
key={String(batch.id)}
|
||||
className="hover:bg-muted/30 border-b"
|
||||
className="hover:bg-muted/30 cursor-pointer border-b"
|
||||
>
|
||||
<td className="p-3">
|
||||
<Badge
|
||||
@@ -131,7 +131,7 @@ export default async function SepaPage({ params }: PageProps) {
|
||||
<td className="p-3">
|
||||
<Link
|
||||
href={`/home/${account}/finance/sepa/${String(batch.id)}`}
|
||||
className="hover:underline"
|
||||
className="font-medium hover:underline"
|
||||
>
|
||||
{String(batch.description ?? '—')}
|
||||
</Link>
|
||||
|
||||
Reference in New Issue
Block a user