gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: some fixes and examples


From: gnunet
Subject: [taler-wallet-core] branch master updated: some fixes and examples
Date: Thu, 16 Nov 2023 22:11:05 +0100

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 860e4216c some fixes and examples
860e4216c is described below

commit 860e4216cdaf3e3bfb50ec1d9d285d34b6af5470
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Nov 16 15:38:27 2023 -0300

    some fixes and examples
---
 packages/aml-backoffice-ui/src/Dashboard.tsx       |  43 ++--
 packages/aml-backoffice-ui/src/forms/902_11e.ts    |   1 -
 packages/aml-backoffice-ui/src/forms/902_1e.ts     |   1 -
 packages/aml-backoffice-ui/src/forms/902_4e.ts     |   3 +-
 packages/aml-backoffice-ui/src/forms/simplest.ts   |   3 +-
 .../aml-backoffice-ui/src/handlers/InputDate.tsx   |  11 +-
 packages/aml-backoffice-ui/src/pages.ts            |  17 +-
 .../src/pages/AntiMoneyLaunderingForm.stories.tsx  |  94 +++++++++
 .../src/pages/AntiMoneyLaunderingForm.tsx          |  72 +++++--
 .../aml-backoffice-ui/src/pages/CaseDetails.tsx    | 226 ++-------------------
 packages/aml-backoffice-ui/src/pages/Cases.tsx     |  26 ++-
 .../src/pages/HandleAccountNotReady.tsx            |  10 +-
 .../aml-backoffice-ui/src/pages/NewFormEntry.tsx   |  51 +----
 .../src/pages/ShowConsolidated.stories.tsx         |  60 ++++++
 .../src/pages/ShowConsolidated.tsx                 | 204 +++++++++++++++++++
 .../aml-backoffice-ui/src/pages/UnlockAccount.tsx  |   7 +-
 .../aml-backoffice-ui/src/pages/index.stories.ts   |   2 +
 packages/aml-backoffice-ui/src/route.ts            |  14 +-
 packages/aml-backoffice-ui/src/stories.test.ts     |   4 +-
 packages/aml-backoffice-ui/src/stories.tsx         |   7 +-
 20 files changed, 533 insertions(+), 323 deletions(-)

diff --git a/packages/aml-backoffice-ui/src/Dashboard.tsx 
b/packages/aml-backoffice-ui/src/Dashboard.tsx
index 5d86836d4..d111ae145 100644
--- a/packages/aml-backoffice-ui/src/Dashboard.tsx
+++ b/packages/aml-backoffice-ui/src/Dashboard.tsx
@@ -1,17 +1,12 @@
-import { Footer, GlobalNotificationsBanner, Header, LangSelector, notifyError, 
notifyException, useNotifications, useTranslationContext } from 
"@gnu-taler/web-util/browser";
-import { Dialog, Transition } from "@headlessui/react";
-import { UserIcon, XCircleIcon } from "@heroicons/react/20/solid";
-import { CheckCircleIcon, XMarkIcon } from "@heroicons/react/24/outline";
-import { InformationCircleIcon } from "@heroicons/react/24/solid";
-import { ComponentChildren, Fragment, VNode, h } from "preact";
-import { useEffect, useErrorBoundary, useState } from "preact/hooks";
-import logo from "./assets/logo-2021.svg";
-import { Pages } from "./pages.js";
-import { PageEntry, Router, useCurrentLocation } from "./route.js";
-import { uiSettings } from "./settings.js";
 import { TranslatedString } from "@gnu-taler/taler-util";
+import { Footer, GlobalNotificationsBanner, Header, notifyError, 
notifyException, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { ComponentChildren, Fragment, VNode, h } from "preact";
+import { useEffect, useErrorBoundary } from "preact/hooks";
 import { useOfficer } from "./hooks/useOfficer.js";
 import { getAllBooleanSettings, getLabelForSetting, useSettings } from 
"./hooks/useSettings.js";
+import { Pages } from "./pages.js";
+import { PageEntry, useChangeLocation, useCurrentLocation } from "./route.js";
+import { uiSettings } from "./settings.js";
 
 function classNames(...classes: string[]) {
   return classes.filter(Boolean).join(" ");
@@ -101,7 +96,7 @@ function LeftMenu() {
                   "group flex gap-x-3 rounded-md p-2 text-sm leading-6 
font-semibold",
                 )}
               >
-                <InformationCircleIcon
+                {/* <InformationCircleIcon
                   class={classNames(
                     Pages.cases.url === currentLocation?.path
                       ? "text-white"
@@ -109,7 +104,11 @@ function LeftMenu() {
                     "h-6 w-6 shrink-0",
                   )}
                   aria-hidden="true"
-                />
+                /> */}
+                <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="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 
001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 
0zm-9-3.75h.008v.008H12V8.25z" />
+                </svg>
+
                 Cases
               </a>
             </li>
@@ -123,7 +122,11 @@ function LeftMenu() {
                   "group flex gap-x-3 rounded-md p-2 text-sm leading-6 
font-semibold",
                 )}
               >
-                <UserIcon
+                <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="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 
0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 
01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" />
+                </svg>
+
+                {/* <UserIcon
                   class={classNames(
                     Pages.officer.url === currentLocation?.path
                       ? "text-white"
@@ -131,7 +134,7 @@ function LeftMenu() {
                     "h-6 w-6 shrink-0",
                   )}
                   aria-hidden="true"
-                />
+                /> */}
                 Account
               </a>
             </li>
@@ -233,6 +236,7 @@ function Navigation(): VNode {
     Pages.officer,
     Pages.cases
   ]
