feat: show validation messages for all banner form fields

This commit is contained in:
2026-08-11 18:47:51 +02:00
parent 83c31d884f
commit c10bfaf68e
3 changed files with 18 additions and 15 deletions
+5 -5
View File
@@ -7,11 +7,11 @@ export const createBanner = defineAction({
accept: "form",
input: z.object({
title: z.string("system.constraint.text.notEmpty").min(1),
description: z.string().min(1),
ctaText: z.string().min(1),
ctaLink: z.url(),
startsAt: z.coerce.date().min(new Date()),
endsAt: z.coerce.date().min(new Date()),
description: z.string("system.constraint.text.notEmpty").min(1),
ctaText: z.string("system.constraint.text.notEmpty").min(1),
ctaLink: z.url("system.constraint.text.expectedUrl"),
startsAt: z.coerce.date().min(new Date(), "system.constraint.date.greaterThan"),
endsAt: z.coerce.date().min(new Date(), "system.constraint.date.greaterThan"),
}),
handler: async (input, context) => {
const { session, t } = context.locals;
@@ -1,11 +1,12 @@
<script lang="ts">
import { actions } from "astro:actions";
import { t } from "../../../../i18n/store";
import { locale, t } from "../../../../i18n/store";
import ActionableButton from "../../../library/buttons/ActionableButton.svelte";
import DateInput from "../../../library/inputs/DateInput.svelte";
import TextArea from "../../../library/inputs/TextArea.svelte";
import TextInput from "../../../library/inputs/TextInput.svelte";
import { formatDate } from "../../../../utils/dates";
interface Props {
onSubmit?: (event: SubmitEvent) => void;
@@ -24,7 +25,7 @@
async function submit() {
fieldErrors = {};
const { data, error } = await actions.createBanner(new FormData(formElement));
const { error } = await actions.createBanner(new FormData(formElement));
if (error) {
// @ts-expect-error fields does exist but astro typing sucks
@@ -34,8 +35,6 @@
Object.entries(errors ?? {}).map(([field, issues]) => [field, issues?.[0]]),
) as FieldErrors;
console.log(fieldErrors);
return;
}
}
@@ -70,7 +69,7 @@
class="flex-1"
name="description"
placeholder={$t("pages.admin.comm.banners.fields.descriptionPlaceholder")}
error={fieldErrors.description}
error={fieldErrors.description && $t(fieldErrors.description)}
/>
<div class="flex gap-6">
@@ -78,7 +77,7 @@
<TextInput
name="ctaText"
placeholder={$t("pages.admin.comm.banners.fields.ctaPlaceholder")}
error={fieldErrors.ctaText}
error={fieldErrors.ctaText && $t(fieldErrors.ctaText)}
/>
</div>
@@ -86,7 +85,7 @@
<TextInput
name="ctaLink"
placeholder={$t("pages.admin.comm.banners.fields.urlPlaceholder")}
error={fieldErrors.ctaLink}
error={fieldErrors.ctaLink && $t(fieldErrors.ctaLink)}
/>
</div>
</div>
@@ -103,14 +102,14 @@
class="flex-1"
name="startsAt"
placeholder={$t("pages.admin.comm.banners.fields.startDatePlaceholder")}
error={fieldErrors.startsAt}
error={fieldErrors.startsAt && $t(fieldErrors.startsAt, { date: formatDate(new Date(), $locale) })}
/>
<DateInput
class="flex-1"
name="endsAt"
placeholder={$t("pages.admin.comm.banners.fields.endDatePlaceholder")}
error={fieldErrors.endsAt}
error={fieldErrors.endsAt && $t(fieldErrors.endsAt, { date: formatDate(new Date(), $locale) })}
/>
</div>
</div>
+5 -1
View File
@@ -19,7 +19,11 @@
},
"constraint": {
"text": {
"notEmpty": "El texto no puede estar vacío"
"notEmpty": "El texto no puede estar vacío",
"expectedUrl": "No es una URL"
},
"date": {
"greaterThan": "La fecha debe ser mayor que {{ date }}"
},
"file": {
"maxAllowedSize": "Tamaño máximo permitido 10MB",