gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: feedback from meeting and edi


From: gnunet
Subject: [taler-wallet-core] branch master updated: feedback from meeting and editing policy
Date: Wed, 03 Nov 2021 21:35:58 +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 a82b5a69 feedback from meeting and editing policy
a82b5a69 is described below

commit a82b5a6992fda61d6eaa0bb079e284805a394777
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Nov 3 17:30:11 2021 -0300

    feedback from meeting and editing policy
---
 packages/anastasis-webui/package.json              |   4 +-
 .../anastasis-webui/src/components/AsyncButton.tsx |  51 ++++++++
 .../src/components/fields/DateInput.tsx            |  46 ++++---
 .../src/components/menu/NavigationBar.tsx          |   2 +-
 .../src/components/menu/SideBar.tsx                |  14 +--
 .../src/components/picker/DatePicker.tsx           |  12 +-
 packages/anastasis-webui/src/hooks/async.ts        |  77 ++++++++++++
 .../pages/home/AttributeEntryScreen.stories.tsx    |   4 +-
 .../src/pages/home/AttributeEntryScreen.tsx        |  37 ++++--
 .../src/pages/home/AuthenticationEditorScreen.tsx  |   4 +
 .../src/pages/home/BackupFinishedScreen.tsx        |   7 +-
 .../home/ContinentSelectionScreen.stories.tsx      |  18 ++-
 .../src/pages/home/ContinentSelectionScreen.tsx    |  36 +++---
 .../pages/home/CountrySelectionScreen.stories.tsx  |  39 ------
 .../src/pages/home/CountrySelectionScreen.tsx      |  31 -----
 .../src/pages/home/EditPoliciesScreen.stories.tsx  | 109 +++++++++++++++++
 .../src/pages/home/EditPoliciesScreen.tsx          | 133 +++++++++++++++++++++
 .../pages/home/ReviewPoliciesScreen.stories.tsx    |   8 +-
 .../src/pages/home/ReviewPoliciesScreen.tsx        |  57 +++++++--
 .../anastasis-webui/src/pages/home/StartScreen.tsx |  42 +++----
 .../home/authMethod/AuthMethodQuestionSetup.tsx    |  15 +--
 packages/anastasis-webui/src/pages/home/index.tsx  |  33 ++---
 packages/anastasis-webui/src/scss/main.scss        |   2 +-
 packages/anastasis-webui/src/utils/index.tsx       |  97 ++++++++++++---
 24 files changed, 657 insertions(+), 221 deletions(-)

diff --git a/packages/anastasis-webui/package.json 
b/packages/anastasis-webui/package.json
index b032c563..3042d8ca 100644
--- a/packages/anastasis-webui/package.json
+++ b/packages/anastasis-webui/package.json
@@ -4,9 +4,9 @@
   "version": "0.0.0",
   "license": "MIT",
   "scripts": {
-    "build": "preact build",
+    "build": "preact build --no-sw --no-esm",
     "serve": "sirv build --port 8080 --cors --single",
-    "dev": "preact watch",
+    "dev": "preact watch --no-sw --no-esm",
     "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
     "test": "jest ./tests",
     "build-storybook": "build-storybook",
diff --git a/packages/anastasis-webui/src/components/AsyncButton.tsx 
b/packages/anastasis-webui/src/components/AsyncButton.tsx
new file mode 100644
index 00000000..5602715e
--- /dev/null
+++ b/packages/anastasis-webui/src/components/AsyncButton.tsx
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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 { ComponentChildren, h, VNode } from "preact";
+// import { LoadingModal } from "../modal";
+import { useAsync } from "../hooks/async";
+// import { Translate } from "../../i18n";
+
+type Props = {
+  children: ComponentChildren;
+  disabled: boolean;
+  onClick?: () => Promise<void>;
+  [rest: string]: any;
+};
+
+export function AsyncButton({ onClick, disabled, children, ...rest }: Props): 
VNode {
+  const { isLoading, request } = useAsync(onClick);
+
+  // if (isSlow) {
+  //   return <LoadingModal onCancel={cancel} />;
+  // }
+  console.log(isLoading)
+  if (isLoading) {
+    
+    return <button class="button">Loading...</button>;
+  }
+
+  return <span {...rest}>
+    <button class="button is-info" onClick={request} disabled={disabled}>
+      {children}
+    </button>
+  </span>;
+}
diff --git a/packages/anastasis-webui/src/components/fields/DateInput.tsx 
b/packages/anastasis-webui/src/components/fields/DateInput.tsx
index 69a05fcf..c406b85d 100644
--- a/packages/anastasis-webui/src/components/fields/DateInput.tsx
+++ b/packages/anastasis-webui/src/components/fields/DateInput.tsx
@@ -1,4 +1,4 @@
-import { format } from "date-fns";
+import { format, isAfter, parse, sub, subYears } from "date-fns";
 import { h, VNode } from "preact";
 import { useLayoutEffect, useRef, useState } from "preact/hooks";
 import { DatePicker } from "../picker/DatePicker";
@@ -19,16 +19,14 @@ export function DateInput(props: DateInputProps): VNode {
       inputRef.current?.focus();
     }
   }, [props.grabFocus]);
-  const [opened, setOpened2] = useState(false)
-  function setOpened(v: boolean): void {
-    console.log('dale', v)
-    setOpened2(v)
-  }
+  const [opened, setOpened] = useState(false)
 
   const value = props.bind[0] || "";
   const [dirty, setDirty] = useState(false)
   const showError = dirty && props.error
 
+  const calendar = subYears(new Date(), 30)
+  
   return <div class="field">
     <label class="label">
       {props.label}
@@ -36,27 +34,37 @@ export function DateInput(props: DateInputProps): VNode {
         <i class="mdi mdi-information" />
       </span>}
     </label>
-    <div class="control has-icons-right">
-      <input
-        type="text"
-        class={showError ? 'input is-danger' : 'input'}
-        readonly
-        onFocus={() => { setOpened(true) } }
-        value={value}
-        ref={inputRef} />
-
-      <span class="control icon is-right">
-        <span class="icon"><i class="mdi mdi-calendar" /></span>
-      </span>
+    <div class="control">
+      <div class="field has-addons">
+        <p class="control">
+          <input
+            type="text"
+            class={showError ? 'input is-danger' : 'input'}
+            value={value}
+            onChange={(e) => {
+              const text = e.currentTarget.value
+              setDirty(true)
+              props.bind[1](text);
+            }}
+            ref={inputRef} />
+        </p>
+        <p class="control">
+          <a class="button" onClick={() => { setOpened(true) }}>
+            <span class="icon"><i class="mdi mdi-calendar" /></span>
+          </a>
+        </p>
+      </div>
     </div>
