gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 03/04: remove handlers from impl


From: gnunet
Subject: [taler-wallet-core] 03/04: remove handlers from impl
Date: Sun, 31 Dec 2023 19:40:00 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit bedeebff1572fa8cfdb0a818030f6b13a3fc0f53
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Sun Dec 31 15:32:12 2023 -0300

    remove handlers from impl
---
 .../aml-backoffice-ui/src/handlers/Calendar.tsx    | 119 ---------
 .../aml-backoffice-ui/src/handlers/Caption.tsx     |  32 ---
 packages/aml-backoffice-ui/src/handlers/Dialog.tsx |  15 --
 .../src/handlers/FormProvider.tsx                  | 140 -----------
 packages/aml-backoffice-ui/src/handlers/Group.tsx  |  41 ----
 .../src/handlers/InputAbsoluteTime.stories.tsx     |  60 -----
 .../src/handlers/InputAbsoluteTime.tsx             |  77 ------
 .../src/handlers/InputAmount.stories.tsx           |  59 -----
 .../aml-backoffice-ui/src/handlers/InputAmount.tsx |  36 ---
 .../src/handlers/InputArray.stories.tsx            |  79 ------
 .../aml-backoffice-ui/src/handlers/InputArray.tsx  | 186 --------------
 .../src/handlers/InputChoiceHorizontal.stories.tsx |  69 ------
 .../src/handlers/InputChoiceHorizontal.tsx         |  87 -------
 .../src/handlers/InputChoiceStacked.stories.tsx    |  69 ------
 .../src/handlers/InputChoiceStacked.tsx            | 113 ---------
 .../src/handlers/InputFile.stories.tsx             |  64 -----
 .../aml-backoffice-ui/src/handlers/InputFile.tsx   | 106 --------
 .../src/handlers/InputInteger.stories.tsx          |  55 -----
 .../src/handlers/InputInteger.tsx                  |  24 --
 .../src/handlers/InputLine.stories.tsx             |  59 -----
 .../aml-backoffice-ui/src/handlers/InputLine.tsx   | 268 ---------------------
 .../src/handlers/InputSelectMultiple.stories.tsx   |  90 -------
 .../src/handlers/InputSelectMultiple.tsx           | 154 ------------
 .../src/handlers/InputSelectOne.stories.tsx        |  70 ------
 .../src/handlers/InputSelectOne.tsx                | 135 -----------
 .../src/handlers/InputText.stories.tsx             |  59 -----
 .../aml-backoffice-ui/src/handlers/InputText.tsx   |   9 -
 .../src/handlers/InputTextArea.stories.tsx         |  59 -----
 .../src/handlers/InputTextArea.tsx                 |   9 -
 .../src/handlers/InputToggle.stories.tsx           |  59 -----
 .../aml-backoffice-ui/src/handlers/InputToggle.tsx |  38 ---
 .../aml-backoffice-ui/src/handlers/NiceForm.tsx    |  60 -----
 .../aml-backoffice-ui/src/handlers/TimePicker.tsx  | 110 ---------
 packages/aml-backoffice-ui/src/handlers/forms.ts   | 141 -----------
 .../src/handlers/index.stories.ts                  |  13 -
 .../aml-backoffice-ui/src/handlers/useField.ts     |  95 --------
 36 files changed, 2859 deletions(-)

