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

@@ -3,7 +3,6 @@
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 { Button } from '@kit/ui/button';
@@ -17,7 +16,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 { CreatePageSchema } from '../schema/site.schema';
import { createPage } from '../server/actions/site-builder-actions';
@@ -51,15 +50,14 @@ export function CreatePageForm({ accountId, account }: Props) {
.replace(/ß/g, 'ss')
.replace(/^-|-$/g, '');
const { execute, isPending } = useAction(createPage, {
onSuccess: ({ data }) => {
if (data?.success && data.data) {
toast.success('Seite erstellt — Editor wird geöffnet');
const { execute, isPending } = useActionWithToast(createPage, {
successMessage: 'Seite erstellt — Editor wird geöffnet',
errorMessage: 'Fehler beim Erstellen',
onSuccess: (data) => {
if (data?.data) {
router.push(`/home/${account}/site-builder/${data.data.id}/edit`);
}
},
onError: ({ error }) =>
toast.error(error.serverError ?? 'Fehler beim Erstellen'),
});
return (

View File

@@ -3,7 +3,6 @@
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 { Button } from '@kit/ui/button';
@@ -17,7 +16,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 { CreatePostSchema } from '../schema/site.schema';
import { createPost } from '../server/actions/site-builder-actions';
@@ -53,12 +52,11 @@ export function CreatePostForm({ accountId, account }: Props) {
.replace(/ü/g, 'ue')
.replace(/ß/g, 'ss');
const { execute, isPending } = useAction(createPost, {
const { execute, isPending } = useActionWithToast(createPost, {
successMessage: 'Beitrag erstellt',
onSuccess: () => {
toast.success('Beitrag erstellt');
router.push(`/home/${account}/site-builder/posts`);
},
onError: ({ error }) => toast.error(error.serverError ?? 'Fehler'),
});
return (

View File

@@ -3,9 +3,7 @@
import { Puck } from '@measured/puck';
import '@measured/puck/puck.css';
import { useAction } from 'next-safe-action/hooks';
import { toast } from '@kit/ui/sonner';
import { useActionWithToast } from '@kit/ui/use-action-with-toast';
import { clubPuckConfig } from '../config/puck-config';
import { publishPage } from '../server/actions/site-builder-actions';
@@ -17,9 +15,8 @@ interface Props {
}
export function SiteEditor({ pageId, accountId, initialData }: Props) {
const { execute: execPublish } = useAction(publishPage, {
onSuccess: () => toast.success('Seite veröffentlicht'),
onError: ({ error }) => toast.error(error.serverError ?? 'Fehler'),
const { execute: execPublish } = useActionWithToast(publishPage, {
successMessage: 'Seite veröffentlicht',
});
const PuckAny = Puck as any;

View File

@@ -3,7 +3,6 @@
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 { Button } from '@kit/ui/button';
@@ -17,7 +16,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 { SiteSettingsSchema } from '../schema/site.schema';
import { updateSiteSettings } from '../server/actions/site-builder-actions';
@@ -50,12 +49,11 @@ export function SiteSettingsForm({ accountId, account, settings }: Props) {
},
});
const { execute, isPending } = useAction(updateSiteSettings, {
const { execute, isPending } = useActionWithToast(updateSiteSettings, {
successMessage: 'Einstellungen gespeichert',
onSuccess: () => {
toast.success('Einstellungen gespeichert');
router.refresh();
},
onError: ({ error }) => toast.error(error.serverError ?? 'Fehler'),
});
return (

View File

@@ -3,6 +3,7 @@ import React from 'react';
import type { Config } from '@measured/puck';
import { formatDate, formatMonthShort } from '@kit/shared/dates';
import { toast } from '@kit/ui/sonner';
import { useSiteData } from '../context/site-data-context';
@@ -71,13 +72,13 @@ const ContactFormBlock = ({
});
const result = await res.json();
if (result.success) {
alert('Nachricht erfolgreich gesendet!');
toast.success('Nachricht erfolgreich gesendet!');
form.reset();
} else {
alert(result.error || 'Fehler beim Senden');
toast.error(result.error || 'Fehler beim Senden');
}
} catch {
alert('Verbindungsfehler');
toast.error('Verbindungsfehler');
}
};
@@ -219,13 +220,15 @@ const NewsletterSignupBlock = ({
});
const result = await res.json();
if (result.success) {
alert('Erfolgreich angemeldet! Bitte bestätigen Sie Ihre E-Mail.');
toast.success(
'Erfolgreich angemeldet! Bitte bestätigen Sie Ihre E-Mail.',
);
form.reset();
} else {
alert(result.error || 'Fehler bei der Anmeldung');
toast.error(result.error || 'Fehler bei der Anmeldung');
}
} catch {
alert('Verbindungsfehler');
toast.error('Verbindungsfehler');
}
};
@@ -399,6 +402,8 @@ const EventListBlock = ({
email: '',
phone: '',
dateOfBirth: '',
parentName: '',
parentPhone: '',
});
const [submitting, setSubmitting] = React.useState(false);
const [successId, setSuccessId] = React.useState<string | null>(null);
@@ -426,6 +431,8 @@ const EventListBlock = ({
email: formData.email,
phone: formData.phone || undefined,
dateOfBirth: formData.dateOfBirth || undefined,
parentName: formData.parentName || undefined,
parentPhone: formData.parentPhone || undefined,
}),
});
const result = await res.json();
@@ -438,6 +445,8 @@ const EventListBlock = ({
email: '',
phone: '',
dateOfBirth: '',
parentName: '',
parentPhone: '',
});
} else {
setErrorMsg(result.error || 'Anmeldung fehlgeschlagen.');
@@ -574,6 +583,29 @@ const EventListBlock = ({
}
className="rounded-md border px-3 py-2 text-sm"
/>
<input
placeholder="Name Erziehungsberechtigter"
value={formData.parentName}
onChange={(e) =>
setFormData((p) => ({
...p,
parentName: e.target.value,
}))
}
className="rounded-md border px-3 py-2 text-sm"
/>
<input
placeholder="Telefon Erziehungsberechtigter"
type="tel"
value={formData.parentPhone}
onChange={(e) =>
setFormData((p) => ({
...p,
parentPhone: e.target.value,
}))
}
className="rounded-md border px-3 py-2 text-sm"
/>
</div>
{errorMsg && (
<p className="mt-2 text-sm text-red-600">{errorMsg}</p>