commit 1937095f39078b379152997590f756f0aa4b12b5
parent f214fa8477bc52e602bf2f329817390e7df03a24
Author: Sebastian <sebasjm@gmail.com>
Date: Sun, 23 Feb 2025 20:06:16 -0300
test form
Diffstat:
9 files changed, 143 insertions(+), 32 deletions(-)
diff --git a/packages/kyc-ui/src/Routing.tsx b/packages/kyc-ui/src/Routing.tsx
@@ -29,6 +29,7 @@ import { Frame } from "./pages/Frame.js";
import { Start } from "./pages/Start.js";
import { useSessionState } from "./hooks/session.js";
import { TriggerKyc } from "./pages/TriggerKyc.js";
+import { TriggerForms } from "./pages/TriggerForms.js";
export function Routing(): VNode {
// check session and defined if this is
@@ -44,6 +45,10 @@ export const publicPages = {
completed: urlPattern(/\/completed/, () => `#/completed`),
start: urlPattern(/\/start/, () => `#/start`),
triggerKyc: urlPattern(/\/test\/trigger-kyc/, () => `#/test/trigger-kyc`),
+ triggerForm: urlPattern(
+ /\/test\/show-forms\/(?<fid>[a-zA-Z0-9-_]+)/,
+ ({ fid }) => `#/test/show-forms/${fid}`,
+ ),
};
function safeGetParam(
@@ -135,12 +140,15 @@ function PublicRounting(): VNode {
return (
<TriggerKyc
onKycStarted={(token) => {
- start(token)
+ start(token);
navigateTo(publicPages.start.url({}));
}}
/>
);
}
+ case "triggerForm": {
+ return <TriggerForms formId={location.values.fid} />;
+ }
default:
assertUnreachable(location);
}
diff --git a/packages/kyc-ui/src/app.tsx b/packages/kyc-ui/src/app.tsx
@@ -34,22 +34,24 @@ import { VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { SWRConfig } from "swr";
import { Routing } from "./Routing.js";
+import { NotifierProvider } from "./context/notifier.js";
import { SettingsProvider } from "./context/settings.js";
+import { UiFormsProvider } from "./context/ui-forms.js";
+import { revalidateKycInfo } from "./hooks/kyc.js";
import { strings } from "./i18n/strings.js";
import { Frame } from "./pages/Frame.js";
import { KycUiSettings, fetchSettings } from "./settings.js";
-import { revalidateKycInfo } from "./hooks/kyc.js";
-import { fetchUiForms, UiFormsProvider } from "./context/ui-forms.js";
-import { NotifierProvider } from "./context/notifier.js";
const WITH_LOCAL_STORAGE_CACHE = false;
export function App(): VNode {
const [settings, setSettings] = useState<KycUiSettings>();
- const [forms, setForms] = useState<UiForms>();
+ const [forms, setForms] = useState<UiForms>({
+ forms: [],
+ });
useEffect(() => {
fetchSettings(setSettings);
- fetchUiForms(setForms);
+ // fetchUiForms(setForms);
}, []);
if (!settings || !forms) return <Loading />;
diff --git a/packages/kyc-ui/src/context/ui-forms.ts b/packages/kyc-ui/src/context/ui-forms.ts
@@ -58,19 +58,18 @@ function removeUndefineField<T extends object>(obj: T): T {
}
export function fetchUiForms(listener: (s: UiForms) => void): void {
- listener(defaultForms);
+ fetch("./forms.json")
+ .then((resp) => resp.json())
+ .then((json) => codecForUIForms().decode(json))
+ .then((result) =>
+ listener({
+ ...defaultForms,
+ ...removeUndefineField(result),
+ }),
+ )
+ .catch((e) => {
+ console.log("failed to fetch forms", e);
+ listener(defaultForms);
+ });
return;
- // fetch("./forms.json")
- // .then((resp) => resp.json())
- // .then((json) => codecForUIForms().decode(json))
- // .then((result) =>
- // listener({
- // ...defaultForms,
- // ...removeUndefineField(result),
- // }),
- // )
- // .catch((e) => {
- // console.log("failed to fetch forms", e);
- // listener(defaultForms);
- // });
}
diff --git a/packages/kyc-ui/src/forms/index.ts b/packages/kyc-ui/src/forms/index.ts
@@ -27,10 +27,9 @@ import {
VQF_902_5,
VQF_902_9,
} from "@gnu-taler/web-util/browser";
-import { simplest } from "./simplest.js";
import { acceptTos } from "./accept-tos.js";
import { nameAndDob } from "./nameAndBirthdate.js";
-import { personalInfo } from "./personal-info.js";
+import { simplest } from "./simplest.js";
const TALER_SCREEN_ID = 105;
diff --git a/packages/kyc-ui/src/pages/FillForm.tsx b/packages/kyc-ui/src/pages/FillForm.tsx
@@ -71,11 +71,9 @@ export function FillForm({
onComplete,
}: Props): VNode {
const { i18n } = useTranslationContext();
- const { config, lib } = useExchangeApiContext();
- // const { forms } = useUiFormsContext();
+ const { lib } = useExchangeApiContext();
const [notification, withErrorHandler] = useLocalNotificationHandler();
const [preferences] = usePreferences();
- const notifier = useNotifierContext();
const customForm =
requirement.context && "form" in requirement.context
@@ -90,17 +88,15 @@ export function FillForm({
const { forms } = useUiFormsContext();
const allForms = customForm ? [...forms, customForm] : forms;
const theForm = searchForm(i18n, allForms, formId, requirement.context);
+ const reqId = requirement.id;
if (!theForm) {
return <div>form with id {formId} not found</div>;
}
- const reqId = requirement.id;
if (!reqId) {
return <div>no id for this form, can't upload</div>;
}
- const { handler, status } = useForm<FormType>(theForm.config, {
- // CUSTOMER_ID: "123",
- });
+ const { handler, status } = useForm<FormType>(theForm.config, {});
const validatedForm = status.status !== "ok" ? undefined : status.result;
const submitHandler =
diff --git a/packages/kyc-ui/src/pages/Frame.tsx b/packages/kyc-ui/src/pages/Frame.tsx
@@ -81,7 +81,10 @@ export function Frame({ children }: { children: ComponentChildren }): VNode {
sites={
!preferences.showDebugInfo
? []
- : [["Test kyc", publicPages.triggerKyc.url({})]]
+ : [
+ ["Test kyc", publicPages.triggerKyc.url({})],
+ ["Test Forms", publicPages.triggerForm.url({})],
+ ]
}
>
<li>
diff --git a/packages/kyc-ui/src/pages/TriggerForms.tsx b/packages/kyc-ui/src/pages/TriggerForms.tsx
@@ -0,0 +1,98 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+import {
+ FormMetadata,
+ FormUI,
+ LocalNotificationBanner,
+ UIHandlerId,
+ useExchangeApiContext,
+ useForm,
+ useLocalNotificationHandler,
+ useTranslationContext,
+} from "@gnu-taler/web-util/browser";
+import { Fragment, h, VNode } from "preact";
+import { preloadedForms } from "../forms/index.js";
+
+const TALER_SCREEN_ID = 102;
+
+type FormType = {
+ form: string;
+};
+type Props = {
+ formId?: string;
+};
+export function TriggerForms({ formId }: Props): VNode {
+ const { i18n } = useTranslationContext();
+ const [notification, withErrorHandler, notify] =
+ useLocalNotificationHandler();
+ const { config, lib } = useExchangeApiContext();
+
+ const pf = preloadedForms(i18n, {});
+
+ const theForm: FormMetadata = {
+ id: "asd",
+ version: 1,
+ label: i18n.str`Trigger KYC balance`,
+ config: {
+ type: "single-column",
+ fields: [
+ {
+ id: "form" as UIHandlerId,
+ type: "selectOne",
+ label: i18n.str`Form`,
+ help: i18n.str`You can also use the formId in the UR after "/test/show-forms/$FORM_ID"`,
+ required: true,
+ choices: pf.map((form) => {
+ return {
+ label: `${form.id}: ${form.label}`,
+ value: form.id,
+ };
+ }),
+ },
+ ],
+ },
+ };
+
+ console.log("ASDASD", formId);
+ const { handler, status } = useForm<FormType>(theForm.config, {
+ form: formId,
+ });
+
+ const selected = !status.result?.form
+ ? undefined
+ : pf.find((f) => f.id === status.result.form);
+ return (
+ <div class="rounded-lg bg-white px-5 py-6 shadow m-4">
+ <LocalNotificationBanner notification={notification} />
+ <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
+ <FormUI handler={handler} design={theForm.config} />
+ </div>
+ {!selected ? undefined : <ShowForm form={selected} />}
+ </div>
+ );
+}
+
+function ShowForm({ form }: { form: FormMetadata }) {
+ const { handler, status } = useForm<FormType>(form.config, {});
+
+ return (
+ <Fragment>
+ <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
+ <FormUI handler={handler} design={form.config} />
+ </div>
+ </Fragment>
+ );
+}
diff --git a/packages/web-util/src/forms/fields/InputSelectOne.stories.tsx b/packages/web-util/src/forms/fields/InputSelectOne.stories.tsx
@@ -51,7 +51,8 @@ const design: FormDesign = {
type: "selectOne",
label: "label of the field" as TranslatedString,
id: "things" as UIHandlerId,
- placeholder: "search..." as TranslatedString,
+ placeholder: "search" as TranslatedString,
+ help: "search..." as TranslatedString,
choices: [
{
label: "one label" as TranslatedString,
diff --git a/packages/web-util/src/forms/fields/InputSelectOne.tsx b/packages/web-util/src/forms/fields/InputSelectOne.tsx
@@ -10,7 +10,7 @@ export function InputSelectOne<T extends object, K extends keyof T>(
choices: ChoiceS<T[K]>[];
} & UIFormProps<T, K>,
): VNode {
- const { label, choices, placeholder, tooltip, required } = props;
+ const { label, choices, placeholder, tooltip, required, help } = props;
const { value, onChange, error } =
props.handler ?? noHandlerPropsAndNoContextForField(props.name);
@@ -124,6 +124,11 @@ export function InputSelectOne<T extends object, K extends keyof T>(
)}
</div>
)}
+ {help && (
+ <p class="mt-2 text-sm text-gray-500" id="email-description">
+ {help}
+ </p>
+ )}
{dirty !== undefined && error && (
<p class="mt-2 text-sm text-red-600" id="email-error">
{error}