commit 3e9ddf23b26a81ee2cf254ba58aa1430946a81f3
parent 2454609d847cf89d8fd4de622d607cc706de6e16
Author: Sebastian <sebasjm@taler-systems.com>
Date: Sat, 7 Feb 2026 07:13:20 -0300
better form validation report
Diffstat:
5 files changed, 53 insertions(+), 48 deletions(-)
diff --git a/packages/web-util/src/forms/fields/InputDownloadLink.tsx b/packages/web-util/src/forms/fields/InputDownloadLink.tsx
@@ -34,46 +34,48 @@ export function InputDownloadLink(props: Props & UIFormProps<boolean>): VNode {
return (
<div class="col-span-6" data-downloaded={!!value}>
{before !== undefined && <RenderAddon addon={before} />}
- <a
- href="#"
- class="underline text-blue-600 hover:text-blue-900 visited:text-purple-600"
- onClick={(e) => {
- e.preventDefault();
- onChange(true);
- return (
- fetch(url, {
- headers: {
- "Content-Type": media ?? "text/html",
- },
- cache: "no-cache",
- })
- // .then((r) => r.text())
- .then((r) => r.arrayBuffer())
- .then((r) => {
- const b64 = window.btoa(
- new Uint8Array(r).reduce(
- (data, byte) => data + String.fromCharCode(byte),
- "",
- ),
- );
-
- const a = document.createElement("a");
- a.href = `data:${media ?? "text/html"};base64,${b64}`;
- a.download = fileName ?? "";
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- return;
+ <label for={props.name}>
+ <a
+ href="#"
+ class="underline text-blue-600 hover:text-blue-900 visited:text-purple-600"
+ onClick={(e) => {
+ e.preventDefault();
+ onChange(true);
+ return (
+ fetch(url, {
+ headers: {
+ "Content-Type": media ?? "text/html",
+ },
+ cache: "no-cache",
})
- );
- }}
- media={media}
- download
- >
- {label}
- </a>
+ // .then((r) => r.text())
+ .then((r) => r.arrayBuffer())
+ .then((r) => {
+ const b64 = window.btoa(
+ new Uint8Array(r).reduce(
+ (data, byte) => data + String.fromCharCode(byte),
+ "",
+ ),
+ );
+
+ const a = document.createElement("a");
+ a.href = `data:${media ?? "text/html"};base64,${b64}`;
+ a.download = fileName ?? "";
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ return;
+ })
+ );
+ }}
+ media={media}
+ download
+ >
+ {label}
+ </a>
+ </label>
{required ? (
- <span class="text-sm leading-6 text-red-600 pl-2">*</span>
+ <span class="text-xl bold leading-6 text-red-600 pl-2">*</span>
) : undefined}
{after !== undefined && <RenderAddon addon={after} />}
diff --git a/packages/web-util/src/forms/fields/InputLine.tsx b/packages/web-util/src/forms/fields/InputLine.tsx
@@ -62,7 +62,7 @@ export function LabelWithTooltipMaybeRequired({
return (
<div class="flex justify-between w-fit">
{WithTooltip}
- <span class="text-sm leading-6 text-red-600 pl-2">*</span>
+ <span class="text-xl bold leading-6 text-red-600 pl-2">*</span>
</div>
);
}
diff --git a/packages/web-util/src/forms/fields/InputToggle.tsx b/packages/web-util/src/forms/fields/InputToggle.tsx
@@ -40,7 +40,7 @@ export function InputToggle(
}
return (
- <div class="sm:col-span-6">
+ <div class="col-span-6">
<div class="flex items-center justify-between">
<LabelWithTooltipMaybeRequired
label={label}
diff --git a/packages/web-util/src/forms/forms-ui.tsx b/packages/web-util/src/forms/forms-ui.tsx
@@ -327,9 +327,9 @@ export function ErrorsSummary<T>({
}
}}
>
- <div class="px-4 sm:px-0">
+ <div class="px-0">
<h3 class="text-base/7 font-semibold text-gray-900">
- <i18n.Translate>Missing fields</i18n.Translate>
+ <i18n.Translate>List of fields with errors</i18n.Translate>
</h3>
</div>
@@ -402,16 +402,16 @@ export function ErrorsSummary<T>({
});
el.classList.add("animate-pulse");
- el.classList.add("border-b");
+ el.classList.add("border-b-2");
el.classList.add("border-red-700");
setTimeout(() => {
el.classList.remove("animate-pulse");
- el.classList.remove("border-b");
+ el.classList.remove("border-b-2");
el.classList.remove("border-red-700");
- }, 5000);
+ }, 6000);
}
}}
- class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0 odd:bg-white even:bg-gray-100 cursor-pointer"
+ class="py-2 grid grid-cols-2 gap-4 px-0 odd:bg-white even:bg-gray-100 cursor-pointer"
>
{errHandler.section ? (
<dt class="underline pl-4 text-sm/6 font-medium text-gray-900">
@@ -422,7 +422,7 @@ export function ErrorsSummary<T>({
{errHandler.label}
</dt>
)}
- <dd class="underline flex text-sm/6 text-red-700 sm:col-span-2 sm:mt-0">
+ <dd class="underline flex text-sm/6 text-red-700 mt-0">
{errHandler.message}
</dd>
</span>
diff --git a/packages/web-util/src/forms/gana/accept-tos.ts b/packages/web-util/src/forms/gana/accept-tos.ts
@@ -81,7 +81,10 @@ export function acceptTos(
id: TalerFormAttributes.DOWNLOADED_TERMS_OF_SERVICE,
url: context.tos_url,
label: i18n.str`Download PDF version`,
- required: true,
+ // required: true,
+ validator(text, form) {
+ return !text ? i18n.str`Click to download & read` : undefined;
+ },
media: "application/pdf",
fileName: tosFileName,
help: i18n.str`You must download to proceed`,