+    <p class="help">Using the format yyyy-mm-dd</p>
     {showError && <p class="help is-danger">{props.error}</p>}
     <DatePicker
       opened={opened}
+      initialDate={calendar}
       years={props.years}
       closeFunction={() => setOpened(false)}
       dateReceiver={(d) => {
         setDirty(true)
-        const v = format(d, 'yyyy/MM/dd')
+        const v = format(d, 'yyyy-MM-dd')
         props.bind[1](v);
       }}
     />
diff --git a/packages/anastasis-webui/src/components/menu/NavigationBar.tsx 
b/packages/anastasis-webui/src/components/menu/NavigationBar.tsx
index e1bb4c7c..935951ab 100644
--- a/packages/anastasis-webui/src/components/menu/NavigationBar.tsx
+++ b/packages/anastasis-webui/src/components/menu/NavigationBar.tsx
@@ -49,7 +49,7 @@ export function NavigationBar({ onMobileMenu, title }: 
Props): VNode {
       </a>
       <div class="navbar-end">
         <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}>
-          <LangSelector />
+          {/* <LangSelector /> */}
         </div>
       </div>
     </div>
diff --git a/packages/anastasis-webui/src/components/menu/SideBar.tsx 
b/packages/anastasis-webui/src/components/menu/SideBar.tsx
index 35720e0f..72655662 100644
--- a/packages/anastasis-webui/src/components/menu/SideBar.tsx
+++ b/packages/anastasis-webui/src/components/menu/SideBar.tsx
@@ -39,9 +39,9 @@ export function Sidebar({ mobile }: Props): VNode {
 
   return (
     <aside class="aside is-placed-left is-expanded">
-      {mobile && <div class="footer" onClick={(e) => { return 
e.stopImmediatePropagation() }}>
+      {/* {mobile && <div class="footer" onClick={(e) => { return 
e.stopImmediatePropagation() }}>
         <LangSelector />
-      </div>}
+      </div>} */}
       <div class="aside-tools">
         <div class="aside-tools-label">
           <div><b>Anastasis</b> Reducer</div>
@@ -68,7 +68,7 @@ export function Sidebar({ mobile }: Props): VNode {
             <li class={reducer.currentReducerState.backup_state === 
BackupStates.ContinentSelecting ||
               reducer.currentReducerState.backup_state === 
BackupStates.CountrySelecting ? 'is-active' : ''}>
               <div class="ml-4">
-                <span class="menu-item-label"><Translate>Location &amp; 
Currency</Translate></span>
+                <span 
class="menu-item-label"><Translate>Location</Translate></span>
               </div>
             </li>
             <li class={reducer.currentReducerState.backup_state === 
BackupStates.UserAttributesCollecting ? 'is-active' : ''}>
@@ -85,7 +85,7 @@ export function Sidebar({ mobile }: Props): VNode {
             <li class={reducer.currentReducerState.backup_state === 
BackupStates.PoliciesReviewing ? 'is-active' : ''}>
               <div class="ml-4">
 
-                <span class="menu-item-label"><Translate>Policies 
reviewing</Translate></span>
+                <span 
class="menu-item-label"><Translate>Policies</Translate></span>
               </div>
             </li>
             <li class={reducer.currentReducerState.backup_state === 
BackupStates.SecretEditing ? 'is-active' : ''}>
@@ -94,12 +94,12 @@ export function Sidebar({ mobile }: Props): VNode {
                 <span class="menu-item-label"><Translate>Secret 
input</Translate></span>
               </div>
             </li>
-            <li class={reducer.currentReducerState.backup_state === 
BackupStates.PoliciesPaying ? 'is-active' : ''}>
+            {/* <li class={reducer.currentReducerState.backup_state === 
BackupStates.PoliciesPaying ? 'is-active' : ''}>
               <div class="ml-4">
 
                 <span class="menu-item-label"><Translate>Payment 
(optional)</Translate></span>
               </div>
-            </li>
+            </li> */}
             <li class={reducer.currentReducerState.backup_state === 
BackupStates.BackupFinished ? 'is-active' : ''}>
               <div class="ml-4">
 
@@ -116,7 +116,7 @@ export function Sidebar({ mobile }: Props): VNode {
             <li class={reducer.currentReducerState.recovery_state === 
RecoveryStates.ContinentSelecting ||
               reducer.currentReducerState.recovery_state === 
RecoveryStates.CountrySelecting ? 'is-active' : ''}>
               <div class="ml-4">
-                <span class="menu-item-label"><Translate>Location &amp; 
Currency</Translate></span>
+                <span 
class="menu-item-label"><Translate>Location</Translate></span>
               </div>
             </li>
             <li class={reducer.currentReducerState.recovery_state === 
RecoveryStates.UserAttributesCollecting ? 'is-active' : ''}>
diff --git a/packages/anastasis-webui/src/components/picker/DatePicker.tsx 
b/packages/anastasis-webui/src/components/picker/DatePicker.tsx
index 5b33fa8b..a94b3708 100644
--- a/packages/anastasis-webui/src/components/picker/DatePicker.tsx
+++ b/packages/anastasis-webui/src/components/picker/DatePicker.tsx
@@ -24,6 +24,7 @@ import { h, Component } from "preact";
 interface Props {
   closeFunction?: () => void;
   dateReceiver?: (d: Date) => void;
+  initialDate?: Date;
   years?: Array<number>;
   opened?: boolean;
 }
@@ -213,8 +214,8 @@ export class DatePicker extends Component<Props, State> {
     // }
   }
 
-  constructor() {
-    super();
+  constructor(props) {
+    super(props);
 
     this.closeDatePicker = this.closeDatePicker.bind(this);
     this.dayClicked = this.dayClicked.bind(this);
@@ -226,11 +227,12 @@ export class DatePicker extends Component<Props, State> {
     this.toggleYearSelector = this.toggleYearSelector.bind(this);
     this.displaySelectedMonth = this.displaySelectedMonth.bind(this);
 
+    const initial = props.initialDate || now;
 
     this.state = {
-      currentDate: now,
-      displayedMonth: now.getMonth(),
-      displayedYear: now.getFullYear(),
+      currentDate: initial,
+      displayedMonth: initial.getMonth(),
+      displayedYear: initial.getFullYear(),
       selectYearMode: false
     }
   }
diff --git a/packages/anastasis-webui/src/hooks/async.ts 
b/packages/anastasis-webui/src/hooks/async.ts
new file mode 100644
index 00000000..f142a5dc
--- /dev/null
+++ b/packages/anastasis-webui/src/hooks/async.ts
@@ -0,0 +1,77 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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 { useState } from "preact/hooks";
+// import { cancelPendingRequest } from "./backend";
+
+export interface Options {
+  slowTolerance: number;
+}
+
+export interface AsyncOperationApi<T> {
+  request: (...a: any) => void;
+  cancel: () => void;
+  data: T | undefined;
+  isSlow: boolean;
+  isLoading: boolean;
+  error: string | undefined;
+}
+
+export function useAsync<T>(fn?: (...args: any) => Promise<T>, { 
slowTolerance: tooLong }: Options = { slowTolerance: 1000 }): 
AsyncOperationApi<T> {
+  const [data, setData] = useState<T | undefined>(undefined);
+  const [isLoading, setLoading] = useState<boolean>(false);
+  const [error, setError] = useState<any>(undefined);
+  const [isSlow, setSlow] = useState(false)
+
+  const request = async (...args: any) => {
+    if (!fn) return;
+    setLoading(true);
+    console.log("loading true")
+    const handler = setTimeout(() => {
+      setSlow(true)
+    }, tooLong)
+
+    try {
+      const result = await fn(...args);
+      console.log(result)
+      setData(result);
+    } catch (error) {
+      setError(error);
+    }
+    setLoading(false);
+    setSlow(false)
+    clearTimeout(handler)
+  };
+
+  function cancel() {
+    // cancelPendingRequest()
+    setLoading(false);
+    setSlow(false)
+  }
+
+  return {
+    request,
+    cancel,
+    data,
+    isSlow,
+    isLoading,
+    error
+  };
+}
diff --git 
a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
index 32d7817e..54968661 100644
--- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx
@@ -52,8 +52,8 @@ export const Backup = createExample(TestedComponent, {
     uuid: 'asdasdsa2',
     widget: 'wid',
   }, {
-    name: 'date',
-    label: 'third',
+    name: 'birthdate',
+    label: 'birthdate',
     type: 'date',
     uuid: 'asdasdsa3',
     widget: 'calendar',
diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx 
b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
index 2c7f54c5..52046b21 100644
--- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx
@@ -7,6 +7,7 @@ import { AnastasisClientFrame, withProcessLabel } from 
"./index";
 import { TextInput } from "../../components/fields/TextInput";
 import { DateInput } from "../../components/fields/DateInput";
 import { NumberInput } from "../../components/fields/NumberInput";
+import { isAfter, parse } from "date-fns";
 
 export function AttributeEntryScreen(): VNode {
   const reducer = useAnastasisContext()
@@ -46,15 +47,14 @@ export function AttributeEntryScreen(): VNode {
         identity_attributes: attrs,
       })}
     >
-      <div class="columns">
-        <div class="column is-half">
+      <div class="columns" style={{ maxWidth: 'unset' }}>
+        <div class="column is-one-third">
           {fieldList}
         </div>
-        <div class="column is-half" >
+        <div class="column is-two-third" >
           <p>This personal information will help to locate your secret.</p>
-          <h1><b>This stay private</b></h1>
-          <p>The information you have entered here:
-          </p>
+          <h1 class="title">This stays private</h1>
+          <p>The information you have entered here:</p>
           <ul>
             <li>
               <span class="icon is-right">
@@ -111,15 +111,17 @@ function AttributeEntryField(props: 
AttributeEntryFieldProps): VNode {
           bind={[props.value, props.setValue]}
         />
       }
-      <span>
+      <div class="block">
+        This stays private
         <span class="icon is-right">
           <i class="mdi mdi-eye-off" />
         </span>
-        This stay private
-      </span>
+      </div>
     </div>
   );
 }
+const YEAR_REGEX = /^[0-9]+-[0-9]+-[0-9]+$/
+
 
 function checkIfValid(value: string, spec: UserAttributeSpec): string | 
undefined {
   const pattern = spec['validation-regex']
@@ -136,5 +138,22 @@ function checkIfValid(value: string, spec: 
UserAttributeSpec): string | undefine
   if (!optional && !value) {
     return 'This value is required'
   }
+  if ("date" === spec.type) {
+    if (!YEAR_REGEX.test(value)) {
+      return "The date doesn't follow the format"
+    }
+
+    try {
+      const v = parse(value, 'yyyy-MM-dd', new Date());
+      if (Number.isNaN(v.getTime())) {
+        return "Some numeric values seems out of range for a date"
+      }
+      if ("birthdate" === spec.name && isAfter(v, new Date())) {
+        return "A birthdate cannot be in the future"
+      }
+    } catch (e) {
+      return "Could not parse the date"
+    }
+  }
   return undefined
 }
diff --git 
a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx 
b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
index 4e7819a7..ab482044 100644
--- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
@@ -142,6 +142,10 @@ export function AuthenticationEditorScreen(): VNode {
         </div>
         <div class="column is-half">
           When recovering your wallet, you will be asked to verify your 
identity via the methods you configure here.
+
+          <b>Explain the exclamation marks</b>
+
+          <a>Explain how to add providers</a>
         </div>
       </div>
     </AnastasisClientFrame>
diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx 
b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
index 70ac8157..7938baca 100644
--- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx
@@ -23,7 +23,7 @@ export function BackupFinishedScreen(): VNode {
       </p>}
 
     {details && <div class="block">
-    <p>The backup is stored by the following providers:</p>
+      <p>The backup is stored by the following providers:</p>
       {Object.keys(details).map((x, i) => {
         const sd = details[x];
         return (
@@ -31,11 +31,14 @@ export function BackupFinishedScreen(): VNode {
             {x}
             <p>
               version {sd.policy_version}
-              {sd.policy_expiration.t_ms !== 'never' ? ` expires at: 
${format(sd.policy_expiration.t_ms, 'dd/MM/yyyy')}` : ' without expiration 
date'}
+              {sd.policy_expiration.t_ms !== 'never' ? ` expires at: 
${format(sd.policy_expiration.t_ms, 'dd-MM-yyyy')}` : ' without expiration 
date'}
             </p>
           </div>
         );
       })}
     </div>}
+    <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+      <button class="button" onClick={() => reducer.back()}>Back</button>
+    </div>
   </AnastasisClientFrame>);
 }
diff --git 
a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
index 2186eb42..6bdb3515 100644
--- 
a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.stories.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -19,12 +20,13 @@
 * @author Sebastian Javier Marchano (sebasjm)
 */
 
+import { ReducerState } from 'anastasis-core';
 import { createExample, reducerStatesExample } from '../../utils';
 import { ContinentSelectionScreen as TestedComponent } from 
'./ContinentSelectionScreen';
 
 
 export default {
-  title: 'Pages/ContinentSelectionScreen',
+  title: 'Pages/Location',
   component: TestedComponent,
   args: {
     order: 2,
@@ -35,6 +37,16 @@ export default {
   },
 };
 
-export const Backup = createExample(TestedComponent, 
reducerStatesExample.backupSelectContinent);
+export const BackupSelectContinent = createExample(TestedComponent, 
reducerStatesExample.backupSelectContinent);
 
-export const Recovery = createExample(TestedComponent, 
reducerStatesExample.recoverySelectContinent);
+export const BackupSelectCountry = createExample(TestedComponent, {
+  ...reducerStatesExample.backupSelectContinent,
+  selected_continent: 'Testcontinent',
+} as ReducerState);
+
+export const RecoverySelectContinent = createExample(TestedComponent, 
reducerStatesExample.recoverySelectContinent);
+
+export const RecoverySelectCountry = createExample(TestedComponent, {
+  ...reducerStatesExample.recoverySelectContinent,
+  selected_continent: 'Testcontinent',
+} as ReducerState);
diff --git 
a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx 
b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
index 71365562..4ab0e6a9 100644
--- a/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ContinentSelectionScreen.tsx
@@ -36,20 +36,21 @@ export function ContinentSelectionScreen(): VNode {
     })
   }
 
-  const step1 = reducer.currentReducerState.backup_state === 
BackupStates.ContinentSelecting ||
-    reducer.currentReducerState.recovery_state === 
RecoveryStates.ContinentSelecting;
+  // const step1 = reducer.currentReducerState.backup_state === 
BackupStates.ContinentSelecting ||
+  //   reducer.currentReducerState.recovery_state === 
RecoveryStates.ContinentSelecting;
 
   const errors = !theCountry ? "Select a country" : undefined 
 
   return (
-    <AnastasisClientFrame hideNext={errors} title={withProcessLabel(reducer, 
"Select location")} onNext={selectCountryAction}>
-      <div class="columns">
-        <div class="column is-half">
+    <AnastasisClientFrame hideNext={errors} title={withProcessLabel(reducer, 
"Where do you live?")} onNext={selectCountryAction}>
+
+      <div class="columns" >
+        <div class="column is-one-third">
           <div class="field">
             <label class="label">Continent</label>
-            <div class="control has-icons-left">
-              <div class="select " >
-                <select onChange={(e) => 
selectContinent(e.currentTarget.value)} value={theContinent} disabled={!step1}>
+            <div class="control is-expanded has-icons-left">
+              <div class="select is-fullwidth" >
+                <select onChange={(e) => 
selectContinent(e.currentTarget.value)} value={theContinent} >
                   <option key="none" disabled selected value=""> Choose a 
continent </option>
                   {continentList.map(prov => (
                     <option key={prov.name} value={prov.name}>
@@ -61,18 +62,13 @@ export function ContinentSelectionScreen(): VNode {
                   <i class="mdi mdi-earth" />
                 </div>
               </div>
-              {!step1 && <span class="control">
-                <a class="button is-danger" onClick={() => reducer.back()}>
-                  X
-                </a>
-              </span>}
             </div>
           </div>
 
           <div class="field">
             <label class="label">Country</label>
-            <div class="control has-icons-left">
-              <div class="select" >
+            <div class="control is-expanded has-icons-left">
+              <div class="select is-fullwidth" >
                 <select onChange={(e) => selectCountry((e.target as 
any).value)} disabled={!theContinent} value={theCountry?.code || ""}>
                   <option key="none" disabled selected value=""> Choose a 
country </option>
                   {countryList.map(prov => (
@@ -88,17 +84,17 @@ export function ContinentSelectionScreen(): VNode {
             </div>
           </div>
 
-          {theCountry && <div class="field">
+          {/* {theCountry && <div class="field">
             <label class="label">Available currencies:</label>
             <div class="control">
               <input class="input is-small" type="text" readonly 
value={theCountry.currency} />
             </div>
-          </div>}
+          </div>} */}
         </div>
-        <div class="column is-half">
+        <div class="column is-two-third">
           <p>
-            A location will help to define a common information that will be 
use to locate your secret and a currency
-            for payments if needed.
+            Your location will help us to determine which personal information 
+            ask you for the next step.
           </p>
         </div>
       </div>
diff --git 
a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx
deleted file mode 100644
index 3a642748..00000000
--- a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.stories.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2021 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 { createExample, reducerStatesExample } from '../../utils';
-import { CountrySelectionScreen as TestedComponent } from 
'./CountrySelectionScreen';
-
-
-export default {
-  title: 'Pages/CountrySelectionScreen',
-  component: TestedComponent,
-  args: {
-    order: 3,
-  },
-  argTypes: {
-    onUpdate: { action: 'onUpdate' },
-    onBack: { action: 'onBack' },
-  },
-};
-
-export const Backup = createExample(TestedComponent, 
reducerStatesExample.backupSelectCountry);
-export const Recovery = createExample(TestedComponent, 
reducerStatesExample.recoverySelectCountry);
diff --git a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx 
b/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx
deleted file mode 100644
index b64e1a09..00000000
--- a/packages/anastasis-webui/src/pages/home/CountrySelectionScreen.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-/* eslint-disable @typescript-eslint/camelcase */
-import { h, VNode } from "preact";
-import { useAnastasisContext } from "../../context/anastasis";
-import { AnastasisClientFrame, withProcessLabel } from "./index";
-
-export function CountrySelectionScreen(): VNode {
-  const reducer = useAnastasisContext()
-  if (!reducer) {
-    return <div>no reducer in context</div>
-  }
-  if (!reducer.currentReducerState || !("countries" in 
reducer.currentReducerState)) {
-    return <div>invalid state</div>
-  }
-  const sel = (x: any): void => reducer.transition("select_country", {
-    country_code: x.code,
-    currencies: [x.currency],
-  });
-  return (
-    <AnastasisClientFrame hideNext={"FIXME"} title={withProcessLabel(reducer, 
"Select Country")} >
-      <div style={{ display: 'flex', flexDirection: 'column' }}>
-        {reducer.currentReducerState.countries!.map((x: any) => (
-          <div key={x.name}>
-            <button class="button" onClick={() => sel(x)} >
-              {x.name} ({x.currency})
-            </button>
-          </div>
-        ))}
-      </div>
-    </AnastasisClientFrame>
-  );
-}
diff --git 
a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx
new file mode 100644
index 00000000..fc339e48
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx
@@ -0,0 +1,109 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 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 { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { EditPoliciesScreen as TestedComponent } from './EditPoliciesScreen';
+
+
+export default {
+  title: 'Pages/backup/ReviewPoliciesScreen/EditPoliciesScreen',
+  args: {
+    order: 6,
+  },
+  component: TestedComponent,
+  argTypes: {
+    onUpdate: { action: 'onUpdate' },
+    onBack: { action: 'onBack' },
+  },
+};
+
+export const EditingAPolicy = createExample(TestedComponent, {
+  ...reducerStatesExample.policyReview,
+  policies: [{
+    methods: [{
+      authentication_method: 1,
+      provider: 'https://anastasis.demo.taler.net/'
+    }, {
+      authentication_method: 2,
+      provider: 'http://localhost:8086/'
+    }]
+  }, {
+    methods: [{
+      authentication_method: 1,
+      provider: 'http://localhost:8086/'
+    }]
+  }],
+  authentication_methods: [{
+    type: "email",
+    instructions: "Email to qwe@asd.com",
+    challenge: "E5VPA"
+  }, {
+    type: "totp",
+    instructions: "Response code for 'Anastasis'",
+    challenge: "E5VPA"
+  }, {
+    type: "sms",
+    instructions: "SMS to 6666-6666",
+    challenge: ""
+  }, {
+    type: "question",
+    instructions: "How did the chicken cross the road?",
+    challenge: "C5SP8"
+  }]
+} as ReducerState, { index : 0});
+
+export const CreatingAPolicy = createExample(TestedComponent, {
+  ...reducerStatesExample.policyReview,
+  policies: [{
+    methods: [{
+      authentication_method: 1,
+      provider: 'https://anastasis.demo.taler.net/'
+    }, {
+      authentication_method: 2,
+      provider: 'http://localhost:8086/'
+    }]
+  }, {
+    methods: [{
+      authentication_method: 1,
+      provider: 'http://localhost:8086/'
+    }]
+  }],
+  authentication_methods: [{
+    type: "email",
+    instructions: "Email to qwe@asd.com",
+    challenge: "E5VPA"
+  }, {
+    type: "totp",
+    instructions: "Response code for 'Anastasis'",
+    challenge: "E5VPA"
+  }, {
+    type: "sms",
+    instructions: "SMS to 6666-6666",
+    challenge: ""
+  }, {
+    type: "question",
+    instructions: "How did the chicken cross the road?",
+    challenge: "C5SP8"
+  }]
+} as ReducerState, { index : 3});
+
diff --git a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx 
b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx
new file mode 100644
index 00000000..85cc96c4
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.tsx
@@ -0,0 +1,133 @@
+/* eslint-disable @typescript-eslint/camelcase */
+import { AuthMethod, Policy } from "anastasis-core";
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useAnastasisContext } from "../../context/anastasis";
+import { authMethods, KnownAuthMethods } from "./authMethod";
+import { AnastasisClientFrame } from "./index";
+
+export interface ProviderInfo {
+  url: string;
+  cost: string;
+  isFree: boolean;
+}
+
+export type ProviderInfoByType = {
+  [type in KnownAuthMethods]?: ProviderInfo[];
+};
+
+interface Props {
+  index: number;
+  cancel: () => void;
+  confirm: (changes: MethodProvider[]) => void;
+
+}
+
+export interface MethodProvider {
+  authentication_method: number;
+  provider: string;
+}
+
+export function EditPoliciesScreen({ index: policy_index, cancel, confirm }: 
Props): VNode {
+  const [changedProvider, setChangedProvider] = useState<Array<string>>([])
+
+  const reducer = useAnastasisContext()
+  if (!reducer) {
+    return <div>no reducer in context</div>
+  }
+  if (!reducer.currentReducerState || reducer.currentReducerState.backup_state 
=== undefined) {
+    return <div>invalid state</div>
+  }
+
+  const selectableProviders: ProviderInfoByType = {}
+  const allProviders = 
Object.entries(reducer.currentReducerState.authentication_providers || {})
+  for (let index = 0; index < allProviders.length; index++) {
+    const [url, status] = allProviders[index]
+    if ("methods" in status) {
+      status.methods.map(m => {
+        const type: KnownAuthMethods = m.type as KnownAuthMethods
+        const values = selectableProviders[type] || []
+        const isFree = !m.usage_fee || m.usage_fee.endsWith(":0")
+        values.push({ url, cost: m.usage_fee, isFree })
+        selectableProviders[type] = values
+      })
+    }
+  }
+
+  const allAuthMethods = reducer.currentReducerState.authentication_methods ?? 
[];
+  const policies = reducer.currentReducerState.policies ?? [];
+  const policy = policies[policy_index]
+  
+  for(let method_index = 0; method_index < allAuthMethods.length; 
method_index++ ) {
+    policy?.methods.find(m => m.authentication_method === 
method_index)?.provider
+  }
+
+  function sendChanges(): void {
+    const newMethods: MethodProvider[] = []
+    allAuthMethods.forEach((method, index) => {
+      const oldValue = policy?.methods.find(m => m.authentication_method === 
index)
+      if (changedProvider[index] === undefined && oldValue !== undefined) {
+        newMethods.push(oldValue)
+      }
+      if (changedProvider[index] !== undefined && changedProvider[index] !== 
"") {
+        newMethods.push({
+          authentication_method: index,
+          provider: changedProvider[index]
+        })
+      }
+    })
+    confirm(newMethods)
+  }
+
+  return <AnastasisClientFrame hideNav title={!policy ? "Backup: New Policy" : 
"Backup: Edit Policy"}>
+    <section class="section">
+      {!policy ? <p>
+        Creating a new policy #{policy_index}
+      </p> : <p>
+        Editing policy #{policy_index}
+      </p>}
+      {allAuthMethods.map((method, index) => {
+        //take the url from the updated change or from the policy
+        const providerURL = changedProvider[index] === undefined ? 
+          policy?.methods.find(m => m.authentication_method === 
index)?.provider : 
+          changedProvider[index];
+
+        const type: KnownAuthMethods = method.type as KnownAuthMethods
+        function changeProviderTo(url: string): void {
+          const copy = [...changedProvider]
+          copy[index] = url
+          setChangedProvider(copy)
+        }
+        return (
+          <div key={index} class="block" style={{ display: 'flex', alignItems: 
'center' }}>
+            <span class="icon">
+              {authMethods[type]?.icon}
+            </span>
+            <span>
+              {method.instructions}
+            </span>
+            <span>
+              <span class="select " >
+                <select onChange={(e) => 
changeProviderTo(e.currentTarget.value)} value={providerURL ?? ""}>
+                  <option key="none" value=""> &lt;&lt; off &gt;&gt; </option>
+                  {selectableProviders[type]?.map(prov => (
+                    <option key={prov.url} value={prov.url}>
+                      {prov.url}
+                    </option>
+                  ))}
+                </select>
+              </span>
+            </span>
+          </div>
+        );
+      })}
+      <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+        <button class="button" onClick={cancel}>Cancel</button>
+        <span class="buttons">
+          <button class="button" onClick={() => 
setChangedProvider([])}>Reset</button>
+          <button class="button is-info" onClick={sendChanges}>Confirm</button>
+        </span>
+      </div>
+    </section>
+  </AnastasisClientFrame>
+}
diff --git 
a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
index 5ba0c937..9f7e26c1 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx
@@ -233,16 +233,16 @@ export const SomePoliciesWithMethods = 
createExample(TestedComponent, {
     instructions: "Does P equal NP?",
     challenge: "C5SP8"
   },{
-    type: "email",
-    instructions: "Email to qwe@asd.com",
+    type: "totp",
+    instructions: "Response code for 'Anastasis'",
     challenge: "E5VPA"
   }, {
     type: "sms",
-    instructions: "SMS to 555-555",
+    instructions: "SMS to 6666-6666",
     challenge: ""
   }, {
     type: "question",
-    instructions: "Does P equal NP?",
+    instructions: "How did the chicken cross the road?",
     challenge: "C5SP8"
 }]
 } as ReducerState);
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx 
b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
index 673f215e..b8beb7b4 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
@@ -1,10 +1,14 @@
 /* eslint-disable @typescript-eslint/camelcase */
+import { AuthMethod } from "anastasis-core";
 import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
 import { useAnastasisContext } from "../../context/anastasis";
-import { AnastasisClientFrame } from "./index";
 import { authMethods, KnownAuthMethods } from "./authMethod";
+import { EditPoliciesScreen } from "./EditPoliciesScreen";
+import { AnastasisClientFrame } from "./index";
 
 export function ReviewPoliciesScreen(): VNode {
+  const [editingPolicy, setEditingPolicy] = useState<number | undefined>()
   const reducer = useAnastasisContext()
   if (!reducer) {
     return <div>no reducer in context</div>
@@ -12,20 +16,44 @@ export function ReviewPoliciesScreen(): VNode {
   if (!reducer.currentReducerState || reducer.currentReducerState.backup_state 
=== undefined) {
     return <div>invalid state</div>
   }
+
   const configuredAuthMethods = 
reducer.currentReducerState.authentication_methods ?? [];
   const policies = reducer.currentReducerState.policies ?? [];
 
+  if (editingPolicy !== undefined) {
+    return (
+      <EditPoliciesScreen
+        index={editingPolicy}
+        cancel={() => setEditingPolicy(undefined)}
+        confirm={(newMethods) => {
+          reducer.runTransaction(async (tx) => {
+            await tx.transition("delete_policy", {
+              policy_index: editingPolicy
+            });
+            await tx.transition("add_policy", {
+              policy: newMethods
+            });
+          });
+          setEditingPolicy(undefined)
+        }}
+      />
+    )
+  }
+
   const errors = policies.length < 1 ? 'Need more policies' : undefined
   return (
     <AnastasisClientFrame hideNext={errors} title="Backup: Review Recovery 
Policies">
       {policies.length > 0 && <p class="block">
         Based on your configured authentication method you have created, some 
policies
-        have been configured. In order to recover your secret you have to 
solve all the 
+        have been configured. In order to recover your secret you have to 
solve all the
         challenges of at least one policy.
-      </p> }
+      </p>}
       {policies.length < 1 && <p class="block">
         No policies had been created. Go back and add more authentication 
methods.
-      </p> }
+      </p>}
+      <div class="block" onClick={() => setEditingPolicy(policies.length + 1)}>
+        <button class="button is-success">Add new policy</button>
+      </div>
       {policies.map((p, policy_index) => {
         const methods = p.methods
           .map(x => configuredAuthMethods[x.authentication_method] && ({ 
...configuredAuthMethods[x.authentication_method], provider: x.provider }))
@@ -44,18 +72,21 @@ export function ReviewPoliciesScreen(): VNode {
               </p>}
               {methods.map((m, i) => {
                 return (
-                  <p key={i} class="block" style={{display:'flex', 
alignItems:'center'}}>
-                      <span class="icon">
-                        {authMethods[m.type as KnownAuthMethods]?.icon}
-                      </span>
-                      <span>
-                        {m.instructions} recovery provided by <a 
href={m.provider}>{m.provider}</a>
-                      </span>
-                    </p>
+                  <p key={i} class="block" style={{ display: 'flex', 
alignItems: 'center' }}>
+                    <span class="icon">
+                      {authMethods[m.type as KnownAuthMethods]?.icon}
+                    </span>
+                    <span>
+                      {m.instructions} recovery provided by <a 
href={m.provider}>{m.provider}</a>
+                    </span>
+                  </p>
                 );
               })}
             </div>
-            <div style={{ marginTop: 'auto', marginBottom: 'auto' }}><button 
class="button is-danger" onClick={() => reducer.transition("delete_policy", { 
policy_index })}>Delete</button></div>
+            <div style={{ marginTop: 'auto', marginBottom: 'auto', display: 
'flex', justifyContent: 'space-between', flexDirection: 'column' }}>
+              <button class="button is-info block" onClick={() => 
setEditingPolicy(policy_index)}>Edit</button>
+              <button class="button is-danger block" onClick={() => 
reducer.transition("delete_policy", { policy_index })}>Delete</button>
+            </div>
           </div>
         );
       })}
diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.tsx 
b/packages/anastasis-webui/src/pages/home/StartScreen.tsx
index c751ad9e..6e97eb58 100644
--- a/packages/anastasis-webui/src/pages/home/StartScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/StartScreen.tsx
@@ -10,33 +10,29 @@ export function StartScreen(): VNode {
   }
   return (
     <AnastasisClientFrame hideNav title="Home">
-      <div>
-        <section class="section is-main-section">
-          <div class="columns">
-            <div class="column" />
-            <div class="column is-four-fifths">
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
 
-              <div class="buttons">
-                <button class="button is-success" autoFocus onClick={() => 
reducer.startBackup()}>
-                  <div class="icon"><i class="mdi mdi-arrow-up" /></div>
-                  <span>Backup a secret</span>
-                </button>
+          <div class="buttons">
+            <button class="button is-success" autoFocus onClick={() => 
reducer.startBackup()}>
+              <div class="icon"><i class="mdi mdi-arrow-up" /></div>
+              <span>Backup a secret</span>
+            </button>
 
-                <button class="button is-info" onClick={() => 
reducer.startRecover()}>
-                  <div class="icon"><i class="mdi mdi-arrow-down" /></div>
-                  <span>Recover a secret</span>
-                </button>
+            <button class="button is-info" onClick={() => 
reducer.startRecover()}>
+              <div class="icon"><i class="mdi mdi-arrow-down" /></div>
+              <span>Recover a secret</span>
+            </button>
 
-                <button class="button">
-                  <div class="icon"><i class="mdi mdi-file" /></div>
-                  <span>Restore a session</span>
-                </button>
-              </div>
-
-            </div>
-            <div class="column" />
+            <button class="button">
+              <div class="icon"><i class="mdi mdi-file" /></div>
+              <span>Restore a session</span>
+            </button>
           </div>
-        </section>
+
+        </div>
+        <div class="column" />
       </div>
     </AnastasisClientFrame>
   );
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
index eab800e3..04fa00d5 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx
@@ -27,7 +27,7 @@ export function AuthMethodQuestionSetup({ cancel, 
addAuthMethod, configured }: A
     <AnastasisClientFrame hideNav title="Add Security Question">
       <div>
         <p>
-          For security question authentication, you need to provide a question
+          For2 security question authentication, you need to provide a question
           and its answer. When recovering your secret, you will be shown the
           question and you will need to type the answer exactly as you typed it
           here.
@@ -47,6 +47,13 @@ export function AuthMethodQuestionSetup({ cancel, 
addAuthMethod, configured }: A
           />
         </div>
 
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={cancel}>Cancel</button>
+          <span data-tooltip={errors}>
+            <button class="button is-info" disabled={errors !== undefined} 
onClick={addQuestionAuth}>Add</button>
+          </span>
+        </div>
+
         {configured.length > 0 && <section class="section">
           <div class="block">
             Your security questions:
@@ -58,12 +65,6 @@ export function AuthMethodQuestionSetup({ cancel, 
addAuthMethod, configured }: A
               </div>
             })}
           </div></section>}
-        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
-          <button class="button" onClick={cancel}>Cancel</button>
-          <span data-tooltip={errors}>
-            <button class="button is-info" disabled={errors !== undefined} 
onClick={addQuestionAuth}>Add</button>
-          </span>
-        </div>
       </div>
     </AnastasisClientFrame >
   );
diff --git a/packages/anastasis-webui/src/pages/home/index.tsx 
b/packages/anastasis-webui/src/pages/home/index.tsx
index fefaa184..415cf6e9 100644
--- a/packages/anastasis-webui/src/pages/home/index.tsx
+++ b/packages/anastasis-webui/src/pages/home/index.tsx
@@ -13,6 +13,7 @@ import {
 import {
   useErrorBoundary
 } from "preact/hooks";
+import { AsyncButton } from "../../components/AsyncButton";
 import { Menu } from "../../components/menu";
 import { AnastasisProvider, useAnastasisContext } from 
"../../context/anastasis";
 import {
@@ -25,7 +26,6 @@ import { BackupFinishedScreen } from "./BackupFinishedScreen";
 import { ChallengeOverviewScreen } from "./ChallengeOverviewScreen";
 import { ChallengePayingScreen } from "./ChallengePayingScreen";
 import { ContinentSelectionScreen } from "./ContinentSelectionScreen";
-import { CountrySelectionScreen } from "./CountrySelectionScreen";
 import { PoliciesPayingScreen } from "./PoliciesPayingScreen";
 import { RecoveryFinishedScreen } from "./RecoveryFinishedScreen";
 import { ReviewPoliciesScreen } from "./ReviewPoliciesScreen";
@@ -95,12 +95,19 @@ export function AnastasisClientFrame(props: 
AnastasisClientFrameProps): VNode {
   if (!reducer) {
     return <p>Fatal: Reducer must be in context.</p>;
   }
-  const next = (): void => {
-    if (props.onNext) {
-      props.onNext();
-    } else {
-      reducer.transition("next", {});
-    }
+  const next = async (): Promise<void> => {
+    return new Promise((res, rej) => {
+      try {
+        if (props.onNext) {
+          props.onNext();
+        } else {
+          reducer.transition("next", {});
+        }
+        res()
+      } catch {
+        rej()
+      }
+    })
   };
   const handleKeyPress = (
     e: h.JSX.TargetedKeyboardEvent<HTMLDivElement>,
@@ -111,20 +118,18 @@ export function AnastasisClientFrame(props: 
AnastasisClientFrameProps): VNode {
   return (
     <Fragment>
       <Menu title="Anastasis" />
-      <div>
-        <div class="home" onKeyPress={(e) => handleKeyPress(e)}>
-          <h1 class="title">{props.title}</h1>
+      <div class="home" onKeyPress={(e) => handleKeyPress(e)}>
+        <h1 class="title">{props.title}</h1>
+        <section class="section is-main-section">
           <ErrorBanner />
           {props.children}
           {!props.hideNav ? (
             <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
               <button class="button" onClick={() => 
reducer.back()}>Back</button>
-              <span data-tooltip={props.hideNext}>
-                <button class="button is-info" onClick={next} 
disabled={props.hideNext !== undefined}>Next</button>
-              </span>
+              <AsyncButton data-tooltip={props.hideNext} onClick={next} 
disabled={props.hideNext !== undefined}>Next</AsyncButton>
             </div>
           ) : null}
-        </div>
+        </section>
       </div>
     </Fragment>
   );
diff --git a/packages/anastasis-webui/src/scss/main.scss 
b/packages/anastasis-webui/src/scss/main.scss
index 1e0d3fde..b5335073 100644
--- a/packages/anastasis-webui/src/scss/main.scss
+++ b/packages/anastasis-webui/src/scss/main.scss
@@ -195,7 +195,7 @@ div[data-tooltip]::before {
   padding: 1em 1em;
   min-height: 100%;
   width: 100%;
-  max-width: 40em;
+  // max-width: 40em;
 }
 
 // .home div {
diff --git a/packages/anastasis-webui/src/utils/index.tsx 
b/packages/anastasis-webui/src/utils/index.tsx
index 48ac4754..244be8af 100644
--- a/packages/anastasis-webui/src/utils/index.tsx
+++ b/packages/anastasis-webui/src/utils/index.tsx
@@ -86,10 +86,10 @@ const base = {
         {
           type: "question",
           usage_fee: "COL:0"
-        },{
+        }, {
           type: "sms",
           usage_fee: "COL:0"
-        },{
+        }, {
           type: "email",
           usage_fee: "COL:0"
         },
@@ -98,6 +98,48 @@ const base = {
       storage_limit_in_megabytes: 16,
       truth_upload_fee: "COL:0"
     },
+    "https://kudos.demo.anastasis.lu/": {
+      http_status: 200,
+      annual_fee: "COL:0",
+      business_name: "ana",
+      currency: "COL",
+      liability_limit: "COL:10",
+      methods: [
+        {
+          type: "question",
+          usage_fee: "COL:0"
+        }, {
+          type: "email",
+          usage_fee: "COL:0"
+        },
+      ],
+      salt: "WBMDD76BR1E90YQ5AHBMKPH7GW",
+      storage_limit_in_megabytes: 16,
+      truth_upload_fee: "COL:0"
+    },
+    "https://anastasis.demo.taler.net/": {
+      http_status: 200,
+      annual_fee: "COL:0",
+      business_name: "ana",
+      currency: "COL",
+      liability_limit: "COL:10",
+      methods: [
+        {
+          type: "question",
+          usage_fee: "COL:0"
+        }, {
+          type: "sms",
+          usage_fee: "COL:0"
+        }, {
+          type: "totp",
+          usage_fee: "COL:0"
+        },
+      ],
+      salt: "WBMDD76BR1E90YQ5AHBMKPH7GW",
+      storage_limit_in_megabytes: 16,
+      truth_upload_fee: "COL:0"
+    },
+
     "http://localhost:8087/": {
       code: 8414,
       hint: "request to provider failed"
@@ -118,55 +160,72 @@ const base = {
 
 export const reducerStatesExample = {
   initial: undefined,
-  recoverySelectCountry: {...base,
+  recoverySelectCountry: {
+    ...base,
     recovery_state: RecoveryStates.CountrySelecting
   } as ReducerState,
-  recoverySelectContinent: {...base,
+  recoverySelectContinent: {
+    ...base,
     recovery_state: RecoveryStates.ContinentSelecting,
   } as ReducerState,
-  secretSelection: {...base,
+  secretSelection: {
+    ...base,
     recovery_state: RecoveryStates.SecretSelecting,
   } as ReducerState,
-  recoveryFinished: {...base,
+  recoveryFinished: {
+    ...base,
     recovery_state: RecoveryStates.RecoveryFinished,
   } as ReducerState,
-  challengeSelecting: {...base,
+  challengeSelecting: {
+    ...base,
     recovery_state: RecoveryStates.ChallengeSelecting,
   } as ReducerState,
-  challengeSolving: {...base,
+  challengeSolving: {
+    ...base,
     recovery_state: RecoveryStates.ChallengeSolving,
   } as ReducerState,
-  challengePaying: {...base,
+  challengePaying: {
+    ...base,
     recovery_state: RecoveryStates.ChallengePaying,
   } as ReducerState,
-  recoveryAttributeEditing: {...base,
+  recoveryAttributeEditing: {
+    ...base,
     recovery_state: RecoveryStates.UserAttributesCollecting
   } as ReducerState,
-  backupSelectCountry: {...base,
+  backupSelectCountry: {
+    ...base,
     backup_state: BackupStates.CountrySelecting
   } as ReducerState,
-  backupSelectContinent: {...base,
+  backupSelectContinent: {
+    ...base,
     backup_state: BackupStates.ContinentSelecting,
   } as ReducerState,
-  secretEdition: {...base,
+  secretEdition: {
+    ...base,
     backup_state: BackupStates.SecretEditing,
   } as ReducerState,
-  policyReview: {...base,
+  policyReview: {
+    ...base,
     backup_state: BackupStates.PoliciesReviewing,
   } as ReducerState,
-  policyPay: {...base,
+  policyPay: {
+    ...base,
     backup_state: BackupStates.PoliciesPaying,
   } as ReducerState,
-  backupFinished: {...base,
+  backupFinished: {
+    ...base,
     backup_state: BackupStates.BackupFinished,
   } as ReducerState,
-  authEditing: {...base,
+  authEditing: {
+    ...base,
     backup_state: BackupStates.AuthenticationsEditing
   } as ReducerState,
-  backupAttributeEditing: {...base,
+  backupAttributeEditing: {
+    ...base,
     backup_state: BackupStates.UserAttributesCollecting
   } as ReducerState,
-  truthsPaying: {...base,
+  truthsPaying: {
+    ...base,
     backup_state: BackupStates.TruthsPaying
   } as ReducerState,
 

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