diff --git a/packages/aml-backoffice-ui/src/handlers/Calendar.tsx 
b/packages/aml-backoffice-ui/src/handlers/Calendar.tsx
deleted file mode 100644
index e476bf6f6..000000000
--- a/packages/aml-backoffice-ui/src/handlers/Calendar.tsx
+++ /dev/null
@@ -1,119 +0,0 @@
-import { AbsoluteTime } from "@gnu-taler/taler-util"
-import { useTranslationContext } from "@gnu-taler/web-util/browser"
-import { add as dateAdd, sub as dateSub, eachDayOfInterval, endOfMonth, 
endOfWeek, format, getMonth, getYear, isSameDay, isSameMonth, startOfDay, 
startOfMonth, startOfWeek } from "date-fns"
-import { VNode, h } from "preact"
-import { useState } from "preact/hooks"
-
-export function Calendar({ value, onChange }: { value: AbsoluteTime | 
undefined, onChange: (v: AbsoluteTime) => void }): VNode {
-  const today = startOfDay(new Date())
-  const selected = !value ? today : new Date(AbsoluteTime.toStampMs(value))
-  const [showingDate, setShowingDate] = useState(selected)
-  const month = getMonth(showingDate)
-  const year = getYear(showingDate)
-
-  const start = startOfWeek(startOfMonth(showingDate));
-  const end = endOfWeek(endOfMonth(showingDate));
-  const daysInMonth = eachDayOfInterval({ start, end });
-  const { i18n } = useTranslationContext()
-  const monthNames = [
-    i18n.str`January`,
-    i18n.str`February`,
-    i18n.str`March`,
-    i18n.str`April`,
-    i18n.str`May`,
-    i18n.str`June`,
-    i18n.str`July`,
-    i18n.str`August`,
-    i18n.str`September`,
-    i18n.str`October`,
-    i18n.str`November`,
-    i18n.str`December`,
-  ]
-  return <div class="text-center p-2">
-    <div class="flex items-center text-gray-900">
-      <button type="button" class="flex px-4 flex-none items-center 
justify-center p-1.5 text-gray-400 hover:text-gray-500 ring-2 round-sm"
-        onClick={() => {
-          setShowingDate(dateSub(showingDate, { years: 1 }))
-        }}>
-        <span class="sr-only">
-          {i18n.str`Previous year`}
-        </span>
-        <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" 
aria-hidden="true">
-          <path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 
10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 
0 011.06.02z" clip-rule="evenodd" />
-        </svg>
-      </button>
-      <div class="flex-auto text-sm font-semibold">{year}</div>
-      <button type="button" class="flex px-4 flex-none items-center 
justify-center p-1.5 text-gray-400 hover:text-gray-500 ring-2 round-sm"
-        onClick={() => {
-          setShowingDate(dateAdd(showingDate, { years: 1 }))
-        }}>
-        <span class="sr-only">
-          {i18n.str`Next year`}
-        </span>
-        <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" 
aria-hidden="true">
-          <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 
10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 
01-1.06-.02z" clip-rule="evenodd" />
-        </svg>
-      </button>
-    </div>
-    <div class="mt-4 flex items-center text-gray-900">
-      <button type="button" class="flex px-4 flex-none items-center 
justify-center p-1.5 text-gray-400 hover:text-gray-500 ring-2 round-sm"
-        onClick={() => {
-          setShowingDate(dateSub(showingDate, { months: 1 }))
-        }}>
-        <span class="sr-only">
-          {i18n.str`Previous month`}
-        </span>
-        <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" 
aria-hidden="true">
-          <path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 
10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 
0 011.06.02z" clip-rule="evenodd" />
-        </svg>
-      </button>
-      <div class="flex-auto text-sm font-semibold">{monthNames[month]}</div>
-      <button type="button" class="flex px-4 flex-none items-center 
justify-center p-1.5 text-gray-400 hover:text-gray-500 ring-2 rounded-sm "
-        onClick={() => {
-          setShowingDate(dateAdd(showingDate, { months: 1 }))
-        }}>
-        <span class="sr-only">
-          {i18n.str`Next month`}
-        </span>
-        <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" 
aria-hidden="true">
-          <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 
10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 
01-1.06-.02z" clip-rule="evenodd" />
-        </svg>
-      </button>
-    </div>
-    <div class="mt-6 grid grid-cols-7 text-xs leading-6 text-gray-500">
-      <div>M</div>
-      <div>T</div>
-      <div>W</div>
-      <div>T</div>
-      <div>F</div>
-      <div>S</div>
-      <div>S</div>
-    </div>
-    <div class="isolate mt-2">
-      <div class="grid grid-cols-7 gap-px rounded-lg bg-gray-200 text-sm 
shadow ring-1 ring-gray-200">
-        {daysInMonth.map(current => (
-          <button type="button"
-            data-month={isSameMonth(current, showingDate)}
-            data-today={isSameDay(current, today)}
-            data-selected={isSameDay(current, selected)}
-            onClick={() => {
-              onChange(AbsoluteTime.fromStampMs(current.getTime()))
-            }}
-            class="text-gray-400 hover:bg-gray-700 focus:z-10 py-1.5 
-          data-[month=false]:bg-gray-100 data-[month=true]:bg-white 
-            data-[today=true]:font-semibold  
-          data-[month=true]:text-gray-900
-          data-[today=true]:bg-red-300 data-[today=true]:hover:bg-red-200
-          data-[month=true]:hover:bg-gray-200
-          data-[selected=true]:!bg-blue-400 
data-[selected=true]:hover:!bg-blue-300 ">
-            <time dateTime={format(current, "yyyy-MM-dd")}
-              class="mx-auto flex h-7 w-7 py-4 px-5 sm:px-8 items-center 
justify-center rounded-full">
-              {format(current, "dd")}
-            </time>
-          </button>
-        ))}
-      </div>
-      {daysInMonth.length < 40 ? <div class="w-7 h-7 m-1.5" /> : undefined}
-    </div>
-  </div>
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/Caption.tsx 
b/packages/aml-backoffice-ui/src/handlers/Caption.tsx
deleted file mode 100644
index 8facddec3..000000000
--- a/packages/aml-backoffice-ui/src/handlers/Caption.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { VNode, h } from "preact";
-import {
-  LabelWithTooltipMaybeRequired
-} from "./InputLine.js";
-
-interface Props {
-  label: TranslatedString;
-  tooltip?: TranslatedString;
-  help?: TranslatedString;
-  before?: VNode;
-  after?: VNode;
-}
-
-export function Caption({ before, after, label, tooltip, help }: Props): VNode 
{
-  return (
-    <div class="sm:col-span-6 flex">
-      {before !== undefined && (
-        <span class="pointer-events-none flex items-center 
pr-2">{before}</span>
-      )}
-      <LabelWithTooltipMaybeRequired label={label} tooltip={tooltip} />
-      {after !== undefined && (
-        <span class="pointer-events-none flex items-center pl-2">{after}</span>
-      )}
-      {help && (
-        <p class="mt-2 text-sm text-gray-500" id="email-description">
-          {help}
-        </p>
-      )}
-    </div>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/Dialog.tsx 
b/packages/aml-backoffice-ui/src/handlers/Dialog.tsx
deleted file mode 100644
index 7b41fe487..000000000
--- a/packages/aml-backoffice-ui/src/handlers/Dialog.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { ComponentChildren, VNode, h } from "preact";
-
-export function Dialog({ children, onClose }: { onClose?: () => void; 
children: ComponentChildren }): VNode {
-  return <div class="relative z-10" aria-labelledby="modal-title" 
role="dialog" aria-modal="true" onClick={onClose}>
-    <div class="fixed inset-0 bg-gray-500 bg-opacity-75 
transition-opacity"></div>
-
-    <div class="fixed inset-0 z-10 w-screen overflow-y-auto">
-      <div class="flex min-h-full items-center justify-center p-4 text-center 
">
-        <div class="relative transform overflow-hidden rounded-lg bg-white p-1 
text-left shadow-xl transition-all" onClick={(e) => e.stopPropagation()}>
-          {children}
-        </div>
-      </div>
-    </div>
-  </div>
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/FormProvider.tsx 
b/packages/aml-backoffice-ui/src/handlers/FormProvider.tsx
deleted file mode 100644
index b9f9f7832..000000000
--- a/packages/aml-backoffice-ui/src/handlers/FormProvider.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import {
-  AbsoluteTime,
-  AmountJson,
-  TranslatedString,
-} from "@gnu-taler/taler-util";
-import { ComponentChildren, VNode, createContext, h } from "preact";
-import {
-  MutableRef,
-  StateUpdater,
-  useState
-} from "preact/hooks";
-
-export interface FormType<T extends object> {
-  value: MutableRef<Partial<T>>;
-  initialValue?: Partial<T>;
-  readOnly?: boolean;
-  onUpdate?: StateUpdater<T>;
-  computeFormState?: (v: T) => FormState<T>;
-}
-
-//@ts-ignore
-export const FormContext = createContext<FormType<any>>({});
-
-/**
- * Map of {[field]:BehaviorResult}
- * for every field of type
- *  - any native (string, number, etc...)
- *  - absoluteTime
- *  - amountJson
- * 
- * except for: 
- *  - object => recurse into
- *  - array => behavior result and element field
- */
-export type FormState<T extends object | undefined> = {
-  [field in keyof T]?: T[field] extends AbsoluteTime
-  ? BehaviorResult
-  : T[field] extends AmountJson
-  ? BehaviorResult
-  : T[field] extends Array<infer P extends object>
-  ? InputArrayFieldState<P>
-  : T[field] extends (object | undefined)
-  ? FormState<T[field]>
-  : BehaviorResult;
-};
-
-export type BehaviorResult = Partial<InputFieldState> & FieldUIOptions
-
-export interface InputFieldState {
-  /* should show the error */
-  error?: TranslatedString;
-  /* should not allow to edit */
-  readonly: boolean;
-  /* should show as disable */
-  disabled: boolean;
-  /* should not show */
-  hidden: boolean;
-}
-
-export interface IconAddon {
-  type: "icon";
-  icon: VNode;
-}
-export interface ButtonAddon {
-  type: "button";
-  onClick: () => void;
-  children: ComponentChildren;
-}
-export interface TextAddon {
-  type: "text";
-  text: TranslatedString;
-}
-export type Addon = IconAddon | ButtonAddon | TextAddon;
-
-export interface StringConverter<T> {
-  toStringUI: (v?: T) => string;
-  fromStringUI: (v?: string) => T;
-}
-
-type FieldUIOptions = {
-  placeholder?: TranslatedString;
-  tooltip?: TranslatedString;
-  help?: TranslatedString;
-  required?: boolean;
-}
-
-export interface UIFormProps<T extends object, K extends keyof T> extends 
FieldUIOptions {
-  name: K;
-  label: TranslatedString;
-  before?: Addon;
-  after?: Addon;
-  converter?: StringConverter<T[K]>;
-}
-
-export interface InputArrayFieldState<P extends object> extends BehaviorResult 
{
-  elements?: FormState<P>[];
-}
-
-export function FormProvider<T extends object>({
-  children,
-  initialValue,
-  onUpdate: notify,
-  onSubmit,
-  computeFormState,
-  readOnly,
-}: {
-  initialValue?: Partial<T>;
-  onUpdate?: (v: Partial<T>) => void;
-  onSubmit?: (v: Partial<T>, s: FormState<T> | undefined) => void;
-  computeFormState?: (v: Partial<T>) => FormState<T>;
-  readOnly?: boolean;
-  children: ComponentChildren;
-}): VNode {
-
-  const [state, setState] = useState<Partial<T>>(initialValue ?? {});
-  const value = { current: state };
-  const onUpdate = (v: typeof state) => {
-    setState(v);
-    if (notify) notify(v);
-  };
-  return (
-    <FormContext.Provider
-      value={{ initialValue, value, onUpdate, computeFormState, readOnly }}
-    >
-      <form
-        onSubmit={(e) => {
-          e.preventDefault();
-          //@ts-ignore
-          if (onSubmit)
-            onSubmit(
-              value.current,
-              !computeFormState ? undefined : computeFormState(value.current),
-            );
-        }}
-      >
-        {children}
-      </form>
-    </FormContext.Provider>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/Group.tsx 
b/packages/aml-backoffice-ui/src/handlers/Group.tsx
deleted file mode 100644
index 0645f6d97..000000000
--- a/packages/aml-backoffice-ui/src/handlers/Group.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { VNode, h } from "preact";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { RenderAllFieldsByUiConfig, UIFormField } from "./forms.js";
-
-interface Props {
-  before?: TranslatedString;
-  after?: TranslatedString;
-  tooltipBefore?: TranslatedString;
-  tooltipAfter?: TranslatedString;
-  fields: UIFormField[];
-}
-
-export function Group({
-  before,
-  after,
-  tooltipAfter,
-  tooltipBefore,
-  fields,
-}: Props): VNode {
-  return (
-    <div class="sm:col-span-6 p-4 rounded-lg border-r-2 border-2 bg-gray-50">
-      <div class="pb-4">
-        {before && (
-          <LabelWithTooltipMaybeRequired
-            label={before}
-            tooltip={tooltipBefore}
-          />
-        )}
-      </div>
-      <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-2 sm:grid-cols-6">
-        <RenderAllFieldsByUiConfig fields={fields} />
-      </div>
-      <div class="pt-4">
-        {after && (
-          <LabelWithTooltipMaybeRequired label={after} tooltip={tooltipAfter} 
/>
-        )}
-      </div>
-    </div>
-  );
-}
diff --git 
a/packages/aml-backoffice-ui/src/handlers/InputAbsoluteTime.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputAbsoluteTime.stories.tsx
deleted file mode 100644
index 54e41ffae..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputAbsoluteTime.stories.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Absolute Time",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  today: AbsoluteTime;
-}
-const initial: TargetObject = {
-  today: AbsoluteTime.now()
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "absoluteTime",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "today",
-        pattern: "dd/MM/yyyy HH:mm"
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputAbsoluteTime.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputAbsoluteTime.tsx
deleted file mode 100644
index 0e03c5595..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputAbsoluteTime.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import { AbsoluteTime } from "@gnu-taler/taler-util";
-import { InputLine } from "./InputLine.js";
-import { Fragment, VNode, h } from "preact";
-import { format, parse } from "date-fns";
-import { Dialog } from "./Dialog.js";
-import { Calendar } from "./Calendar.js";
-import { useState } from "preact/hooks";
-import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
-import { TimePicker } from "./TimePicker.js";
-
-export function InputAbsoluteTime<T extends object, K extends keyof T>(
-  props: { pattern?: string } & UIFormProps<T, K>,
-): VNode {
-  const pattern = props.pattern ?? "dd/MM/yyyy";
-  const [open, setOpen] = useState(true)
-  const { value, onChange } = useField<T, K>(props.name);
-  return (
-    <Fragment>
-
-      <InputLine<T, K>
-        type="text"
-        after={{
-          type: "button",
-          onClick: () => {
-            setOpen(true)
-          },
-          // icon: <CalendarIcon class="h-6 w-6" />,
-          children: (
-            <svg xmlns="http://www.w3.org/2000/svg"; fill="none" viewBox="0 0 
24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
-              <path stroke-linecap="round" stroke-linejoin="round" d="M6.75 
3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 
7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 
0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />
-            </svg>)
-        }}
-        converter={{
-          //@ts-ignore
-          fromStringUI: (v): AbsoluteTime | undefined => {
-            if (!v) return undefined;
-            try {
-              const t_ms = parse(v, pattern, Date.now()).getTime();
-              return AbsoluteTime.fromMilliseconds(t_ms);
-            } catch (e) {
-              return undefined;
-            }
-          },
-          //@ts-ignore
-          toStringUI: (v: AbsoluteTime | undefined) => {
-            return !v || !v.t_ms
-              ? undefined
-              : v.t_ms === "never"
-                ? "never"
-                : format(v.t_ms, pattern);
-          },
-        }}
-        {...props}
-      />
-      {/* {open &&
-        <Dialog onClose={() => setOpen(false)}>
-          <Calendar value={value as AbsoluteTime ?? AbsoluteTime.now()}
-            onChange={(v) => {
-              onChange(v as any)
-              setOpen(false)
-            }} />
-        </Dialog>
-      } */}
-      {open &&
-        <Dialog onClose={() => setOpen(false)} >
-          <TimePicker value={value as AbsoluteTime ?? AbsoluteTime.now()}
-            onChange={(v) => {
-              onChange(v as any)
-            }}
-            onConfirm={() => {
-              setOpen(false)
-            }} />
-        </Dialog>}
-    </Fragment>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputAmount.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputAmount.stories.tsx
deleted file mode 100644
index 872726247..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputAmount.stories.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { AmountJson, Amounts, TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Amount",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  amount: AmountJson;
-}
-const initial: TargetObject = {
-  amount: Amounts.parseOrThrow("USD:10")
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "amount",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "amount",
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputAmount.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputAmount.tsx
deleted file mode 100644
index 29ec43525..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputAmount.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { AmountJson, Amounts, TranslatedString } from "@gnu-taler/taler-util";
-import { VNode, h } from "preact";
-import { InputLine } from "./InputLine.js";
-import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
-
-export function InputAmount<T extends object, K extends keyof T>(
-  props: { currency?: string } & UIFormProps<T, K>,
-): VNode {
-  const { value } = useField<T, K>(props.name);
-  const currency =
-    !value || !(value as any).currency
-      ? props.currency
-      : (value as any).currency;
-  return (
-    <InputLine<T, K>
-      type="text"
-      before={{
-        type: "text",
-        text: currency as TranslatedString,
-      }}
-      converter={{
-        //@ts-ignore
-        fromStringUI: (v): AmountJson => {
-
-          return Amounts.parse(`${currency}:${v}`) ?? 
Amounts.zeroOfCurrency(currency);
-        },
-        //@ts-ignore
-        toStringUI: (v: AmountJson) => {
-          return v === undefined ? "" : Amounts.stringifyValue(v);
-        },
-      }}
-      {...props}
-    />
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputArray.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputArray.stories.tsx
deleted file mode 100644
index ee25d355b..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputArray.stories.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Array",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  people: {
-    name: string;
-    age: number;
-  }[];
-}
-const initial: TargetObject = {
-  people: [{
-    name: "me",
-    age: 17,
-  }]
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "array",
-      props: {
-        label: "People" as TranslatedString,
-        name: "comment",
-        fields: [{
-          type: "text",
-          props: {
-            label: "the name" as TranslatedString,
-            name: "name",
-          }
-        }, {
-          type: "integer",
-          props: {
-            label: "the age" as TranslatedString,
-            name: "age",
-          }
-        }],
-        labelField: "name"
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputArray.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputArray.tsx
deleted file mode 100644
index 38c399e66..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputArray.tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { Fragment, VNode, h } from "preact";
-import { useState } from "preact/hooks";
-import { FormProvider, UIFormProps } from "./FormProvider.js";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { RenderAllFieldsByUiConfig, UIFormField } from "./forms.js";
-import { useField } from "./useField.js";
-
-function Option({
-  label,
-  disabled,
-  isFirst,
-  isLast,
-  isSelected,
-  onClick,
-}: {
-  label: TranslatedString;
-  isFirst?: boolean;
-  isLast?: boolean;
-  isSelected?: boolean;
-  disabled?: boolean;
-  onClick: () => void;
-}): VNode {
-  let clazz = "relative flex border p-4 focus:outline-none disabled:text-grey";
-  if (isFirst) {
-    clazz += " rounded-tl-md rounded-tr-md ";
-  }
-  if (isLast) {
-    clazz += " rounded-bl-md rounded-br-md ";
-  }
-  if (isSelected) {
-    clazz += " z-10 border-indigo-200 bg-indigo-50 ";
-  } else {
-    clazz += " border-gray-200";
-  }
-  if (disabled) {
-    clazz +=
-      " cursor-not-allowed bg-gray-50 text-gray-500 ring-gray-200  text-gray";
-  } else {
-    clazz += " cursor-pointer";
-  }
-  return (
-    <label class={clazz}>
-      <input
-        type="radio"
-        name="privacy-setting"
-        checked={isSelected}
-        disabled={disabled}
-        onClick={onClick}
-        class="mt-0.5 h-4 w-4 shrink-0 text-indigo-600 
disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 
disabled:ring-gray-200  focus:ring-indigo-600"
-        aria-labelledby="privacy-setting-0-label"
-        aria-describedby="privacy-setting-0-description"
-      />
-      <span class="ml-3 flex flex-col">
-        <span
-          id="privacy-setting-0-label"
-          disabled
-          class="block text-sm font-medium"
-        >
-          {label}
-        </span>
-        {/* <!-- Checked: "text-indigo-700", Not Checked: "text-gray-500" --> 
*/}
-        {/* <span
-        id="privacy-setting-0-description"
-        class="block text-sm"
-      >
-        This project would be available to anyone who has the link
-      </span> */}
-      </span>
-    </label>
-  );
-}
-
-export function InputArray<T extends object, K extends keyof T>(
-  props: {
-    fields: UIFormField[];
-    labelField: string;
-  } & UIFormProps<T, K>,
-): VNode {
-  const { fields, labelField, name, label, required, tooltip } = props;
-  const { value, onChange, state } = useField<T, K>(name);
-  const list = (value ?? []) as Array<Record<string, string | undefined>>;
-  const [selectedIndex, setSelected] = useState<number | undefined>(undefined);
-  const selected =
-    selectedIndex === undefined ? undefined : list[selectedIndex];
-
-  return (
-    <div class="sm:col-span-6">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-
-      <div class="-space-y-px rounded-md bg-white ">
-        {list.map((v, idx) => {
-          return (
-            <Option
-              label={v[labelField] as TranslatedString}
-              isSelected={selectedIndex === idx}
-              isLast={idx === list.length - 1}
-              disabled={selectedIndex !== undefined && selectedIndex !== idx}
-              isFirst={idx === 0}
-              onClick={() => {
-                setSelected(selectedIndex === idx ? undefined : idx);
-              }}
-            />
-          );
-        })}
-        {!state.disabled &&
-          <div class="pt-2">
-            <Option
-              label={"Add..." as TranslatedString}
-              isSelected={selectedIndex === list.length}
-              isLast
-              isFirst
-              disabled={
-                selectedIndex !== undefined && selectedIndex !== list.length
-              }
-              onClick={() => {
-                setSelected(
-                  selectedIndex === list.length ? undefined : list.length,
-                );
-              }}
-            />
-          </div>
-        }
-      </div>
-      {selectedIndex !== undefined && (
-        /**
-         * This form provider act as a substate of the parent form
-         * Consider creating an InnerFormProvider since not every feature is 
expected
-         */
-        <FormProvider
-          initialValue={selected}
-          readOnly={state.disabled}
-          computeFormState={(v) => {
-            // current state is ignored
-            // the state is defined by the parent form
-
-            // elements should be present in the state object since this is 
expected to be an array
-            //@ts-ignore
-            return state.elements[selectedIndex];
-          }}
-          onSubmit={(v) => {
-            const newValue = [...list];
-            newValue.splice(selectedIndex, 1, v);
-            onChange(newValue as T[K]);
-            setSelected(undefined);
-          }}
-          onUpdate={(v) => {
-            const newValue = [...list];
-            newValue.splice(selectedIndex, 1, v);
-            onChange(newValue as T[K]);
-          }}
-        >
-          <div class="px-4 py-6">
-            <div class="grid grid-cols-1 gap-y-8 ">
-              <RenderAllFieldsByUiConfig fields={fields} />
-            </div>
-          </div>
-        </FormProvider>
-      )}
-      {selectedIndex !== undefined && (
-        <div class="flex items-center pt-3">
-          <div class="flex-auto">
-            {selected !== undefined && (
-              <button
-                type="button"
-                onClick={() => {
-                  const newValue = [...list];
-                  newValue.splice(selectedIndex, 1);
-                  onChange(newValue as T[K]);
-                  setSelected(undefined);
-                }}
-                class="block rounded-md bg-red-600 px-3 py-2 text-center 
text-sm  text-white shadow-sm hover:bg-red-500 "
-              >
-                Remove
-              </button>
-            )}
-          </div>
-        </div>
-      )}
-    </div>
-  );
-}
diff --git 
a/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.stories.tsx
deleted file mode 100644
index 7872afac7..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.stories.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Choice Horizontal",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "0"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "choiceHorizontal",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-        choices: [{
-          label: "first choice" as TranslatedString,
-          value: "1"
-        }, {
-          label: "second choice" as TranslatedString,
-          value: "2"
-        }, {
-          label: "thrid choice" as TranslatedString,
-          value: "3"
-        },],
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx
deleted file mode 100644
index 594b1c32e..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { Fragment, VNode, h } from "preact";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
-
-export interface Choice<V> {
-  label: TranslatedString;
-  value: V;
-}
-
-export function InputChoiceHorizontal<T extends object, K extends keyof T>(
-  props: {
-    choices: Choice<T[K]>[];
-  } & UIFormProps<T, K>,
-): VNode {
-  const {
-    choices,
-    name,
-    label,
-    tooltip,
-    help,
-    placeholder,
-    required,
-    before,
-    after,
-    converter,
-  } = props;
-  const { value, onChange, state, isDirty } = useField<T, K>(name);
-  if (state.hidden) {
-    return <Fragment />;
-  }
-
-  return (
-    <div class="sm:col-span-6">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-      <fieldset class="mt-2">
-        <div class="isolate inline-flex rounded-md shadow-sm">
-          {choices.map((choice, idx) => {
-            const isFirst = idx === 0;
-            const isLast = idx === choices.length - 1;
-            let clazz =
-              "relative inline-flex items-center px-3 py-2 text-sm 
font-semibold text-gray-900 ring-1 ring-inset ring-gray-300  focus:z-10";
-            if (choice.value === value) {
-              clazz +=
-                " text-white bg-indigo-600 hover:bg-indigo-500 ring-2 
ring-indigo-600 hover:ring-indigo-500";
-            } else {
-              clazz += " hover:bg-gray-100 border-gray-300";
-            }
-            if (isFirst) {
-              clazz += " rounded-l-md";
-            } else {
-              clazz += " -ml-px";
-            }
-            if (isLast) {
-              clazz += " rounded-r-md";
-            }
-            return (
-              <button
-                type="button"
-                disabled={state.disabled}
-                label={choice.label}
-                class={clazz}
-                onClick={(e) => {
-                  onChange(
-                    (value === choice.value ? undefined : choice.value) as 
T[K],
-                  );
-                }}
-              >
-                {choice.label}
-              </button>
-            );
-          })}
-        </div>
-      </fieldset>
-      {help && (
-        <p class="mt-2 text-sm text-gray-500" id="email-description">
-          {help}
-        </p>
-      )}
-    </div>
-  );
-}
diff --git 
a/packages/aml-backoffice-ui/src/handlers/InputChoiceStacked.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputChoiceStacked.stories.tsx
deleted file mode 100644
index 215418430..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputChoiceStacked.stories.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Choice Stacked",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "some initial comment"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "choiceStacked",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-        choices: [{
-          label: "first choice" as TranslatedString,
-          value: "1"
-        }, {
-          label: "second choice" as TranslatedString,
-          value: "2"
-        }, {
-          label: "thrid choice" as TranslatedString,
-          value: "3"
-        },],
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputChoiceStacked.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputChoiceStacked.tsx
deleted file mode 100644
index 48d367ff2..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputChoiceStacked.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { Fragment, VNode, h } from "preact";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
-
-export interface Choice<V> {
-  label: TranslatedString;
-  description?: TranslatedString;
-  value: V;
-}
-
-export function InputChoiceStacked<T extends object, K extends keyof T>(
-  props: {
-    choices: Choice<T[K]>[];
-  } & UIFormProps<T, K>,
-): VNode {
-  const {
-    choices,
-    name,
-    label,
-    tooltip,
-    help,
-    placeholder,
-    required,
-    before,
-    after,
-    converter,
-  } = props;
-  const { value, onChange, state, isDirty } = useField<T, K>(name);
-  if (state.hidden) {
-    return <Fragment />;
-  }
-
-  return (
-    <div class="sm:col-span-6">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-      <fieldset class="mt-2">
-        <div class="space-y-4">
-          {choices.map((choice) => {
-            // const currentValue = !converter
-            //   ? choice.value
-            //   : converter.fromStringUI(choice.value) ?? "";
-
-            let clazz =
-              "border relative block cursor-pointer rounded-lg bg-white px-6 
py-4 shadow-sm focus:outline-none sm:flex sm:justify-between";
-            if (choice.value === value) {
-              clazz +=
-                " border-transparent border-indigo-600 ring-2 ring-indigo-600";
-            } else {
-              clazz += " border-gray-300";
-            }
-
-            return (
-              <label class={clazz}>
-                <input
-                  type="radio"
-                  name="server-size"
-                  // defaultValue={choice.value}
-                  disabled={state.disabled}
-                  value={
-                    (!converter
-                      ? (choice.value as string)
-                      : converter?.toStringUI(choice.value)) ?? ""
-                  }
-                  onClick={(e) => {
-                    onChange(
-                      (value === choice.value
-                        ? undefined
-                        : choice.value) as T[K],
-                    );
-                  }}
-                  class="sr-only"
-                  aria-labelledby="server-size-0-label"
-                  aria-describedby="server-size-0-description-0 
server-size-0-description-1"
-                />
-                <span class="flex items-center">
-                  <span class="flex flex-col text-sm">
-                    <span
-                      id="server-size-0-label"
-                      class="font-medium text-gray-900"
-                    >
-                      {choice.label}
-                    </span>
-                    {choice.description !== undefined && (
-                      <span
-                        id="server-size-0-description-0"
-                        class="text-gray-500"
-                      >
-                        <span class="block sm:inline">
-                          {choice.description}
-                        </span>
-                      </span>
-                    )}
-                  </span>
-                </span>
-              </label>
-            );
-          })}
-        </div>
-      </fieldset>
-      {help && (
-        <p class="mt-2 text-sm text-gray-500" id="email-description">
-          {help}
-        </p>
-      )}
-    </div>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputFile.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputFile.stories.tsx
deleted file mode 100644
index 8a1783bda..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputFile.stories.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input File",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "some initial comment"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "file",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-        required: true,
-        maxBites: 2 * 1024 * 1024,
-        accept: ".png",
-        tooltip: "this is a very long tooltip that explain what the field does 
without being short" as TranslatedString,
-        help: "Max size of 2 mega bytes" as TranslatedString,
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputFile.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputFile.tsx
deleted file mode 100644
index bc460f370..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputFile.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-import { Fragment, VNode, h } from "preact";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { useField } from "./useField.js";
-import { UIFormProps, BehaviorResult } from "./FormProvider.js";
-
-export function InputFile<T extends object, K extends keyof T>(
-  props: { maxBites: number; accept?: string } & UIFormProps<T, K>,
-): VNode {
-  const {
-    name,
-    label,
-    placeholder,
-    tooltip,
-    required,
-    help: propsHelp,
-    maxBites,
-    accept,
-  } = props;
-  const { value, onChange, state } = useField<T, K>(name);
-  const help = propsHelp ?? state.help
-  if (state.hidden) {
-    return <div />;
-  }
-  return (
-    <div class="col-span-full">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        tooltip={tooltip}
-        required={required}
-      />
-      {!value || !(value as string).startsWith("data:image/") ? (
-        <div class="mt-2 flex justify-center rounded-lg border border-dashed 
border-gray-900/25 py-1">
-          <div class="text-center">
-            <svg
-              class="mx-auto h-12 w-12 text-gray-300"
-              viewBox="0 0 24 24"
-              fill="currentColor"
-              aria-hidden="true"
-            >
-              <path
-                fill-rule="evenodd"
-                d="M1.5 6a2.25 2.25 0 012.25-2.25h16.5A2.25 2.25 0 0122.5 
6v12a2.25 2.25 0 01-2.25 2.25H3.75A2.25 2.25 0 011.5 18V6zM3 16.06V18c0 
.414.336.75.75.75h16.5A.75.75 0 0021 18v-1.94l-2.69-2.689a1.5 1.5 0 00-2.12 
0l-.88.879.97.97a.75.75 0 11-1.06 1.06l-5.16-5.159a1.5 1.5 0 00-2.12 0L3 
16.061zm10.125-7.81a1.125 1.125 0 112.25 0 1.125 1.125 0 01-2.25 0z"
-                clip-rule="evenodd"
-              />
-            </svg>
-            {!state.disabled &&
-              <div class="my-2 flex text-sm leading-6 text-gray-600">
-                <label
-                  for="file-upload"
-                  class="relative cursor-pointer rounded-md bg-white 
font-semibold text-indigo-600 focus-within:outline-none focus-within:ring-2 
focus-within:ring-indigo-600 focus-within:ring-offset-2 hover:text-indigo-500"
-                >
-                  <span>Upload a file</span>
-                  <input
-                    id="file-upload"
-                    name="file-upload"
-                    type="file"
-                    class="sr-only"
-                    accept={accept}
-                    onChange={(e) => {
-                      const f: FileList | null = e.currentTarget.files;
-                      if (!f || f.length != 1) {
-                        return onChange(undefined!);
-                      }
-                      if (f[0].size > maxBites) {
-                        return onChange(undefined!);
-                      }
-                      return f[0].arrayBuffer().then((b) => {
-                        const b64 = window.btoa(
-                          new Uint8Array(b).reduce(
-                            (data, byte) => data + String.fromCharCode(byte),
-                            "",
-                          ),
-                        );
-                        return onChange(`data:${f[0].type};base64,${b64}` as 
any);
-                      });
-                    }}
-                  />
-                </label>
-                {/* <p class="pl-1">or drag and drop</p> */}
-              </div>
-            }
-          </div>
-        </div>
-      ) : (
-        <div class="mt-2 flex justify-center rounded-lg border border-dashed 
border-gray-900/25 relative">
-          <img
-            src={value as string}
-            class=" h-24 w-full object-cover relative"
-          />
-
-          {!state.disabled &&
-            <div
-              class="opacity-0 hover:opacity-70 duration-300 absolute 
rounded-lg border inset-0 z-10 flex justify-center text-xl items-center 
bg-black text-white cursor-pointer "
-              onClick={() => {
-                onChange(undefined!);
-              }}
-            >
-              Clear
-            </div>
-          }
-        </div>
-      )}
-      {help && <p class="text-xs leading-5 text-gray-600 mt-2">{help}</p>}
-    </div>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputInteger.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputInteger.stories.tsx
deleted file mode 100644
index 344865817..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputInteger.stories.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Integer",
-};
-
-
-type TargetObject = {
-  age: number;
-}
-const initial: TargetObject = {
-  age: 5,
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "integer",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "age",
-        tooltip: "just numbers" as TranslatedString,
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputInteger.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputInteger.tsx
deleted file mode 100644
index a6a02ad43..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputInteger.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { VNode, h } from "preact";
-import { InputLine } from "./InputLine.js";
-import { UIFormProps } from "./FormProvider.js";
-
-export function InputInteger<T extends object, K extends keyof T>(
-  props: UIFormProps<T, K>,
-): VNode {
-  return (
-    <InputLine
-      type="number"
-      converter={{
-        //@ts-ignore
-        fromStringUI: (v): number => {
-          return !v ? 0 : Number.parseInt(v, 10);
-        },
-        //@ts-ignore
-        toStringUI: (v?: number): string => {
-          return v === undefined ? "" : String(v);
-        },
-      }}
-      {...props}
-    />
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputLine.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputLine.stories.tsx
deleted file mode 100644
index 0d55bddf7..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputLine.stories.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Line",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "some initial comment"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "text",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputLine.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputLine.tsx
deleted file mode 100644
index 8c44b1ca5..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputLine.tsx
+++ /dev/null
@@ -1,268 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { ComponentChildren, Fragment, VNode, h } from "preact";
-import { useField } from "./useField.js";
-import { useEffect, useState } from "preact/hooks";
-import { UIFormProps } from "./FormProvider.js";
-
-//@ts-ignore
-const TooltipIcon = (
-  <svg
-    class="w-5 h-5"
-    xmlns="http://www.w3.org/2000/svg";
-    viewBox="0 0 20 20"
-    fill="currentColor"
-  >
-    <path
-      fill-rule="evenodd"
-      d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 
11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 
1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z"
-      clip-rule="evenodd"
-    />
-  </svg>
-);
-
-export function LabelWithTooltipMaybeRequired({
-  label,
-  required,
-  tooltip,
-}: {
-  label: TranslatedString;
-  required?: boolean;
-  tooltip?: TranslatedString;
-}): VNode {
-  const Label = (
-    <Fragment>
-      <div class="flex justify-between">
-        <label
-          htmlFor="email"
-          class="block text-sm font-medium leading-6 text-gray-900"
-        >
-          {label}
-        </label>
-      </div>
-    </Fragment>
-  );
-  const WithTooltip = tooltip ? (
-    <div class="relative flex flex-grow items-stretch focus-within:z-10">
-      {Label}
-      <span class="relative flex items-center group pl-2">
-        {TooltipIcon}
-        <div class="absolute bottom-0 -ml-10 hidden flex-col items-center mb-6 
group-hover:flex w-28">
-          <div class="relative z-10 p-2 text-xs leading-none text-white 
whitespace-no-wrap bg-black shadow-lg">
-            {tooltip}
-          </div>
-          <div class="w-3 h-3 -mt-2  rotate-45 bg-black"></div>
-        </div>
-      </span>
-    </div>
-  ) : (
-    Label
-  );
-  if (required) {
-    return (
-      <div class="flex justify-between">
-        {WithTooltip}
-        <span class="text-sm leading-6 text-red-600">*</span>
-      </div>
-    );
-  }
-  return WithTooltip;
-}
-
-function InputWrapper<T extends object, K extends keyof T>({
-  children,
-  label,
-  tooltip,
-  before,
-  after,
-  help,
-  error,
-  disabled,
-  required,
-}: { error?: string; disabled: boolean, children: ComponentChildren } & 
UIFormProps<T, K>): VNode {
-  return (
-    <div class="sm:col-span-6">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-      <div class="relative mt-2 flex rounded-md shadow-sm">
-        {before &&
-          (before.type === "text" ? (
-            <span class="inline-flex items-center rounded-l-md border 
border-r-0 border-gray-300 px-3 text-gray-500 sm:text-sm">
-              {before.text}
-            </span>
-          ) : before.type === "icon" ? (
-            <div class="pointer-events-none absolute inset-y-0 left-0 flex 
items-center pl-3">
-              {before.icon}
-            </div>
-          ) : before.type === "button" ? (
-            <button
-              type="button"
-              disabled={disabled}
-              onClick={before.onClick}
-              class="relative -ml-px inline-flex items-center gap-x-1.5 
rounded-l-md px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset 
ring-gray-300 hover:bg-gray-50"
-            >
-              {before.children}
-            </button>
-          ) : undefined)}
-
-        {children}
-
-        {after &&
-          (after.type === "text" ? (
-            <span class="inline-flex items-center rounded-r-md border 
border-l-0 border-gray-300 px-3 text-gray-500 sm:text-sm">
-              {after.text}
-            </span>
-          ) : after.type === "icon" ? (
-            <div class="pointer-events-none absolute inset-y-0 right-0 flex 
items-center pr-3">
-              {after.icon}
-            </div>
-          ) : after.type === "button" ? (
-            <button
-              type="button"
-              disabled={disabled}
-              onClick={after.onClick}
-              class="relative -ml-px inline-flex items-center gap-x-1.5 
rounded-r-md px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset 
ring-gray-300 hover:bg-gray-50"
-            >
-              {after.children}
-            </button>
-          ) : undefined)}
-      </div>
-      {error && (
-        <p class="mt-2 text-sm text-red-600" id="email-error">
-          {error}
-        </p>
-      )}
-      {help && (
-        <p class="mt-2 text-sm text-gray-500" id="email-description">
-          {help}
-        </p>
-      )}
-    </div>
-  );
-}
-
-function defaultToString(v: unknown) {
-  return v === undefined ? "" : typeof v !== "object" ? String(v) : "";
-}
-function defaultFromString(v: string) {
-  return v;
-}
-
-type InputType = "text" | "text-area" | "password" | "email" | "number";
-
-export function InputLine<T extends object, K extends keyof T>(
-  props: { type: InputType } & UIFormProps<T, K>,
-): VNode {
-  const { name, placeholder, before, after, converter, type } = props;
-  const { value, onChange, state, isDirty } = useField<T, K>(name);
-
-  const [text, setText] = useState("")
-  const fromString: (s: string) => any =
-    converter?.fromStringUI ?? defaultFromString;
-  const toString: (s: any) => string = converter?.toStringUI ?? 
defaultToString;
-
-  useEffect(() => {
-    const newValue = toString(value)
-    if (newValue) {
-      setText(newValue)
-    }
-  }, [value])
-
-  if (state.hidden) return <div />;
-
-  let clazz =
-    "block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset 
focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 
disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 
disabled:ring-gray-200";
-  if (before) {
-    switch (before.type) {
-      case "icon": {
-        clazz += " pl-10";
-        break;
-      }
-      case "button": {
-        clazz += " rounded-none rounded-r-md ";
-        break;
-      }
-      case "text": {
-        clazz += " min-w-0 flex-1 rounded-r-md rounded-none ";
-        break;
-      }
-    }
-  }
-  if (after) {
-    switch (after.type) {
-      case "icon": {
-        clazz += " pr-10";
-        break;
-      }
-      case "button": {
-        clazz += " rounded-none rounded-l-md";
-        break;
-      }
-      case "text": {
-        clazz += " min-w-0 flex-1 rounded-l-md rounded-none ";
-        break;
-      }
-    }
-  }
-  const showError = isDirty && state.error;
-  if (showError) {
-    clazz +=
-      " text-red-900 ring-red-300  placeholder:text-red-300 
focus:ring-red-500";
-  } else {
-    clazz +=
-      " text-gray-900 ring-gray-300 placeholder:text-gray-400 
focus:ring-indigo-600";
-  }
-
-  if (type === "text-area") {
-    return (
-      <InputWrapper<T, K>
-        {...props}
-        help={props.help ?? state.help}
-        disabled={state.disabled ?? false}
-        error={showError ? state.error : undefined}
-      >
-        <textarea
-          rows={4}
-          name={String(name)}
-          onChange={(e) => {
-            onChange(fromString(e.currentTarget.value));
-          }}
-          placeholder={placeholder ? placeholder : undefined}
-          value={toString(value) ?? ""}
-          // defaultValue={toString(value)}
-          disabled={state.disabled}
-          aria-invalid={showError}
-          // aria-describedby="email-error"
-          class={clazz}
-        />
-      </InputWrapper>
-    );
-  }
-
-  return (
-    <InputWrapper<T, K> {...props}
-      help={props.help ?? state.help}
-      disabled={state.disabled ?? false} error={showError ? state.error : 
undefined}
-    >
-      <input
-        name={String(name)}
-        type={type}
-        onChange={(e) => {
-          setText(e.currentTarget.value)
-        }}
-        placeholder={placeholder ? placeholder : undefined}
-        value={text}
-        onBlur={() => {
-          onChange(fromString(text));
-        }}
-        // defaultValue={toString(value)}
-        disabled={state.disabled}
-        aria-invalid={showError}
-        // aria-describedby="email-error"
-        class={clazz}
-      />
-    </InputWrapper>
-  );
-}
diff --git 
a/packages/aml-backoffice-ui/src/handlers/InputSelectMultiple.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputSelectMultiple.stories.tsx
deleted file mode 100644
index 4dac61f21..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputSelectMultiple.stories.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Select Multiple",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  pets: string[];
-  things: string[];
-}
-const initial: TargetObject = {
-  pets: [],
-  things: [],
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "selectMultiple",
-      props: {
-        label: "allow diplicates" as TranslatedString,
-        name: "pets",
-        placeholder: "search..." as TranslatedString,
-        choices: [{
-          label: "one label" as TranslatedString,
-          value: "one"
-        }, {
-          label: "two label" as TranslatedString,
-          value: "two"
-        }, {
-          label: "five label" as TranslatedString,
-          value: "five"
-        }]
-      },
-    }, {
-      type: "selectMultiple",
-      props: {
-        label: "unique values" as TranslatedString,
-        name: "things",
-        unique: true,
-        placeholder: "search..." as TranslatedString,
-        choices: [{
-          label: "one label" as TranslatedString,
-          value: "one"
-        }, {
-          label: "two label" as TranslatedString,
-          value: "two"
-        }, {
-          label: "five label" as TranslatedString,
-          value: "five"
-        }]
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputSelectMultiple.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputSelectMultiple.tsx
deleted file mode 100644
index 06eb91bb3..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputSelectMultiple.tsx
+++ /dev/null
@@ -1,154 +0,0 @@
-import { Fragment, VNode, h } from "preact";
-import { Choice } from "./InputChoiceStacked.js";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { useField } from "./useField.js";
-import { useState } from "preact/hooks";
-import { UIFormProps } from "./FormProvider.js";
-
-export function InputSelectMultiple<T extends object, K extends keyof T>(
-  props: {
-    choices: Choice<T[K]>[];
-    unique?: boolean;
-    max?: number;
-  } & UIFormProps<T, K>,
-): VNode {
-  const { name, label, choices, placeholder, tooltip, required, unique, max } =
-    props;
-  const { value, onChange, state } = useField<T, K>(name);
-
-  const [filter, setFilter] = useState<string | undefined>(undefined);
-  const regex = new RegExp(`.*${filter}.*`, "i");
-  const choiceMap = choices.reduce((prev, curr) => {
-    return { ...prev, [curr.value as string]: curr.label };
-  }, {} as Record<string, string>);
-
-  const list = (value ?? []) as string[];
-  const filteredChoices =
-    filter === undefined
-      ? undefined
-      : choices.filter((v) => {
-        return regex.test(v.label);
-      });
-  return (
-    <div class="sm:col-span-6">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-      {list.map((v, idx) => {
-        return (
-          <span class="inline-flex items-center gap-x-0.5 rounded-md 
bg-gray-100 p-1 mr-2 text-xs font-medium text-gray-600">
-            {choiceMap[v]}
-            <button
-              type="button"
-              disabled={state.disabled}
-              onClick={() => {
-                const newValue = [...list];
-                newValue.splice(idx, 1);
-                onChange(newValue as T[K]);
-                setFilter(undefined);
-              }}
-              class="group relative h-5 w-5 rounded-sm hover:bg-gray-500/20"
-            >
-              <span class="sr-only">Remove</span>
-              <svg
-                viewBox="0 0 14 14"
-                class="h-5 w-5 stroke-gray-700/50 
group-hover:stroke-gray-700/75"
-              >
-                <path d="M4 4l6 6m0-6l-6 6" />
-              </svg>
-              <span class="absolute -inset-1"></span>
-            </button>
-          </span>
-        );
-      })}
-
-      {!state.disabled && <div class="relative mt-2">
-        <input
-          id="combobox"
-          type="text"
-          value={filter ?? ""}
-          onChange={(e) => {
-            setFilter(e.currentTarget.value);
-          }}
-          placeholder={placeholder}
-          class="w-full rounded-md border-0 bg-white py-1.5 pl-3 pr-12 
text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 
focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
-          role="combobox"
-          aria-controls="options"
-          aria-expanded="false"
-        />
-        <button
-          type="button"
-          disabled={state.disabled}
-          onClick={() => {
-            setFilter(filter === undefined ? "" : undefined);
-          }}
-          class="absolute inset-y-0 right-0 flex items-center rounded-r-md 
px-2 focus:outline-none"
-        >
-          <svg
-            class="h-5 w-5 text-gray-400"
-            viewBox="0 0 20 20"
-            fill="currentColor"
-            aria-hidden="true"
-          >
-            <path
-              fill-rule="evenodd"
-              d="M10 3a.75.75 0 01.55.24l3.25 3.5a.75.75 0 11-1.1 1.02L10 
4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 0 0110 3zm-3.76 9.2a.75.75 
0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 1.02l-3.25 3.5a.75.75 0 01-1.1 
0l-3.25-3.5a.75.75 0 01.04-1.06z"
-              clip-rule="evenodd"
-            />
-          </svg>
-        </button>
-
-        {filteredChoices !== undefined && (
-          <ul
-            class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md 
bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 
focus:outline-none sm:text-sm"
-            id="options"
-            role="listbox"
-          >
-            {filteredChoices.map((v, idx) => {
-              return (
-                <li
-                  class="relative cursor-pointer select-none py-2 pl-3 pr-9 
text-gray-900 hover:text-white hover:bg-indigo-600"
-                  id="option-0"
-                  role="option"
-                  onClick={() => {
-                    setFilter(undefined);
-                    if (unique && list.indexOf(v.value as string) !== -1) {
-                      return;
-                    }
-                    if (max !== undefined && list.length >= max) {
-                      return;
-                    }
-                    const newValue = [...list];
-                    newValue.splice(0, 0, v.value as string);
-                    onChange(newValue as T[K]);
-                  }}
-
-                // tabindex="-1"
-                >
-                  {/* <!-- Selected: "font-semibold" --> */}
-                  <span class="block truncate">{v.label}</span>
-
-                  {/* <!--
-          Checkmark, only display for selected option.
-
-          Active: "text-white", Not Active: "text-indigo-600"
-        --> */}
-                </li>
-              );
-            })}
-
-            {/* <!--
-        Combobox option, manage highlight styles based on 
mouseenter/mouseleave and keyboard navigation.
-
-        Active: "text-white bg-indigo-600", Not Active: "text-gray-900"
-      --> */}
-
-            {/* <!-- More items... --> */}
-          </ul>
-        )}
-      </div>}
-    </div>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputSelectOne.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputSelectOne.stories.tsx
deleted file mode 100644
index 0bb871500..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputSelectOne.stories.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Select One",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  things: string;
-}
-const initial: TargetObject = {
-  things: "one"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "selectOne",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "things",
-        placeholder: "search..." as TranslatedString,
-        choices: [{
-          label: "one label" as TranslatedString,
-          value: "one"
-        }, {
-          label: "two label" as TranslatedString,
-          value: "two"
-        }, {
-          label: "five label" as TranslatedString,
-          value: "five"
-        }]
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputSelectOne.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputSelectOne.tsx
deleted file mode 100644
index 98430306e..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputSelectOne.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import { Fragment, VNode, h } from "preact";
-import { Choice } from "./InputChoiceStacked.js";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { useField } from "./useField.js";
-import { useState } from "preact/hooks";
-import { UIFormProps } from "./FormProvider.js";
-
-export function InputSelectOne<T extends object, K extends keyof T>(
-  props: {
-    choices: Choice<T[K]>[];
-  } & UIFormProps<T, K>,
-): VNode {
-  const { name, label, choices, placeholder, tooltip, required } = props;
-  const { value, onChange } = useField<T, K>(name);
-
-  const [filter, setFilter] = useState<string | undefined>(undefined);
-  const regex = new RegExp(`.*${filter}.*`, "i");
-  const choiceMap = choices.reduce((prev, curr) => {
-    return { ...prev, [curr.value as string]: curr.label };
-  }, {} as Record<string, string>);
-
-  const filteredChoices =
-    filter === undefined
-      ? undefined
-      : choices.filter((v) => {
-        return regex.test(v.label);
-      });
-  return (
-    <div class="sm:col-span-6">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-      {value ? (
-        <span class="inline-flex items-center gap-x-0.5 rounded-md bg-gray-100 
p-1 mr-2 font-medium text-gray-600">
-          {choiceMap[value as string]}
-          <button
-            type="button"
-            onClick={() => {
-              onChange(undefined!);
-            }}
-            class="group relative h-5 w-5 rounded-sm hover:bg-gray-500/20"
-          >
-            <span class="sr-only">Remove</span>
-            <svg
-              viewBox="0 0 14 14"
-              class="h-5 w-5 stroke-gray-700/50 group-hover:stroke-gray-700/75"
-            >
-              <path d="M4 4l6 6m0-6l-6 6" />
-            </svg>
-            <span class="absolute -inset-1"></span>
-          </button>
-        </span>
-      ) : (
-        <div class="relative mt-2">
-          <input
-            id="combobox"
-            type="text"
-            value={filter ?? ""}
-            onChange={(e) => {
-              setFilter(e.currentTarget.value);
-            }}
-            placeholder={placeholder}
-            class="w-full rounded-md border-0 bg-white py-1.5 pl-3 pr-12 
text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 
focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
-            role="combobox"
-            aria-controls="options"
-            aria-expanded="false"
-          />
-          <button
-            type="button"
-            onClick={() => {
-              setFilter(filter === undefined ? "" : undefined);
-            }}
-            class="absolute inset-y-0 right-0 flex items-center rounded-r-md 
px-2 focus:outline-none"
-          >
-            <svg
-              class="h-5 w-5 text-gray-400"
-              viewBox="0 0 20 20"
-              fill="currentColor"
-              aria-hidden="true"
-            >
-              <path
-                fill-rule="evenodd"
-                d="M10 3a.75.75 0 01.55.24l3.25 3.5a.75.75 0 11-1.1 1.02L10 
4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 0 0110 3zm-3.76 9.2a.75.75 
0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 1.02l-3.25 3.5a.75.75 0 01-1.1 
0l-3.25-3.5a.75.75 0 01.04-1.06z"
-                clip-rule="evenodd"
-              />
-            </svg>
-          </button>
-
-          {filteredChoices !== undefined && (
-            <ul
-              class="absolute z-10 mt-1 max-h-60 w-full overflow-auto 
rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 
focus:outline-none sm:text-sm"
-              id="options"
-              role="listbox"
-            >
-              {filteredChoices.map((v, idx) => {
-                return (
-                  <li
-                    class="relative cursor-pointer select-none py-2 pl-3 pr-9 
text-gray-900 hover:text-white hover:bg-indigo-600"
-                    id="option-0"
-                    role="option"
-                    onClick={() => {
-                      setFilter(undefined);
-                      onChange(v.value as T[K]);
-                    }}
-
-                  // tabindex="-1"
-                  >
-                    {/* <!-- Selected: "font-semibold" --> */}
-                    <span class="block truncate">{v.label}</span>
-
-                    {/* <!--
-          Checkmark, only display for selected option.
-
-          Active: "text-white", Not Active: "text-indigo-600"
-        --> */}
-                  </li>
-                );
-              })}
-
-              {/* <!--
-        Combobox option, manage highlight styles based on 
mouseenter/mouseleave and keyboard navigation.
-
-        Active: "text-white bg-indigo-600", Not Active: "text-gray-900"
-      --> */}
-
-              {/* <!-- More items... --> */}
-            </ul>
-          )}
-        </div>
-      )}
-    </div>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputText.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputText.stories.tsx
deleted file mode 100644
index 9ce733d4a..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputText.stories.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Text",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "some initial comment"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "text",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputText.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputText.tsx
deleted file mode 100644
index 7ad36b737..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputText.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { VNode, h } from "preact";
-import { InputLine } from "./InputLine.js";
-import { UIFormProps } from "./FormProvider.js";
-
-export function InputText<T extends object, K extends keyof T>(
-  props: UIFormProps<T, K>,
-): VNode {
-  return <InputLine type="text" {...props} />;
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputTextArea.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputTextArea.stories.tsx
deleted file mode 100644
index df35b25c4..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputTextArea.stories.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Text Area",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "some initial comment"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "text",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputTextArea.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputTextArea.tsx
deleted file mode 100644
index 6b76d8329..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputTextArea.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { VNode, h } from "preact";
-import { InputLine } from "./InputLine.js";
-import { UIFormProps } from "./FormProvider.js";
-
-export function InputTextArea<T extends object, K extends keyof T>(
-  props: UIFormProps<T, K>,
-): VNode {
-  return <InputLine type="text-area" {...props} />;
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/InputToggle.stories.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputToggle.stories.tsx
deleted file mode 100644
index 735e812f3..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputToggle.stories.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { TranslatedString } from "@gnu-taler/taler-util";
-import * as tests from "@gnu-taler/web-util/testing";
-import {
-  NiceForm as TestedComponent,
-} from "./NiceForm.js";
-import { FlexibleForm } from "./forms.js";
-
-export default {
-  title: "Input Toggle",
-};
-
-export namespace Simplest {
-  export interface Form {
-    comment: string;
-  }
-}
-
-type TargetObject = {
-  comment: string;
-}
-const initial: TargetObject = {
-  comment: "some initial comment"
-}
-
-const form: FlexibleForm<TargetObject> = {
-  design: [{
-    title: "this is a simple form" as TranslatedString,
-    fields: [{
-      type: "toggle",
-      props: {
-        label: "label of the field" as TranslatedString,
-        name: "comment",
-      },
-    }]
-  }]
-}
-
-export const SimpleComment = tests.createExample(TestedComponent, { initial, 
form });
diff --git a/packages/aml-backoffice-ui/src/handlers/InputToggle.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputToggle.tsx
deleted file mode 100644
index 1ea8699b2..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputToggle.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { VNode, h } from "preact";
-import { InputLine, LabelWithTooltipMaybeRequired } from "./InputLine.js";
-import { UIFormProps } from "./FormProvider.js";
-import { useField } from "./useField.js";
-
-export function InputToggle<T extends object, K extends keyof T>(
-  props: UIFormProps<T, K>,
-): VNode {
-  const {
-    name,
-    label,
-    tooltip,
-    help,
-    placeholder,
-    required,
-    before,
-    after,
-    converter,
-  } = props;
-  const { value, onChange, state, isDirty } = useField<T, K>(name);
-
-  const isOn = !!value
-  return <div class="sm:col-span-6">
-    <div class="flex items-center justify-between">
-      <LabelWithTooltipMaybeRequired
-        label={label}
-        required={required}
-        tooltip={tooltip}
-      />
-      <button type="button" data-enabled={isOn}
-        class="bg-indigo-600 data-[enabled=false]:bg-gray-200 relative 
inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 
border-transparent transition-colors duration-200 ease-in-out 
focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2"
-        role="switch" aria-checked="false" 
aria-labelledby="availability-label" aria-describedby="availability-description"
-        onClick={() => { onChange(!isOn as any); }}>
-        <span aria-hidden="true" data-enabled={isOn} class="translate-x-5 
data-[enabled=false]:translate-x-0 pointer-events-none inline-block h-5 w-5 
transform rounded-full bg-white shadow ring-0 transition duration-200 
ease-in-out"></span>
-      </button>
-    </div>
-  </div>
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/NiceForm.tsx 
b/packages/aml-backoffice-ui/src/handlers/NiceForm.tsx
deleted file mode 100644
index d01b80b02..000000000
--- a/packages/aml-backoffice-ui/src/handlers/NiceForm.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { ComponentChildren, Fragment, h } from "preact";
-import { FormProvider } from "./FormProvider.js";
-import { FlexibleForm, RenderAllFieldsByUiConfig } from "./forms.js";
-
-export function NiceForm<T extends object>({
-  initial,
-  onUpdate,
-  form,
-  onSubmit,
-  children,
-  readOnly,
-}: {
-  children?: ComponentChildren;
-  initial: Partial<T>;
-  onSubmit?: (v: Partial<T>) => void;
-  form: FlexibleForm<T>;
-  readOnly?: boolean;
-  onUpdate?: (d: Partial<T>) => void;
-}) {
-  return (
-    <FormProvider
-      initialValue={initial}
-      onUpdate={onUpdate}
-      onSubmit={onSubmit}
-      readOnly={readOnly}
-      computeFormState={form.behavior}
-    >
-      <div class="space-y-10 divide-y -mt-5 divide-gray-900/10">
-        {form.design.map((section, i) => {
-          if (!section) return <Fragment />;
-          return (
-            <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-5 md:grid-cols-3">
-              <div class="px-4 sm:px-0">
-                <h2 class="text-base font-semibold leading-7 text-gray-900">
-                  {section.title}
-                </h2>
-                {section.description && (
-                  <p class="mt-1 text-sm leading-6 text-gray-600">
-                    {section.description}
-                  </p>
-                )}
-              </div>
-              <div class="bg-white shadow-sm ring-1 ring-gray-900/5 rounded-md 
md:col-span-2">
-                <div class="p-3">
-                  <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 
sm:grid-cols-6">
-                    <RenderAllFieldsByUiConfig
-                      key={i}
-                      fields={section.fields}
-                    />
-                  </div>
-                </div>
-              </div>
-            </div>
-          );
-        })}
-      </div>
-      {children}
-    </FormProvider>
-  );
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/TimePicker.tsx 
b/packages/aml-backoffice-ui/src/handlers/TimePicker.tsx
deleted file mode 100644
index c6dc3e794..000000000
--- a/packages/aml-backoffice-ui/src/handlers/TimePicker.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import { AbsoluteTime } from "@gnu-taler/taler-util"
-import { useTranslationContext } from "@gnu-taler/web-util/browser"
-import { startOfDay, getHours, getMinutes, getSeconds, setHours } from 
"date-fns"
-import { Fragment, VNode, h } from "preact"
-import { useState } from "preact/hooks"
-
-export function TimePicker({ value, onChange, onConfirm }: { value: 
AbsoluteTime | undefined, onChange: (v: AbsoluteTime) => void, onConfirm: () => 
void }): VNode {
-  const date = !value ? new Date() : new Date(AbsoluteTime.toStampMs(value))
-  const hours = getHours(date) % 12
-  const minutes = getMinutes(date)
-  const seconds = getSeconds(date)
-
-  const { i18n } = useTranslationContext()
-
-  return <Fragment>
-    <div class="flex flex-col bg-white rounded-t-sm  justify-around" >
-      {/* time selection */}
-      <div id="" class="bg-[#3b71ca] dark:bg-zinc-700 h-24 rounded-t-lg p-12  
flex flex-row items-center justify-center">
-        <div class="flex w-full justify-evenly">
-          <div class="">
-            <span class="relative h-full">
-              <button type="button" class="py-1 px-3 text-[3.75rem] font-light 
leading-[1.2]  text-white opacity-[.54] border-none bg-transparent p-0  
cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] 
focus:outline-none "
-                style="pointer-events: none;">
-                {new String(hours).padStart(2, "0")}
-              </button>
-            </span>
-            <span type="button" class="font-light leading-[1.2]  
text-[3.75rem] opacity-[.54] border-none bg-transparent p-0 text-white " 
>:</span>
-            <span class="relative h-full">
-              <button type="button" class="py-1 px-3 text-[3.75rem] font-light 
leading-[1.2]  text-white opacity-[.54] border-none bg-transparent p-0  
cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] 
focus:outline-none " >
-                {new String(minutes).padStart(2, "0")}
-              </button>
-            </span>
-            <span type="button" class="font-light leading-[1.2]  
text-[3.75rem] opacity-[.54] border-none bg-transparent p-0 text-white " 
>:</span>
-            <span class="relative h-full">
-              <button type="button" class="py-1 px-3 text-[3.75rem] font-light 
leading-[1.2]  text-white opacity-[.54] border-none bg-transparent p-0  
cursor-pointer hover:bg-[#00000026] hover:outline-none focus:bg-[#00000026] 
focus:outline-none " >
-                {new String(seconds).padStart(2, "0")}
-              </button>
-            </span>
-          </div>
-          <div class="flex flex-col justify-center text-[18px] 
text-[#ffffff8a] ">
-            <button type="button" class="py-1 px-3 bg-transparent border-none 
text-white cursor-pointer hover:bg-[#00000026] hover:outline-none 
focus:bg-[#00000026] focus:outline-none" >
-              AM
-            </button>
-            <button type="button" class="py-1 px-3 bg-transparent border-none 
text-white cursor-pointer hover:bg-[#00000026] hover:outline-none 
focus:bg-[#00000026] focus:outline-none" >
-              PM
-            </button>
-          </div>
-        </div>
-      </div>
-      {/* clock */}
-      <div id="" class="mt-2 min-w-[310px] max-w-[325px] min-h-[305px] 
overflow-x-hidden h-full flex justify-center mx-auto   flex-col items-center 
dark:bg-zinc-500" >
-        <div class="relative rounded-[100%] w-[260px] h-[260px] cursor-default 
my-0 mx-auto bg-[#00000012] dark:bg-zinc-600/50 
animate-[show-up-clock_350ms_linear]" >
-
-          <span class="top-1/2 left-1/2 w-[6px] h-[6px] -translate-y-1/2 
-translate-x-1/2 rounded-[50%] bg-[#3b71ca] absolute" ></span>
-          <div class="bg-[#3b71ca] bottom-1/2 h-2/5 left-[calc(50%-1px)] 
rtl:!left-auto origin-[center_bottom_0] rtl:!origin-[50%_50%_0] w-[2px] 
absolute" style={{ transform: "rotateZ(60deg)", height: "calc(35% + 1px)" }}>
-            {/* <div class="-top-[21px] -left-[15px] w-[4px] border-[14px] 
border-solid border-[#3b71ca] h-[4px] box-content rounded-[100%] absolute" 
style="background-color: rgb(25, 118, 210);"></div> */}
-          </div>
-
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 12).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 114px; bottom: 224px;">
-            <span>0</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 1).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 169px; bottom: 209.263px;">
-            <span >1</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 2).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
data-selected={true} style="left: 209.263px; bottom: 169px;" >
-            <span >2</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 3).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 224px; bottom: 114px;">
-            <span >3</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 4).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 209.263px; bottom: 59px;">
-            <span >4</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 5).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 169px; bottom: 18.7372px;">
-            <span >5</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 6).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 114px; bottom: 4px;">
-            <span >6</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 7).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 59px; bottom: 18.7372px;">
-            <span >7</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 8).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 18.7372px; bottom: 59px;">
-            <span >8</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 9).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 4px; bottom: 114px;">
-            <span >9</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 10).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 18.7372px; bottom: 169px;">
-            <span >10</span>
-          </span>
-          <span onClick={() => 
onChange(AbsoluteTime.fromStampMs(setHours(date, 11).getTime()))} 
class="absolute rounded-[100%] w-[32px] h-[32px] text-center cursor-pointer 
text-[1.1rem] bg-transparent flex justify-center items-center font-light 
focus:outline-none selection:bg-transparent data-[selected=true]:text-white 
data-[selected=true]:bg-[#3b71ca] data-[selected=true]:font-normal" 
style="left: 59px; bottom: 209.263px;">
-            <span >11</span>
-          </span>
-        </div>
-      </div>
-    </div>
-    <div id="" class="rounded-b-lg flex justify-between items-center w-full 
h-[56px] px-[12px] bg-white dark:bg-zinc-500">
-      <div class="w-full flex justify-end">
-        <button
-          type="submit"
-          onClick={onConfirm}
-          class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold 
text-white shadow-sm hover:bg-indigo-500 focus-visible:outline 
focus-visible:outline-2 focus-visible:outline-offset-2 
focus-visible:outline-indigo-600"
-        >
-          <i18n.Translate>Confirm</i18n.Translate>
-        </button>
-      </div>
-    </div>
-  </Fragment>
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/forms.ts 
b/packages/aml-backoffice-ui/src/handlers/forms.ts
deleted file mode 100644
index 1c212fafa..000000000
--- a/packages/aml-backoffice-ui/src/handlers/forms.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { InputText } from "./InputText.js";
-import { InputAbsoluteTime } from "./InputAbsoluteTime.js";
-import { InputInteger } from "./InputInteger.js";
-import { h as create, Fragment, VNode } from "preact";
-import { InputChoiceStacked } from "./InputChoiceStacked.js";
-import { InputArray } from "./InputArray.js";
-import { InputSelectMultiple } from "./InputSelectMultiple.js";
-import { InputTextArea } from "./InputTextArea.js";
-import { InputFile } from "./InputFile.js";
-import { Caption } from "./Caption.js";
-import { Group } from "./Group.js";
-import { InputSelectOne } from "./InputSelectOne.js";
-import { FormProvider, FormState } from "./FormProvider.js";
-import { InputLine } from "./InputLine.js";
-import { InputAmount } from "./InputAmount.js";
-import { InputChoiceHorizontal } from "./InputChoiceHorizontal.js";
-import { InputToggle } from "./InputToggle.js";
-
-export type DoubleColumnForm = Array<DoubleColumnFormSection | undefined>;
-
-export type DoubleColumnFormSection = {
-  title: TranslatedString;
-  description?: TranslatedString;
-  fields: UIFormField[];
-};
-export interface FlexibleForm<T extends object> {
-  design: DoubleColumnForm;
-  behavior?: (form: Partial<T>) => FormState<T>;
-}
-
-/**
- * Constrain the type with the ui props
- */
-type FieldType<T extends object = any, K extends keyof T = any> = {
-  group: Parameters<typeof Group>[0];
-  caption: Parameters<typeof Caption>[0];
-  array: Parameters<typeof InputArray<T, K>>[0];
-  file: Parameters<typeof InputFile<T, K>>[0];
-  selectOne: Parameters<typeof InputSelectOne<T, K>>[0];
-  selectMultiple: Parameters<typeof InputSelectMultiple<T, K>>[0];
-  text: Parameters<typeof InputText<T, K>>[0];
-  textArea: Parameters<typeof InputTextArea<T, K>>[0];
-  choiceStacked: Parameters<typeof InputChoiceStacked<T, K>>[0];
-  choiceHorizontal: Parameters<typeof InputChoiceHorizontal<T, K>>[0];
-  absoluteTime: Parameters<typeof InputAbsoluteTime<T, K>>[0];
-  integer: Parameters<typeof InputInteger<T, K>>[0];
-  toggle: Parameters<typeof InputToggle<T, K>>[0];
-  amount: Parameters<typeof InputAmount<T, K>>[0];
-};
-
-/**
- * List all the form fields so typescript can type-check the form instance
- */
-export type UIFormField =
-  | { type: "group"; props: FieldType["group"] }
-  | { type: "caption"; props: FieldType["caption"] }
-  | { type: "array"; props: FieldType["array"] }
-  | { type: "file"; props: FieldType["file"] }
-  | { type: "amount"; props: FieldType["amount"] }
-  | { type: "selectOne"; props: FieldType["selectOne"] }
-  | { type: "selectMultiple"; props: FieldType["selectMultiple"] }
-  | { type: "text"; props: FieldType["text"] }
-  | { type: "textArea"; props: FieldType["textArea"] }
-  | { type: "choiceStacked"; props: FieldType["choiceStacked"] }
-  | { type: "choiceHorizontal"; props: FieldType["choiceHorizontal"] }
-  | { type: "integer"; props: FieldType["integer"] }
-  | { type: "toggle"; props: FieldType["toggle"] }
-  | { type: "absoluteTime"; props: FieldType["absoluteTime"] };
-
-type FieldComponentFunction<key extends keyof FieldType> = (
-  props: FieldType[key],
-) => VNode;
-
-type UIFormFieldMap = {
-  [key in keyof FieldType]: FieldComponentFunction<key>;
-};
-
-/**
- * Maps input type with component implementation
- */
-const UIFormConfiguration: UIFormFieldMap = {
-  group: Group,
-  caption: Caption,
-  //@ts-ignore
-  array: InputArray,
-  text: InputText,
-  //@ts-ignore
-  file: InputFile,
-  textArea: InputTextArea,
-  //@ts-ignore
-  absoluteTime: InputAbsoluteTime,
-  //@ts-ignore
-  choiceStacked: InputChoiceStacked,
-  //@ts-ignore
-  choiceHorizontal: InputChoiceHorizontal,
-  integer: InputInteger,
-  //@ts-ignore
-  selectOne: InputSelectOne,
-  //@ts-ignore
-  selectMultiple: InputSelectMultiple,
-  //@ts-ignore
-  toggle: InputToggle,
-  //@ts-ignore
-  amount: InputAmount,
-};
-
-export function RenderAllFieldsByUiConfig({
-  fields,
-}: {
-  fields: UIFormField[];
-}): VNode {
-  return create(
-    Fragment,
-    {},
-    fields.map((field, i) => {
-      const Component = UIFormConfiguration[
-        field.type
-      ] as FieldComponentFunction<any>;
-      return Component(field.props);
-    }),
-  );
-}
-
-type FormSet<T extends object> = {
-  Provider: typeof FormProvider<T>;
-  InputLine: <K extends keyof T>() => typeof InputLine<T, K>;
-  InputChoiceHorizontal: <K extends keyof T>() => typeof 
InputChoiceHorizontal<T, K>;
-};
-export function createNewForm<T extends object>() {
-  const res: FormSet<T> = {
-    Provider: FormProvider,
-    InputLine: () => InputLine,
-    InputChoiceHorizontal: () => InputChoiceHorizontal,
-  };
-  return {
-    Provider: res.Provider,
-    InputLine: res.InputLine(),
-    InputChoiceHorizontal: res.InputChoiceHorizontal(),
-  };
-}
diff --git a/packages/aml-backoffice-ui/src/handlers/index.stories.ts 
b/packages/aml-backoffice-ui/src/handlers/index.stories.ts
deleted file mode 100644
index 55878cb02..000000000
--- a/packages/aml-backoffice-ui/src/handlers/index.stories.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export * as a1 from "./InputAmount.stories.js";
-export * as a2 from "./InputArray.stories.js";
-export * as a3 from "./InputChoiceHorizontal.stories.js";
-export * as a4 from "./InputChoiceStacked.stories.js";
-export * as a5 from "./InputAbsoluteTime.stories.js";
-export * as a6 from "./InputFile.stories.js";
-export * as a7 from "./InputInteger.stories.js";
-export * as a8 from "./InputLine.stories.js";
-export * as a9 from "./InputSelectMultiple.stories.js";
-export * as a10 from "./InputSelectOne.stories.js";
-export * as a11 from "./InputText.stories.js";
-export * as a12 from "./InputTextArea.stories.js";
-export * as a13 from "./InputToggle.stories.js";
diff --git a/packages/aml-backoffice-ui/src/handlers/useField.ts 
b/packages/aml-backoffice-ui/src/handlers/useField.ts
deleted file mode 100644
index 651778628..000000000
--- a/packages/aml-backoffice-ui/src/handlers/useField.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import { useContext, useState } from "preact/compat";
-import { BehaviorResult, FormContext, InputFieldState } from 
"./FormProvider.js";
-
-export interface InputFieldHandler<Type> {
-  value: Type;
-  onChange: (s: Type) => void;
-  state: BehaviorResult;
-  isDirty: boolean;
-}
-
-export function useField<T extends object, K extends keyof T>(
-  name: K,
-): InputFieldHandler<T[K]> {
-  const {
-    initialValue,
-    value: formValue,
-    computeFormState,
-    onUpdate: notifyUpdate,
-    readOnly: readOnlyForm,
-  } = useContext(FormContext);
-
-  type P = typeof name;
-  type V = T[P];
-  const formState = computeFormState ? computeFormState(formValue.current) : 
{};
-
-  const fieldValue = readField(formValue.current, String(name)) as V;
-  // console.log("USE FIELD", String(name), formValue.current, fieldValue);
-  const [currentValue, setCurrentValue] = useState<any | 
undefined>(fieldValue);
-  const fieldState =
-    readField<Partial<BehaviorResult>>(formState, String(name)) ?? {};
-
-  //compute default state
-  const state = {
-    disabled: readOnlyForm ? true : (fieldState.disabled ?? false),
-    readonly: readOnlyForm ? true : (fieldState.readonly ?? false),
-    hidden: fieldState.hidden ?? false,
-    error: fieldState.error,
-    help: fieldState.help,
-    elements: "elements" in fieldState ? fieldState.elements ?? [] : [],
-  };
-
-  function onChange(value: V): void {
-    setCurrentValue(value);
-    formValue.current = setValueDeeper(
-      formValue.current,
-      String(name).split("."),
-      value,
-    );
-    if (notifyUpdate) {
-      notifyUpdate(formValue.current);
-    }
-  }
-
-  return {
-    value: fieldValue,
-    onChange,
-    isDirty: currentValue !== undefined,
-    state,
-  };
-}
-
-/**
- * read the field of an object an support accessing it using '.'
- *
- * @param object
- * @param name
- * @returns
- */
-function readField<T>(
-  object: any,
-  name: string,
-  debug?: boolean,
-): T | undefined {
-  return name.split(".").reduce((prev, current) => {
-    if (debug) {
-      console.log(
-        "READ",
-        name,
-        prev,
-        current,
-        prev ? prev[current] : undefined,
-      );
-    }
-    return prev ? prev[current] : undefined;
-  }, object);
-}
-
-function setValueDeeper(object: any, names: string[], value: any): any {
-  if (names.length === 0) return value;
-  const [head, ...rest] = names;
-  if (object === undefined) {
-    return { [head]: setValueDeeper({}, rest, value) };
-  }
-  return { ...object, [head]: setValueDeeper(object[head] ?? {}, rest, value) 
};
-}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]