feat: enhance API response handling and add new components for module management
Some checks failed
Workflow / ʦ TypeScript (push) Failing after 4m50s
Workflow / ⚫️ Test (push) Has been skipped

This commit is contained in:
T. Zehetbauer
2026-04-01 15:18:24 +02:00
parent f82a366a52
commit 7b078f298b
58 changed files with 1845 additions and 398 deletions

View File

@@ -1,11 +1,22 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { zodResolver } from '@hookform/resolvers/zod';
import { useAction } from 'next-safe-action/hooks';
import { useForm } from 'react-hook-form';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@kit/ui/alert-dialog';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import {
@@ -17,7 +28,7 @@ import {
FormMessage,
} from '@kit/ui/form';
import { Input } from '@kit/ui/input';
import { toast } from '@kit/ui/sonner';
import { useActionWithToast } from '@kit/ui/use-action-with-toast';
import { CreateMemberSchema } from '../schema/member.schema';
import { createMember } from '../server/actions/member-actions';
@@ -28,12 +39,19 @@ interface Props {
duesCategories: Array<{ id: string; name: string; amount: number }>;
}
interface DuplicateEntry {
field: string;
message: string;
id?: string;
}
export function CreateMemberForm({
accountId,
account,
duesCategories,
}: Props) {
const router = useRouter();
const [duplicates, setDuplicates] = useState<DuplicateEntry[]>([]);
const form = useForm({
resolver: zodResolver(CreateMemberSchema),
defaultValues: {
@@ -59,15 +77,16 @@ export function CreateMemberForm({
},
});
const { execute, isPending } = useAction(createMember, {
onSuccess: ({ data }) => {
if (data?.success) {
toast.success('Mitglied erfolgreich erstellt');
router.push(`/home/${account}/members-cms`);
}
const { execute, isPending } = useActionWithToast(createMember, {
successMessage: 'Mitglied erfolgreich erstellt',
errorMessage: 'Fehler beim Erstellen',
onSuccess: () => {
router.push(`/home/${account}/members-cms`);
},
onError: ({ error }) => {
toast.error(error.serverError ?? 'Fehler beim Erstellen');
onError: (_error, data) => {
if (data?.validationErrors) {
setDuplicates(data.validationErrors as DuplicateEntry[]);
}
},
});
@@ -586,6 +605,37 @@ export function CreateMemberForm({
</Button>
</div>
</form>
<AlertDialog
open={duplicates.length > 0}
onOpenChange={() => setDuplicates([])}
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Mögliches Duplikat gefunden</AlertDialogTitle>
<AlertDialogDescription>
Es wurden ähnliche Mitglieder gefunden:
<ul className="mt-2 list-inside list-disc">
{duplicates.map((d, i) => (
<li key={d.id ?? i}>{d.message}</li>
))}
</ul>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Abbrechen</AlertDialogCancel>
<AlertDialogAction
onClick={() => {
router.push(
`/home/${account}/members-cms/${duplicates[0]?.id}`,
);
}}
>
Zum bestehenden Mitglied
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</Form>
);
}