+  const location = useChangeLocation();
   return (
     <div class="flex gap-y-5 w-48 bg-indigo-600 divide-y rounded-r-lg 
divide-cyan-800 overflow-y-auto overflow-x-clip">
 
@@ -241,10 +245,13 @@ function Navigation(): VNode {
           <li>
             <ul role="list" class="-mx-2 space-y-1">
               {pageList.map(p => {
+                
                 return <li>
-                  {/* <!-- Current: "bg-indigo-700 text-white", Default: 
"text-indigo-200 hover:text-white hover:bg-indigo-700" --> */}
-                  <a href="#" class="bg-indigo-700 text-white group flex 
gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
-                    <img src={p.icon} />
+                  {/* <!-- Current: "bg-indigo-700 text-white", 
+                         Default: "text-indigo-200 hover:text-white 
hover:bg-indigo-700" --> */}
+                  <a href={p.url} data-selected={location == p.url} 
+                    class="data-[selected=true]:bg-indigo-700 
data-[selected=true]:text-white  text-indigo-200 hover:text-white 
hover:bg-indigo-700   group flex gap-x-3 rounded-md p-2 text-sm leading-6 
font-semibold">
+                    { p.Icon && <p.Icon />}
                     {p.name}
                   </a>
                 </li>
diff --git a/packages/aml-backoffice-ui/src/forms/902_11e.ts 
b/packages/aml-backoffice-ui/src/forms/902_11e.ts
index a91e7a866..5507c72dc 100644
--- a/packages/aml-backoffice-ui/src/forms/902_11e.ts
+++ b/packages/aml-backoffice-ui/src/forms/902_11e.ts
@@ -52,7 +52,6 @@ export const v1 = (current: State): 
FlexibleForm<Form902_11.Form> => ({
             name: "businessEstablisher",
             label: "Persons" as TranslatedString,
             required: true,
-            tooltip: "hola" as TranslatedString,
             placeholder: "this is the placeholder" as TranslatedString,
             fields: [
               {
diff --git a/packages/aml-backoffice-ui/src/forms/902_1e.ts 
b/packages/aml-backoffice-ui/src/forms/902_1e.ts
index 167d1ac19..c212efb1a 100644
--- a/packages/aml-backoffice-ui/src/forms/902_1e.ts
+++ b/packages/aml-backoffice-ui/src/forms/902_1e.ts
@@ -220,7 +220,6 @@ export const v1 = (current: State): 
FlexibleForm<Form902_1.Form> => ({
             name: "businessEstablisher",
             label: "Persons" as TranslatedString,
             required: true,
-            tooltip: "hola" as TranslatedString,
             placeholder: "this is the placeholder" as TranslatedString,
             fields: [
               {
diff --git a/packages/aml-backoffice-ui/src/forms/902_4e.ts 
b/packages/aml-backoffice-ui/src/forms/902_4e.ts
index cecd74390..7c47a8746 100644
--- a/packages/aml-backoffice-ui/src/forms/902_4e.ts
+++ b/packages/aml-backoffice-ui/src/forms/902_4e.ts
@@ -1,11 +1,10 @@
 import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
-import { ArrowRightIcon } from "@heroicons/react/24/outline";
-import { ChevronRightIcon } from "@heroicons/react/24/solid";
 import { h as create } from "preact";
 import { FormState } from "../handlers/FormProvider.js";
 import { State } from "../pages/AntiMoneyLaunderingForm.js";
 import { FlexibleForm } from "./index.js";
 import { Simplest, resolutionSection } from "./simplest.js";
+import { ArrowRightIcon, ChevronRightIcon } from "../pages/Cases.js";
 
 export const v1 = (current: State): FlexibleForm<Form902_4.Form> => ({
   versionId: "2023-05-15",
diff --git a/packages/aml-backoffice-ui/src/forms/simplest.ts 
b/packages/aml-backoffice-ui/src/forms/simplest.ts
index 023c1765f..6497f3949 100644
--- a/packages/aml-backoffice-ui/src/forms/simplest.ts
+++ b/packages/aml-backoffice-ui/src/forms/simplest.ts
@@ -7,9 +7,10 @@ import {
 import { FormState } from "../handlers/FormProvider.js";
 import { DoubleColumnFormSection } from "../handlers/forms.js";
 import { State } from "../pages/AntiMoneyLaunderingForm.js";
-import { amlStateConverter } from "../pages/CaseDetails.js";
+
 import { AmlExchangeBackend } from "../types.js";
 import { FlexibleForm } from "./index.js";
+import { amlStateConverter } from "../pages/ShowConsolidated.js";
 
 export const v1 = (current: State): FlexibleForm<Simplest.Form> => ({
   versionId: "2023-05-25",
diff --git a/packages/aml-backoffice-ui/src/handlers/InputDate.tsx 
b/packages/aml-backoffice-ui/src/handlers/InputDate.tsx
index 1fd81aad9..0f286e001 100644
--- a/packages/aml-backoffice-ui/src/handlers/InputDate.tsx
+++ b/packages/aml-backoffice-ui/src/handlers/InputDate.tsx
@@ -1,6 +1,5 @@
 import { AbsoluteTime } from "@gnu-taler/taler-util";
 import { InputLine, UIFormProps } from "./InputLine.js";
-import { CalendarIcon } from "@heroicons/react/24/outline";
 import { VNode, h } from "preact";
 import { format, parse } from "date-fns";
 
@@ -13,7 +12,11 @@ export function InputDate<T extends object, K extends keyof 
T>(
       type="text"
       after={{
         type: "icon",
-        icon: <CalendarIcon class="h-6 w-6" />,
+        // icon: <CalendarIcon class="h-6 w-6" />,
+        icon: <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
@@ -27,8 +30,8 @@ export function InputDate<T extends object, K extends keyof 
T>(
           return !v || !v.t_ms
             ? ""
             : v.t_ms === "never"
-            ? "never"
-            : format(v.t_ms, pattern);
+              ? "never"
+              : format(v.t_ms, pattern);
         },
       }}
       {...props}
diff --git a/packages/aml-backoffice-ui/src/pages.ts 
b/packages/aml-backoffice-ui/src/pages.ts
index 17ede651d..109cd31d0 100644
--- a/packages/aml-backoffice-ui/src/pages.ts
+++ b/packages/aml-backoffice-ui/src/pages.ts
@@ -1,24 +1,24 @@
 import { TranslatedString } from "@gnu-taler/taler-util";
 import { AntiMoneyLaunderingForm } from "./pages/AntiMoneyLaunderingForm.js";
 import { CaseDetails } from "./pages/CaseDetails.js";
-import { Cases } from "./pages/Cases.js";
+import { Cases, HomeIcon, PeopleIcon } from "./pages/Cases.js";
 import { NewFormEntry } from "./pages/NewFormEntry.js";
 import { Officer } from "./pages/Officer.js";
 import { PageEntry, pageDefinition } from "./route.js";
-import homeLogo from "./assets/home.svg";
-import peopleLogo from "./assets/people.svg";
+// import homeLogo from "./assets/home.svg";
+// import peopleLogo from "./assets/people.svg";
 const cases: PageEntry = {
   url: "#/cases",
   view: Cases,
   name: "Cases" as TranslatedString,
-  icon: homeLogo,
+  Icon: HomeIcon,
 };
 
 const officer: PageEntry = {
   url: "#/officer",
   view: Officer,
   name: "Officer" as TranslatedString,
-  icon: peopleLogo,
+  Icon: PeopleIcon,
 };
 
 const account: PageEntry<{ account: string }> = {
@@ -35,17 +35,10 @@ const newFormEntry: PageEntry<{ account?: string; type?: 
string }> = {
   // icon: () => undefined,
 };
 
-const form: PageEntry<{ number?: string }> = {
-  url: pageDefinition("#/form/:number?"),
-  view: AntiMoneyLaunderingForm,
-  name: "Form" as TranslatedString,
-  // icon: () => undefined,
-};
 
 export const Pages = {
   cases,
   officer,
   account,
-  form,
   newFormEntry,
 };
diff --git 
a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.stories.tsx 
b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.stories.tsx
new file mode 100644
index 000000000..a14966cc0
--- /dev/null
+++ b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.stories.tsx
@@ -0,0 +1,94 @@
+/*
+ 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 * as tests from "@gnu-taler/web-util/testing";
+import {
+  AntiMoneyLaunderingForm as TestedComponent,
+} from "./AntiMoneyLaunderingForm.js";
+
+export default {
+  title: "aml form",
+};
+
+export const SimpleComment = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 0,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const Identification = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 1,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const OperationalLegalEntity = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 2,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const Foundations = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 3,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const DelcarationOfTrusts = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 4,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const InformationOnLifeInsurance = tests.createExample(TestedComponent, 
{
+  account: "the_account",
+  selectedForm: 5,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const DeclarationOfBeneficialOwner = 
tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 6,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const CustomerProfile = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 7,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+export const RiskProfile = tests.createExample(TestedComponent, {
+  account: "the_account",
+  selectedForm: 8,
+  onSubmit: async (justification, newState, newThreshold) => {
+    alert(JSON.stringify({justification, newState, newThreshold}, undefined, 
2))
+  }
+});
+
diff --git a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx 
b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx
index c3fb7dafe..5d2a3dffe 100644
--- a/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx
+++ b/packages/aml-backoffice-ui/src/pages/AntiMoneyLaunderingForm.tsx
@@ -1,3 +1,5 @@
+import { AbsoluteTime, AmountJson, Amounts } from "@gnu-taler/taler-util";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
 import { h } from "preact";
 import { NiceForm } from "../NiceForm.js";
 import { v1 as form_902_11e_v1 } from "../forms/902_11e.js";
@@ -9,30 +11,63 @@ import { v1 as form_902_4e_v1 } from "../forms/902_4e.js";
 import { v1 as form_902_5e_v1 } from "../forms/902_5e.js";
 import { v1 as form_902_9e_v1 } from "../forms/902_9e.js";
 import { v1 as simplest } from "../forms/simplest.js";
-import { DocumentDuplicateIcon } from "@heroicons/react/24/solid";
-import { AbsoluteTime } from "@gnu-taler/taler-util";
-import { AmountJson, Amounts } from "@gnu-taler/taler-util";
+import { Pages } from "../pages.js";
 import { AmlExchangeBackend } from "../types.js";
 
-export function AntiMoneyLaunderingForm({ number }: { number?: string }) {
-  const selectedForm = Number.parseInt(number ?? "0", 10);
-  if (Number.isNaN(selectedForm)) {
-    return <div>WHAT! {number}</div>;
-  }
+export type Justification = {
+  // form index in the list of forms
+  index: number;
+  // form name
+  name: string;
+  // form values
+  value: any;
+}
+
+export function AntiMoneyLaunderingForm({ account, selectedForm, onSubmit }: { 
account: string, selectedForm: number, onSubmit: (justification: Justification, 
state: AmlExchangeBackend.AmlState, threshold: AmountJson) => Promise<void>; }) 
{
+  const { i18n } = useTranslationContext()
   const showingFrom = allForms[selectedForm].impl;
-  const storedValue = {
+  const formName = allForms[selectedForm].name
+  const initial = {
     fullName: "loggedIn_user_fullname",
     when: AbsoluteTime.now(),
+    state: AmlExchangeBackend.AmlState.pending,
+    threshold: Amounts.parseOrThrow("KUDOS:1000"),
   };
   return (
     <NiceForm
-      initial={storedValue}
-      form={showingFrom({
-        state: AmlExchangeBackend.AmlState.pending,
-        threshold: Amounts.parseOrThrow("USD:10"),
-      })}
-      onUpdate={() => {}}
-    />
+      initial={initial}
+      form={showingFrom(initial)}
+      onUpdate={() => { }}
+      onSubmit={(formValue) => {
+        if (formValue.state === undefined || formValue.threshold === 
undefined) return;
+        const st = formValue.state;
+        const amount = formValue.threshold;
+
+        const justification = {
+          index: selectedForm,
+          name: formName,
+          value: formValue
+        }
+
+        onSubmit(justification, st, amount);
+      }}
+    >
+      <div class="mt-6 flex items-center justify-end gap-x-6">
+        <a
+          //   type="button"
+          href={Pages.account.url({ account })}
+          class="text-sm font-semibold leading-6 text-gray-900"
+        >
+          <i18n.Translate>Cancel</i18n.Translate>
+        </a>
+        <button
+          type="submit"
+          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>
+    </NiceForm>
   );
 }
 
@@ -41,6 +76,11 @@ export interface State {
   threshold: AmountJson;
 }
 
+const DocumentDuplicateIcon = <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="M15.75 17.25v3.375c0 
.621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 
01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 
011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 
1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 
00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 
1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 
00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375  [...]
+</svg>
+
+
 export const allForms = [
   {
     name: "Simple comment",
diff --git a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx 
b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
index f618a3592..1f8d6ac5e 100644
--- a/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
+++ b/packages/aml-backoffice-ui/src/pages/CaseDetails.tsx
@@ -2,24 +2,20 @@ import {
   AbsoluteTime,
   AmountJson,
   Amounts,
-  PaytoString,
   TalerError,
   TranslatedString,
-  assertUnreachable,
+  assertUnreachable
 } from "@gnu-taler/taler-util";
 import { ErrorLoading, Loading, useTranslationContext } from 
"@gnu-taler/web-util/browser";
-import { ArrowDownCircleIcon, ClockIcon } from "@heroicons/react/20/solid";
 import { format } from "date-fns";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
-import { NiceForm } from "../NiceForm.js";
-import { FlexibleForm } from "../forms/index.js";
-import { UIFormField } from "../handlers/forms.js";
 import { useCaseDetails } from "../hooks/useCaseDetails.js";
 import { Pages } from "../pages.js";
 import { AmlExchangeBackend } from "../types.js";
+import { ShowConsolidated } from "./ShowConsolidated.js";
 
-type AmlEvent = AmlFormEvent | KycCollectionEvent | KycExpirationEvent;
+export type AmlEvent = AmlFormEvent | KycCollectionEvent | KycExpirationEvent;
 type AmlFormEvent = {
   type: "aml-form";
   when: AbsoluteTime;
@@ -47,7 +43,7 @@ function selectSooner(a: WithTime, b: WithTime) {
   return AbsoluteTime.cmp(a.when, b.when);
 }
 
-function getEventsFromAmlHistory(
+export function getEventsFromAmlHistory(
   aml: AmlExchangeBackend.AmlDecisionDetail[],
   kyc: AmlExchangeBackend.KycDetail[],
 ): AmlEvent[] {
@@ -113,12 +109,16 @@ export function CaseDetails({ account }: { account: 
string }) {
         href={Pages.newFormEntry.url({ account })}
         class="m-4 block rounded-md w-fit border-0 px-3 py-2 text-center 
text-sm bg-indigo-700 text-white shadow-sm hover:bg-indigo-700"
       >
-        New AML form
+        <i18n.Translate>
+          New AML form
+        </i18n.Translate>
       </a>
 
       <header class="flex items-center justify-between border-b border-white/5 
px-4 py-4 sm:px-6 sm:py-6 lg:px-8">
         <h1 class="text-base font-semibold leading-7 text-black">
-          Case history
+          <i18n.Translate>
+            Case history
+          </i18n.Translate>
         </h1>
       </header>
       <div class="flow-root">
@@ -187,11 +187,18 @@ export function CaseDetails({ account }: { account: 
string }) {
                         }
                         case "kyc-collection": {
                           return (
-                            <ArrowDownCircleIcon class="h-8 w-8 
text-green-700" />
+                            // <ArrowDownCircleIcon class="h-8 w-8 
text-green-700" />
+                            <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="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 
9 0 0118 0z" />
+                            </svg>
                           );
                         }
                         case "kyc-expiration": {
-                          return <ClockIcon class="h-8 w-8 text-gray-700" />;
+                          // return <ClockIcon class="h-8 w-8 text-gray-700" 
/>;
+                          return <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="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
+                          </svg>
+
                         }
                       }
                     })()}
@@ -217,7 +224,7 @@ export function CaseDetails({ account }: { account: string 
}) {
         </ul>
       </div>
       {selected && <ShowEventDetails event={selected} />}
-      {selected && <ShowConsolidated history={events} until={selected} />}
+      {selected && <ShowConsolidated history={events} until={selected.when} />}
     </div>
   );
 }
@@ -226,197 +233,4 @@ function ShowEventDetails({ event }: { event: AmlEvent 
}): VNode {
   return <div>type {event.type}</div>;
 }
 
-function ShowConsolidated({
-  history,
-  until,
-}: {
-  history: AmlEvent[];
-  until: AmlEvent;
-}): VNode {
-  const cons = getConsolidated(history, until.when);
-
-  const form: FlexibleForm<Consolidated> = {
-    versionId: "1",
-    behavior: (form) => {
-      return {
-        aml: {
-          threshold: {
-            hidden: !form.aml
-          },
-          since: {
-            hidden: !form.aml
-          },
-          state: {
-            hidden: !form.aml
-          }
-        }
-      };
-    },
-    design: [
-      {
-        title: "AML" as TranslatedString,
-        fields: [
-          {
-            type: "amount",
-            props: {
-              label: "Threshold" as TranslatedString,
-              name: "aml.threshold",
-            },
-          },
-          {
-            type: "choiceHorizontal",
-            props: {
-              label: "State" as TranslatedString,
-              name: "aml.state",
-              converter: amlStateConverter,
-              choices: [
-                {
-                  label: "Frozen" as TranslatedString,
-                  value: AmlExchangeBackend.AmlState.frozen,
-                },
-                {
-                  label: "Pending" as TranslatedString,
-                  value: AmlExchangeBackend.AmlState.pending,
-                },
-                {
-                  label: "Normal" as TranslatedString,
-                  value: AmlExchangeBackend.AmlState.normal,
-                },
-              ],
-            },
-          },
-        ],
-      },
-      Object.entries(cons.kyc).length > 0
-        ? {
-          title: "KYC" as TranslatedString,
-          fields: Object.entries(cons.kyc).map(([key, field]) => {
-            const result: UIFormField = {
-              type: "text",
-              props: {
-                label: key as TranslatedString,
-                name: `kyc.${key}.value`,
-                help: `${field.provider} since ${field.since.t_ms === "never"
-                  ? "never"
-                  : format(field.since.t_ms, "dd/MM/yyyy")
-                  }` as TranslatedString,
-              },
-            };
-            return result;
-          }),
-        }
-        : undefined,
-    ],
-  };
-  return (
-    <Fragment>
-      <h1 class="text-base font-semibold leading-7 text-black">
-        Consolidated information after{" "}
-        {until.when.t_ms === "never"
-          ? "never"
-          : format(until.when.t_ms, "dd MMMM yyyy")}
-      </h1>
-      <NiceForm
-        key={`${String(Date.now())}`}
-        form={form}
-        initial={cons}
-        onUpdate={() => { }}
-      />
-    </Fragment>
-  );
-}
 
-interface Consolidated {
-  aml: {
-    state: AmlExchangeBackend.AmlState;
-    threshold: AmountJson;
-    since: AbsoluteTime;
-  };
-  kyc: {
-    [field: string]: {
-      value: any;
-      provider: string;
-      since: AbsoluteTime;
-    };
-  };
-}
-
-function getConsolidated(
-  history: AmlEvent[],
-  when: AbsoluteTime,
-): Consolidated {
-  const initial: Consolidated = {
-    aml: {
-      state: AmlExchangeBackend.AmlState.normal,
-      threshold: {
-        currency: "ARS",
-        value: 1000,
-        fraction: 0,
-      },
-      since: AbsoluteTime.never()
-    },
-    kyc: {},
-  };
-  return history.reduce((prev, cur) => {
-    if (AbsoluteTime.cmp(when, cur.when) < 0) {
-      return prev;
-    }
-    switch (cur.type) {
-      case "kyc-expiration": {
-        cur.fields.forEach((field) => {
-          delete prev.kyc[field];
-        });
-        break;
-      }
-      case "aml-form": {
-        prev.aml = {
-          since: cur.when,
-          state: cur.state,
-          threshold: cur.threshold
-        }
-        break;
-      }
-      case "kyc-collection": {
-        Object.keys(cur.values).forEach((field) => {
-          prev.kyc[field] = {
-            value: (cur.values as any)[field],
-            provider: cur.provider,
-            since: cur.when,
-          };
-        });
-        break;
-      }
-    }
-    return prev;
-  }, initial);
-}
-
-export const amlStateConverter = {
-  toStringUI: stringifyAmlState,
-  fromStringUI: parseAmlState,
-};
-
-function stringifyAmlState(s: AmlExchangeBackend.AmlState | undefined): string 
{
-  if (s === undefined) return "";
-  switch (s) {
-    case AmlExchangeBackend.AmlState.normal:
-      return "normal";
-    case AmlExchangeBackend.AmlState.pending:
-      return "pending";
-    case AmlExchangeBackend.AmlState.frozen:
-      return "frozen";
-  }
-}
-
-function parseAmlState(s: string | undefined): AmlExchangeBackend.AmlState {
-  switch (s) {
-    case "normal":
-      return AmlExchangeBackend.AmlState.normal;
-    case "pending":
-      return AmlExchangeBackend.AmlState.pending;
-    case "frozen":
-      return AmlExchangeBackend.AmlState.frozen;
-    default:
-      throw Error(`unknown AML state: ${s}`);
-  }
-}
diff --git a/packages/aml-backoffice-ui/src/pages/Cases.tsx 
b/packages/aml-backoffice-ui/src/pages/Cases.tsx
index 624f2c985..64cacf68c 100644
--- a/packages/aml-backoffice-ui/src/pages/Cases.tsx
+++ b/packages/aml-backoffice-ui/src/pages/Cases.tsx
@@ -6,8 +6,9 @@ import { createNewForm } from "../handlers/forms.js";
 import { useCases } from "../hooks/useCases.js";
 import { Pages } from "../pages.js";
 import { AmlExchangeBackend } from "../types.js";
-import { amlStateConverter } from "./CaseDetails.js";
+
 import { Officer } from "./Officer.js";
+import { amlStateConverter } from "./ShowConsolidated.js";
 
 export function Cases() {
   const { i18n } = useTranslationContext();
@@ -43,10 +44,14 @@ export function Cases() {
         <div class="sm:flex sm:items-center">
           <div class="sm:flex-auto">
             <h1 class="text-base font-semibold leading-6 text-gray-900">
+              <i18n.Translate>
               Cases
+              </i18n.Translate>
             </h1>
             <p class="mt-2 text-sm text-gray-700">
+              <i18n.Translate>
               A list of all the account with the status
+              </i18n.Translate>
             </p>
           </div>
           <form.Provider
@@ -166,6 +171,25 @@ export function Cases() {
   );
 }
 
+export const PeopleIcon = () => <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="M15.75 6a3.75 3.75 0 
11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 
0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" />
+</svg>
+
+export const HomeIcon = () => <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="M2.25 
12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 
1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 
1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" 
/>
+</svg>
+
+
+export const ChevronRightIcon = () => <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="M8.25 4.5l7.5 7.5-7.5 
7.5" />
+</svg>
+
+
+export const ArrowRightIcon = () => <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="M13.5 4.5L21 12m0 
0l-7.5 7.5M21 12H3" />
+</svg>
+
+
 function Pagination() {
   return (
     <nav class="flex items-center justify-between px-4 sm:px-0">
diff --git a/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx 
b/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx
index b3d04d97e..ff800ebdc 100644
--- a/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx
+++ b/packages/aml-backoffice-ui/src/pages/HandleAccountNotReady.tsx
@@ -2,6 +2,7 @@ import { VNode, h } from "preact";
 import { OfficerNotReady } from "../hooks/useOfficer.js";
 import { CreateAccount } from "./CreateAccount.js";
 import { UnlockAccount } from "./UnlockAccount.js";
+import { assertUnreachable } from "@gnu-taler/taler-util";
 
 export function HandleAccountNotReady({
   officer,
@@ -24,14 +25,11 @@ export function HandleAccountNotReady({
         onRemoveAccount={() => {
           officer.forget();
         }}
-        onAccountUnlocked={(pwd) => {
-          officer.tryUnlock(pwd);
+        onAccountUnlocked={async (pwd) => {
+          await officer.tryUnlock(pwd);
         }}
       />
     );
   }
-  return <div>
-    some
-  </div>
-  throw Error(`unexpected account state ${(officer as any).state}`);
+  assertUnreachable(officer)
 }
diff --git a/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx 
b/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx
index b291ffbee..e70536cb2 100644
--- a/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx
+++ b/packages/aml-backoffice-ui/src/pages/NewFormEntry.tsx
@@ -1,5 +1,5 @@
 import { VNode, h } from "preact";
-import { allForms } from "./AntiMoneyLaunderingForm.js";
+import { AntiMoneyLaunderingForm, allForms } from 
"./AntiMoneyLaunderingForm.js";
 import { Pages } from "../pages.js";
 import { NiceForm } from "../NiceForm.js";
 import { AbsoluteTime, Amounts, TalerExchangeApi, TalerProtocolTimestamp } 
from "@gnu-taler/taler-util";
@@ -31,60 +31,27 @@ export function NewFormEntry({
   if (Number.isNaN(selectedForm)) {
     return <div>WHAT! {type}</div>;
   }
-  const showingFrom = allForms[selectedForm].impl;
-  const formName = allForms[selectedForm].name
-  const initial = {
-    fullName: "loggedIn_user_fullname",
-    when: AbsoluteTime.now(),
-    state: AmlExchangeBackend.AmlState.pending,
-    threshold: Amounts.parseOrThrow("KUDOS:1000"),
-  };
+
   const { api } = useExchangeApiContext()
 
   return (
-    <NiceForm
-      initial={initial}
-      form={showingFrom(initial)}
-      onSubmit={(formValue) => {
-        if (formValue.state === undefined || formValue.threshold === 
undefined) return;
-
-        const justification = {
-          index: selectedForm,
-          name: formName,
-          value: formValue
-        }
+    <AntiMoneyLaunderingForm
+      account={account}
+      selectedForm={selectedForm}
+      onSubmit={async (justification, new_state, new_threshold) => {
         const decision: TalerExchangeApi.AmlDecision = {
           justification: JSON.stringify(justification),
           decision_time: TalerProtocolTimestamp.now(),
           h_payto: account,
-          new_state: formValue.state,
-          new_threshold: Amounts.stringify(formValue.threshold),
+          new_state,
+          new_threshold: Amounts.stringify(new_threshold),
           officer_sig: "",
           kyc_requirements: undefined
         }
-        // const signature = 
buildDecisionSignature(officer.account.signingKey, decision);
-        // decision.officer_sig = signature
         api.addDecisionDetails(officer.account, decision);
 
-        // alert(JSON.stringify(formValue));
       }}
-    >
-      <div class="mt-6 flex items-center justify-end gap-x-6">
-        <a
-          //   type="button"
-          href={Pages.account.url({ account })}
-          class="text-sm font-semibold leading-6 text-gray-900"
-        >
-          Cancel
-        </a>
-        <button
-          type="submit"
-          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"
-        >
-          Confirm
-        </button>
-      </div>
-    </NiceForm>
+    />
   );
 }
 
diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx 
b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx
new file mode 100644
index 000000000..1a86e8e98
--- /dev/null
+++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.stories.tsx
@@ -0,0 +1,60 @@
+/*
+ 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 { addDays } from "date-fns";
+import {
+  ShowConsolidated as TestedComponent,
+} from "./ShowConsolidated.js";
+import * as tests from "@gnu-taler/web-util/testing";
+import { getEventsFromAmlHistory } from "./CaseDetails.js";
+import { AbsoluteTime, Duration } from "@gnu-taler/taler-util";
+
+export default {
+  title: "show consolidated",
+};
+
+export const WithEmptyHistory = tests.createExample(TestedComponent, {
+  history: getEventsFromAmlHistory([],[]),
+  until: AbsoluteTime.now()
+});
+
+export const WithSomeEvents = tests.createExample(TestedComponent, {
+  history: getEventsFromAmlHistory([{
+    decider_pub: "123",
+    decision_time: { t_s: 1 },
+    justification: "yes",
+    new_state: 1,
+    new_threshold: "USD:10",
+  }],[{
+    collection_time: AbsoluteTime.toProtocolTimestamp(
+      AbsoluteTime.subtractDuraction(AbsoluteTime.now(), 
Duration.fromPrettyString("1d"))
+    ),
+    expiration_time: { t_s: "never"},
+    provider_section: "asd",
+    attributes: {
+      email: "sebasjm@qwe.com"
+    }
+  }]),
+  until: AbsoluteTime.now()
+});
+
+
+
diff --git a/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx 
b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
new file mode 100644
index 000000000..0efc68632
--- /dev/null
+++ b/packages/aml-backoffice-ui/src/pages/ShowConsolidated.tsx
@@ -0,0 +1,204 @@
+import { Fragment, VNode, h } from "preact";
+import { useState } from "preact/hooks";
+import { NiceForm } from "../NiceForm.js";
+import { FlexibleForm } from "../forms/index.js";
+import { UIFormField } from "../handlers/forms.js";
+import { AmlEvent } from "./CaseDetails.js";
+import { AmlExchangeBackend } from "../types.js";
+import { AbsoluteTime, AmountJson, TranslatedString } from 
"@gnu-taler/taler-util";
+import { format } from "date-fns";
+
+export function ShowConsolidated({
+  history,
+  until,
+}: {
+  history: AmlEvent[];
+  until: AbsoluteTime;
+}): VNode {
+  const cons = getConsolidated(history, until);
+
+  const form: FlexibleForm<Consolidated> = {
+    versionId: "1",
+    behavior: (form) => {
+      return {
+        aml: {
+          threshold: {
+            hidden: !form.aml
+          },
+          since: {
+            hidden: !form.aml
+          },
+          state: {
+            hidden: !form.aml
+          }
+        }
+      };
+    },
+    design: [
+      {
+        title: "AML" as TranslatedString,
+        fields: [
+          {
+            type: "amount",
+            props: {
+              label: "Threshold" as TranslatedString,
+              name: "aml.threshold",
+            },
+          },
+          {
+            type: "choiceHorizontal",
+            props: {
+              label: "State" as TranslatedString,
+              name: "aml.state",
+              converter: amlStateConverter,
+              choices: [
+                {
+                  label: "Frozen" as TranslatedString,
+                  value: AmlExchangeBackend.AmlState.frozen,
+                },
+                {
+                  label: "Pending" as TranslatedString,
+                  value: AmlExchangeBackend.AmlState.pending,
+                },
+                {
+                  label: "Normal" as TranslatedString,
+                  value: AmlExchangeBackend.AmlState.normal,
+                },
+              ],
+            },
+          },
+        ],
+      },
+      Object.entries(cons.kyc).length > 0
+        ? {
+          title: "KYC" as TranslatedString,
+          fields: Object.entries(cons.kyc).map(([key, field]) => {
+            const result: UIFormField = {
+              type: "text",
+              props: {
+                label: key as TranslatedString,
+                name: `kyc.${key}.value`,
+                help: `${field.provider} since ${field.since.t_ms === "never"
+                  ? "never"
+                  : format(field.since.t_ms, "dd/MM/yyyy")
+                  }` as TranslatedString,
+              },
+            };
+            return result;
+          }),
+        }
+        : undefined,
+    ],
+  };
+  return (
+    <Fragment>
+      <h1 class="text-base font-semibold leading-7 text-black">
+        Consolidated information 
+        {until.t_ms === "never"
+          ? ""
+          : `after ${format(until.t_ms, "dd MMMM yyyy")}` }
+      </h1>
+      <NiceForm
+        key={`${String(Date.now())}`}
+        form={form}
+        initial={cons}
+        onUpdate={() => { }}
+      />
+    </Fragment>
+  );
+}
+
+interface Consolidated {
+  aml: {
+    state: AmlExchangeBackend.AmlState;
+    threshold: AmountJson;
+    since: AbsoluteTime;
+  };
+  kyc: {
+    [field: string]: {
+      value: any;
+      provider: string;
+      since: AbsoluteTime;
+    };
+  };
+}
+
+function getConsolidated(
+  history: AmlEvent[],
+  when: AbsoluteTime,
+): Consolidated {
+  const initial: Consolidated = {
+    aml: {
+      state: AmlExchangeBackend.AmlState.normal,
+      threshold: {
+        currency: "ARS",
+        value: 1000,
+        fraction: 0,
+      },
+      since: AbsoluteTime.never()
+    },
+    kyc: {},
+  };
+  return history.reduce((prev, cur) => {
+    if (AbsoluteTime.cmp(when, cur.when) < 0) {
+      return prev;
+    }
+    switch (cur.type) {
+      case "kyc-expiration": {
+        cur.fields.forEach((field) => {
+          delete prev.kyc[field];
+        });
+        break;
+      }
+      case "aml-form": {
+        prev.aml = {
+          since: cur.when,
+          state: cur.state,
+          threshold: cur.threshold
+        }
+        break;
+      }
+      case "kyc-collection": {
+        Object.keys(cur.values).forEach((field) => {
+          prev.kyc[field] = {
+            value: (cur.values as any)[field],
+            provider: cur.provider,
+            since: cur.when,
+          };
+        });
+        break;
+      }
+    }
+    return prev;
+  }, initial);
+}
+
+export const amlStateConverter = {
+  toStringUI: stringifyAmlState,
+  fromStringUI: parseAmlState,
+};
+
+function stringifyAmlState(s: AmlExchangeBackend.AmlState | undefined): string 
{
+  if (s === undefined) return "";
+  switch (s) {
+    case AmlExchangeBackend.AmlState.normal:
+      return "normal";
+    case AmlExchangeBackend.AmlState.pending:
+      return "pending";
+    case AmlExchangeBackend.AmlState.frozen:
+      return "frozen";
+  }
+}
+
+function parseAmlState(s: string | undefined): AmlExchangeBackend.AmlState {
+  switch (s) {
+    case "normal":
+      return AmlExchangeBackend.AmlState.normal;
+    case "pending":
+      return AmlExchangeBackend.AmlState.pending;
+    case "frozen":
+      return AmlExchangeBackend.AmlState.frozen;
+    default:
+      throw Error(`unknown AML state: ${s}`);
+  }
+}
diff --git a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx 
b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
index a6570ffcc..ba5aa7b1f 100644
--- a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
+++ b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
@@ -7,7 +7,7 @@ export function UnlockAccount({
   onAccountUnlocked,
   onRemoveAccount,
 }: {
-  onAccountUnlocked: (password: string) => void;
+  onAccountUnlocked: (password: string) => Promise<void>;
   onRemoveAccount: () => void;
 }): VNode {
   const { i18n } = useTranslationContext()
@@ -30,13 +30,10 @@ export function UnlockAccount({
       <div class="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px] ">
         <div class="bg-gray-100 px-6 py-6 shadow sm:rounded-lg sm:px-12">
           <Form.Provider
-            initialValue={{
-              password: "qwe",
-            }}
+            initialValue={{}}
             onSubmit={async (v) => {
               try {
                 await onAccountUnlocked(v.password!);
-
                 notifyInfo("Account unlocked" as TranslatedString);
               } catch (e) {
                 if (e instanceof UnwrapKeyError) {
diff --git a/packages/aml-backoffice-ui/src/pages/index.stories.ts 
b/packages/aml-backoffice-ui/src/pages/index.stories.ts
new file mode 100644
index 000000000..e31e13a28
--- /dev/null
+++ b/packages/aml-backoffice-ui/src/pages/index.stories.ts
@@ -0,0 +1,2 @@
+export * as a1 from "./ShowConsolidated.stories.js";
+export * as a2 from "./AntiMoneyLaunderingForm.stories.js";
diff --git a/packages/aml-backoffice-ui/src/route.ts 
b/packages/aml-backoffice-ui/src/route.ts
index 4c3331668..9176ab5e4 100644
--- a/packages/aml-backoffice-ui/src/route.ts
+++ b/packages/aml-backoffice-ui/src/route.ts
@@ -49,14 +49,14 @@ export type PageEntry<T = unknown> = T extends 
Record<string, string>
     url: PageDefinition<T>;
     view: (props: T) => VNode;
     name: TranslatedString,
-    icon?: string,
+    Icon?: () => VNode,
   }
   : T extends unknown
   ? {
     url: string;
     view: (props: {}) => VNode;
     name: TranslatedString,
-    icon?: string,
+    Icon?: () => VNode,
   }
   : never;
 
@@ -124,6 +124,16 @@ export function useCurrentLocation(pageList: 
Array<PageEntry<any>>) {
   return currentLocation;
 }
 
+export function useChangeLocation() {
+  const [location, setLocation] = useState(window.location.hash)
+  useEffect(() => {
+    return history.listen(() => {
+      setLocation(window.location.hash)
+    });
+  }, []);
+  return location;
+}
+
 function doestUrlMatchToRoute(
   url: string,
   route: string,
diff --git a/packages/aml-backoffice-ui/src/stories.test.ts 
b/packages/aml-backoffice-ui/src/stories.test.ts
index 4e24967e4..3b1d0267d 100644
--- a/packages/aml-backoffice-ui/src/stories.test.ts
+++ b/packages/aml-backoffice-ui/src/stories.test.ts
@@ -23,7 +23,7 @@ import { parseGroupImport } from 
"@gnu-taler/web-util/browser";
 import * as tests from "@gnu-taler/web-util/testing";
 
 // import * as components from "./components/index.examples.js";
-// import * as pages from "./pages/index.stories.js";
+import * as pages from "./pages/index.stories.js";
 
 import { ComponentChildren, Fragment, VNode, h as create } from "preact";
 // import { BackendStateProviderTesting } from "./context/backend.js";
@@ -31,7 +31,7 @@ import { ComponentChildren, Fragment, VNode, h as create } 
from "preact";
 setupI18n("en", { en: {} });
 
 describe("All the examples:", () => {
-  const cms = parseGroupImport({});
+  const cms = parseGroupImport({pages});
   cms.forEach((group) => {
     describe(`Example for group "${group.title}:"`, () => {
       group.list.forEach((component) => {
diff --git a/packages/aml-backoffice-ui/src/stories.tsx 
b/packages/aml-backoffice-ui/src/stories.tsx
index b6c0c1f07..5ef54309c 100644
--- a/packages/aml-backoffice-ui/src/stories.tsx
+++ b/packages/aml-backoffice-ui/src/stories.tsx
@@ -20,17 +20,16 @@
  */
 import { strings } from "./i18n/strings.js";
 
-// import * as pages from "./pages/index.stories.js";
+import * as pages from "./pages/index.stories.js";
 // import * as components from "./components/index.examples.js";
 
 import { renderStories } from "@gnu-taler/web-util/browser";
 
-// import "./scss/main.scss";
+import "./scss/main.css";
 
 function main(): void {
   renderStories(
-    // { pages, components },
-    {},
+    {pages},
     {
       strings,
     },

-- 
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]