gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant-backoffice] 01/02: format


From: gnunet
Subject: [taler-merchant-backoffice] 01/02: format
Date: Tue, 30 Nov 2021 20:21:48 +0100

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

sebasjm pushed a commit to branch master
in repository merchant-backoffice.

commit b56c499a55de0b54b3cf407bdc955abd51c36d16
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Nov 30 16:12:20 2021 -0300

    format
---
 .../src/components/form/InputPaytoForm.tsx         | 282 +++++++----
 .../instance/DefaultInstanceFormFields.tsx         | 135 ++++--
 packages/merchant-backoffice/src/i18n/index.tsx    |  54 ++-
 .../src/paths/admin/create/CreatePage.tsx          | 257 ++++++----
 .../src/paths/admin/create/index.tsx               |  56 ++-
 .../paths/instance/orders/create/CreatePage.tsx    | 539 +++++++++++++--------
 .../src/paths/instance/update/UpdatePage.tsx       | 288 ++++++-----
 .../src/paths/instance/update/index.tsx            |  85 ++--
 8 files changed, 1059 insertions(+), 637 deletions(-)

diff --git 
a/packages/merchant-backoffice/src/components/form/InputPaytoForm.tsx 
b/packages/merchant-backoffice/src/components/form/InputPaytoForm.tsx
index c52dc33..02436a3 100644
--- a/packages/merchant-backoffice/src/components/form/InputPaytoForm.tsx
+++ b/packages/merchant-backoffice/src/components/form/InputPaytoForm.tsx
@@ -15,9 +15,9 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 import { h, VNode, Fragment } from "preact";
 import { useCallback, useState } from "preact/hooks";
 import { Translate, useTranslator } from "../../i18n";
@@ -33,135 +33,231 @@ export interface Props<T> extends InputProps<T> {
 
 // https://datatracker.ietf.org/doc/html/rfc8905
 type Entity = {
-  target: string,
-  path: string,
-  path1: string,
-  path2: string,
-  host: string,
-  account: string,
+  target: string;
+  path: string;
+  path1: string;
+  path2: string;
+  host: string;
+  account: string;
   options: {
-    'receiver-name'?: string,
-    sender?: string,
-    message?: string,
-    amount?: string,
-    instruction?: string,
-    [name: string]: string | undefined,
-  },
-}
+    "receiver-name"?: string;
+    sender?: string;
+    message?: string;
+    amount?: string;
+    instruction?: string;
+    [name: string]: string | undefined;
+  };
+};
 
 // const targets = ['ach', 'bic', 'iban', 'upi', 'bitcoin', 'ilp', 'void', 
'x-taler-bank']
-const targets = ['iban', 'x-taler-bank']
-const defaultTarget = { target: 'iban', options: {} }
+const targets = ["iban", "x-taler-bank"];
+const defaultTarget = { target: "iban", options: {} };
 
 function undefinedIfEmpty<T>(obj: T): T | undefined {
-  return Object.keys(obj).some(k => (obj as any)[k] !== undefined) ? obj : 
undefined
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
 }
 
-export function InputPaytoForm<T>({ name, readonly, label, tooltip }: 
Props<keyof T>): VNode {
-  const { value: paytos, onChange, } = useField<T>(name);
+export function InputPaytoForm<T>({
+  name,
+  readonly,
+  label,
+  tooltip,
+}: Props<keyof T>): VNode {
+  const { value: paytos, onChange } = useField<T>(name);
 
-  const [value, valueHandler] = useState<Partial<Entity>>(defaultTarget)
+  const [value, valueHandler] = useState<Partial<Entity>>(defaultTarget);
 
   if (value.path1) {
     if (value.path2) {
-      value.path = `/${value.path1}/${value.path2}`
+      value.path = `/${value.path1}/${value.path2}`;
     } else {
-      value.path = `/${value.path1}`
+      value.path = `/${value.path1}`;
     }
   }
-  const i18n = useTranslator()
+  const i18n = useTranslator();
 
-  const url = new URL(`payto://${value.target}${value.path}`)
-  const ops = value.options!
-  Object.keys(ops).forEach(opt_key => {
-    const opt_value = ops[opt_key]
-    if (opt_value) url.searchParams.set(opt_key, opt_value)
-  })
-  const paytoURL = url.toString()
+  const url = new URL(`payto://${value.target}${value.path}`);
+  const ops = value.options!;
+  Object.keys(ops).forEach((opt_key) => {
+    const opt_value = ops[opt_key];
+    if (opt_value) url.searchParams.set(opt_key, opt_value);
+  });
+  const paytoURL = url.toString();
 
   const errors: FormErrors<Entity> = {
     target: !value.target ? i18n`required` : undefined,
-    path1: !value.path1 ? i18n`required` : (
-      value.target === 'iban' ? (
-        value.path1.length < 4 ? i18n`IBAN numbers usually have more that 4 
digits` : (
-          value.path1.length > 34 ? i18n`IBAN numbers usually have less that 
34 digits` :
-          undefined
-        )
-      ): undefined 
-    ),
-    path2: value.target === 'x-taler-bank' ? (!value.path2 ? i18n`required` : 
undefined) : undefined,
+    path1: !value.path1
+      ? i18n`required`
+      : value.target === "iban"
+      ? value.path1.length < 4
+        ? i18n`IBAN numbers usually have more that 4 digits`
+        : value.path1.length > 34
+        ? i18n`IBAN numbers usually have less that 34 digits`
+        : undefined
+      : undefined,
+    path2:
+      value.target === "x-taler-bank"
+        ? !value.path2
+          ? i18n`required`
+          : undefined
+        : undefined,
     options: undefinedIfEmpty({
-      'receiver-name': !value.options?.["receiver-name"] ? i18n`required` : 
undefined,
-    })
-  }
+      "receiver-name": !value.options?.["receiver-name"]
+        ? i18n`required`
+        : undefined,
+    }),
+  };
 
-  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
 
   const submit = useCallback((): void => {
-    const alreadyExists = paytos.findIndex((x:string) => x === paytoURL) !== 
-1;
+    const alreadyExists =
+      paytos.findIndex((x: string) => x === paytoURL) !== -1;
     if (!alreadyExists) {
-      onChange([paytoURL, ...paytos] as any)
+      onChange([paytoURL, ...paytos] as any);
     }
-    valueHandler(defaultTarget)
-  }, [value])
-
+    valueHandler(defaultTarget);
+  }, [value]);
 
   //FIXME: translating plural singular
   return (
     <InputGroup name="payto" label={label} fixed tooltip={tooltip}>
-      <FormProvider<Entity> name="tax" errors={errors} object={value} 
valueHandler={valueHandler} >
-
-        <InputSelector<Entity> name="target" label={i18n`Target type`} 
tooltip={i18n`Method to use for wire transfer`} values={targets} />
-
-        {value.target === 'ach' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Routing`} 
tooltip={i18n`Routing number.`} />
-          <Input<Entity> name="path2" label={i18n`Account`} 
tooltip={i18n`Account number.`} />
-        </Fragment>}
-        {value.target === 'bic' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Code`} 
tooltip={i18n`Business Identifier Code.`} />
-        </Fragment>}
-        {value.target === 'iban' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Account`} tooltip={i18n`Bank 
Account Number.`} />
-        </Fragment>}
-        {value.target === 'upi' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Account`} 
tooltip={i18n`Unified Payment Interface.`} />
-        </Fragment>}
-        {value.target === 'bitcoin' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Address`} 
tooltip={i18n`Bitcoin protocol.`} />
-        </Fragment>}
-        {value.target === 'ilp' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Address`} 
tooltip={i18n`Interledger protocol.`} />
-        </Fragment>}
-        {value.target === 'void' && <Fragment>
-        </Fragment>}
-        {value.target === 'x-taler-bank' && <Fragment>
-          <Input<Entity> name="path1" label={i18n`Host`} tooltip={i18n`Bank 
host.`} />
-          <Input<Entity> name="path2" label={i18n`Account`} tooltip={i18n`Bank 
account.`} />
-        </Fragment>}
-
-        <Input name="options.receiver-name" label={i18n`Name`} 
tooltip={i18n`Bank account owner's name.`} />
+      <FormProvider<Entity>
+        name="tax"
+        errors={errors}
+        object={value}
+        valueHandler={valueHandler}
+      >
+        <InputSelector<Entity>
+          name="target"
+          label={i18n`Target type`}
+          tooltip={i18n`Method to use for wire transfer`}
+          values={targets}
+        />
+
+        {value.target === "ach" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Routing`}
+              tooltip={i18n`Routing number.`}
+            />
+            <Input<Entity>
+              name="path2"
+              label={i18n`Account`}
+              tooltip={i18n`Account number.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "bic" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Code`}
+              tooltip={i18n`Business Identifier Code.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "iban" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Account`}
+              tooltip={i18n`Bank Account Number.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "upi" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Account`}
+              tooltip={i18n`Unified Payment Interface.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "bitcoin" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Address`}
+              tooltip={i18n`Bitcoin protocol.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "ilp" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Address`}
+              tooltip={i18n`Interledger protocol.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "void" && <Fragment></Fragment>}
+        {value.target === "x-taler-bank" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Host`}
+              tooltip={i18n`Bank host.`}
+            />
+            <Input<Entity>
+              name="path2"
+              label={i18n`Account`}
+              tooltip={i18n`Bank account.`}
+            />
+          </Fragment>
+        )}
+
+        <Input
+          name="options.receiver-name"
+          label={i18n`Name`}
+          tooltip={i18n`Bank account owner's name.`}
+        />
 
         <div class="field is-horizontal">
           <div class="field-label is-normal" />
-          <div class="field-body" style={{ display: 'block' }}>
-            {paytos.map((v: any, i: number) => <div key={i} class="tags 
has-addons mt-3 mb-0 mr-3" style={{ flexWrap: 'nowrap' }}>
-              <span class="tag is-medium is-info mb-0" style={{ maxWidth: 
'90%' }}>{v}</span>
-              <a class="tag is-medium is-danger is-delete mb-0" onClick={() => 
{
-                onChange(paytos.filter((f: any) => f !== v) as any);
-              }} />
-            </div>
-            )}
+          <div class="field-body" style={{ display: "block" }}>
+            {paytos.map((v: any, i: number) => (
+              <div
+                key={i}
+                class="tags has-addons mt-3 mb-0 mr-3"
+                style={{ flexWrap: "nowrap" }}
+              >
+                <span
+                  class="tag is-medium is-info mb-0"
+                  style={{ maxWidth: "90%" }}
+                >
+                  {v}
+                </span>
+                <a
+                  class="tag is-medium is-danger is-delete mb-0"
+                  onClick={() => {
+                    onChange(paytos.filter((f: any) => f !== v) as any);
+                  }}
+                />
+              </div>
+            ))}
             {!paytos.length && i18n`No accounts yet.`}
           </div>
         </div>
 
         <div class="buttons is-right mt-5">
-          <button class="button is-info"
+          <button
+            class="button is-info"
             data-tooltip={i18n`add tax to the tax list`}
             disabled={hasErrors}
-            onClick={submit}><Translate>Add</Translate></button>
+            onClick={submit}
+          >
+            <Translate>Add</Translate>
+          </button>
         </div>
       </FormProvider>
     </InputGroup>
-  )
+  );
 }
diff --git 
a/packages/merchant-backoffice/src/components/instance/DefaultInstanceFormFields.tsx
 
b/packages/merchant-backoffice/src/components/instance/DefaultInstanceFormFields.tsx
index fae8a35..5a8e1d1 100644
--- 
a/packages/merchant-backoffice/src/components/instance/DefaultInstanceFormFields.tsx
+++ 
b/packages/merchant-backoffice/src/components/instance/DefaultInstanceFormFields.tsx
@@ -15,9 +15,9 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import { Fragment, h } from "preact";
 import { useBackendContext } from "../../context/backend";
@@ -31,56 +31,85 @@ import { InputLocation } from "../form/InputLocation";
 import { InputPaytoForm } from "../form/InputPaytoForm";
 import { InputWithAddon } from "../form/InputWithAddon";
 
-export function DefaultInstanceFormFields({ readonlyId, showId }: { 
readonlyId?: boolean; showId: boolean }) {
+export function DefaultInstanceFormFields({
+  readonlyId,
+  showId,
+}: {
+  readonlyId?: boolean;
+  showId: boolean;
+}) {
   const i18n = useTranslator();
   const backend = useBackendContext();
-  return <Fragment>
-    {showId && <InputWithAddon<Entity> name="id"
-      addonBefore={`${backend.url}/instances/`} readonly={readonlyId}
-      label={i18n`Identifier`}
-      tooltip={i18n`Name of the instance in URLs. The 'default' instance is 
special in that it is used to administer other instances.`} />
-    }
-
-    <Input<Entity> name="name"
-      label={i18n`Business name`}
-      tooltip={i18n`Legal name of the business represented by this instance.`} 
/>
-
-    <InputPaytoForm<Entity> name="payto_uris"
-      label={i18n`Bank account`} 
-      tooltip={i18n`URI specifying bank account for crediting revenue.`} />
-
-    <InputCurrency<Entity> name="default_max_deposit_fee"
-      label={i18n`Default max deposit fee`}
-      tooltip={i18n`Maximum deposit fees this merchant is willing to pay per 
order by default.`} />
-
-    <InputCurrency<Entity> name="default_max_wire_fee"
-      label={i18n`Default max wire fee`}
-      tooltip={i18n`Maximum wire fees this merchant is willing to pay per wire 
transfer by default.`} />
-
-    <Input<Entity> name="default_wire_fee_amortization"
-      label={i18n`Default wire fee amortization`}
-      tooltip={i18n`Number of orders excess wire transfer fees will be divided 
by to compute per order surcharge.`} />
-
-    <InputGroup name="address"
-      label={i18n`Address`}
-      tooltip={i18n`Physical location of the merchant.`}>
-      <InputLocation name="address" />
-    </InputGroup>
-
-    <InputGroup name="jurisdiction"
-      label={i18n`Jurisdiction`}
-      tooltip={i18n`Jurisdiction for legal disputes with the merchant.`}>
-      <InputLocation name="jurisdiction" />
-    </InputGroup>
-
-    <InputDuration<Entity> name="default_pay_delay"
-      label={i18n`Default payment delay`}
-      withForever
-      tooltip={i18n`Time customers have to pay an order before the offer 
expires by default.`} />
-
-    <InputDuration<Entity> name="default_wire_transfer_delay"
-      label={i18n`Default wire transfer delay`}
-      tooltip={i18n`Maximum time an exchange is allowed to delay wiring funds 
to the merchant, enabling it to aggregate smaller payments into larger wire 
transfers and reducing wire fees.`} />
-
-  </Fragment>;
+  return (
+    <Fragment>
+      {showId && (
+        <InputWithAddon<Entity>
+          name="id"
+          addonBefore={`${backend.url}/instances/`}
+          readonly={readonlyId}
+          label={i18n`Identifier`}
+          tooltip={i18n`Name of the instance in URLs. The 'default' instance 
is special in that it is used to administer other instances.`}
+        />
+      )}
+
+      <Input<Entity>
+        name="name"
+        label={i18n`Business name`}
+        tooltip={i18n`Legal name of the business represented by this 
instance.`}
+      />
+
+      <InputPaytoForm<Entity>
+        name="payto_uris"
+        label={i18n`Bank account`}
+        tooltip={i18n`URI specifying bank account for crediting revenue.`}
+      />
+
+      <InputCurrency<Entity>
+        name="default_max_deposit_fee"
+        label={i18n`Default max deposit fee`}
+        tooltip={i18n`Maximum deposit fees this merchant is willing to pay per 
order by default.`}
+      />
+
+      <InputCurrency<Entity>
+        name="default_max_wire_fee"
+        label={i18n`Default max wire fee`}
+        tooltip={i18n`Maximum wire fees this merchant is willing to pay per 
wire transfer by default.`}
+      />
+
+      <Input<Entity>
+        name="default_wire_fee_amortization"
+        label={i18n`Default wire fee amortization`}
+        tooltip={i18n`Number of orders excess wire transfer fees will be 
divided by to compute per order surcharge.`}
+      />
+
+      <InputGroup
+        name="address"
+        label={i18n`Address`}
+        tooltip={i18n`Physical location of the merchant.`}
+      >
+        <InputLocation name="address" />
+      </InputGroup>
+
+      <InputGroup
+        name="jurisdiction"
+        label={i18n`Jurisdiction`}
+        tooltip={i18n`Jurisdiction for legal disputes with the merchant.`}
+      >
+        <InputLocation name="jurisdiction" />
+      </InputGroup>
+
+      <InputDuration<Entity>
+        name="default_pay_delay"
+        label={i18n`Default payment delay`}
+        withForever
+        tooltip={i18n`Time customers have to pay an order before the offer 
expires by default.`}
+      />
+
+      <InputDuration<Entity>
+        name="default_wire_transfer_delay"
+        label={i18n`Default wire transfer delay`}
+        tooltip={i18n`Maximum time an exchange is allowed to delay wiring 
funds to the merchant, enabling it to aggregate smaller payments into larger 
wire transfers and reducing wire fees.`}
+      />
+    </Fragment>
+  );
 }
diff --git a/packages/merchant-backoffice/src/i18n/index.tsx 
b/packages/merchant-backoffice/src/i18n/index.tsx
index 63c8e19..f89ab31 100644
--- a/packages/merchant-backoffice/src/i18n/index.tsx
+++ b/packages/merchant-backoffice/src/i18n/index.tsx
@@ -27,23 +27,25 @@ import { useTranslationContext } from 
"../context/translation";
 
 export function useTranslator() {
   const ctx = useTranslationContext();
-  const jed = ctx.handler
-  return function str(stringSeq: TemplateStringsArray, ...values: any[]): 
string {
+  const jed = ctx.handler;
+  return function str(
+    stringSeq: TemplateStringsArray,
+    ...values: any[]
+  ): string {
     const s = toI18nString(stringSeq);
-    if (!s) return s
+    if (!s) return s;
     const tr = jed
       .translate(s)
       .ifPlural(1, s)
       .fetch(...values);
     return tr;
-  }
+  };
 }
 
-
 /**
  * Convert template strings to a msgid
  */
- function toI18nString(stringSeq: ReadonlyArray<string>): string {
+function toI18nString(stringSeq: ReadonlyArray<string>): string {
   let s = "";
   for (let i = 0; i < stringSeq.length; i++) {
     s += stringSeq[i];
@@ -54,7 +56,6 @@ export function useTranslator() {
   return s;
 }
 
-
 interface TranslateSwitchProps {
   target: number;
   children: ComponentChildren;
@@ -88,7 +89,7 @@ interface TranslateProps {
 
 function getTranslatedChildren(
   translation: string,
-  children: ComponentChildren,
+  children: ComponentChildren
 ): ComponentChild[] {
   const tr = translation.split(/%(\d+)\$s/);
   const childArray = children instanceof Array ? children : [children];
@@ -110,7 +111,7 @@ function getTranslatedChildren(
       // Text
       result.push(tr[i]);
     } else {
-      const childIdx = Number.parseInt(tr[i],10) - 1;
+      const childIdx = Number.parseInt(tr[i], 10) - 1;
       result.push(placeholderChildren[childIdx]);
     }
   }
@@ -131,9 +132,9 @@ function getTranslatedChildren(
  */
 export function Translate({ children }: TranslateProps): VNode {
   const s = stringifyChildren(children);
-  const ctx = useTranslationContext()
+  const ctx = useTranslationContext();
   const translation: string = ctx.handler.ngettext(s, s, 1);
-  const result = getTranslatedChildren(translation, children)
+  const result = getTranslatedChildren(translation, children);
   return <Fragment>{result}</Fragment>;
 }
 
@@ -154,14 +155,16 @@ export function TranslateSwitch({ children, target }: 
TranslateSwitchProps) {
   let plural: VNode<TranslationPluralProps> | undefined;
   // const children = this.props.children;
   if (children) {
-    (children instanceof Array ? children : [children]).forEach((child: any) 
=> {
-      if (child.type === TranslatePlural) {
-        plural = child;
+    (children instanceof Array ? children : [children]).forEach(
+      (child: any) => {
+        if (child.type === TranslatePlural) {
+          plural = child;
+        }
+        if (child.type === TranslateSingular) {
+          singular = child;
+        }
       }
-      if (child.type === TranslateSingular) {
-        singular = child;
-      }
-    });
+    );
   }
   if (!singular || !plural) {
     console.error("translation not found");
@@ -182,9 +185,12 @@ interface TranslationPluralProps {
 /**
  * See [[TranslateSwitch]].
  */
-export function TranslatePlural({ children, target }: TranslationPluralProps): 
VNode {
+export function TranslatePlural({
+  children,
+  target,
+}: TranslationPluralProps): VNode {
   const s = stringifyChildren(children);
-  const ctx = useTranslationContext()
+  const ctx = useTranslationContext();
   const translation = ctx.handler.ngettext(s, s, 1);
   const result = getTranslatedChildren(translation, children);
   return <Fragment>{result}</Fragment>;
@@ -193,11 +199,13 @@ export function TranslatePlural({ children, target }: 
TranslationPluralProps): V
 /**
  * See [[TranslateSwitch]].
  */
-export function TranslateSingular({ children, target }: 
TranslationPluralProps): VNode {
+export function TranslateSingular({
+  children,
+  target,
+}: TranslationPluralProps): VNode {
   const s = stringifyChildren(children);
-  const ctx = useTranslationContext()
+  const ctx = useTranslationContext();
   const translation = ctx.handler.ngettext(s, s, target);
   const result = getTranslatedChildren(translation, children);
   return <Fragment>{result}</Fragment>;
-
 }
diff --git a/packages/merchant-backoffice/src/paths/admin/create/CreatePage.tsx 
b/packages/merchant-backoffice/src/paths/admin/create/CreatePage.tsx
index f5fa7c9..f1214c9 100644
--- a/packages/merchant-backoffice/src/paths/admin/create/CreatePage.tsx
+++ b/packages/merchant-backoffice/src/paths/admin/create/CreatePage.tsx
@@ -15,15 +15,18 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
-import * as yup from 'yup';
+import * as yup from "yup";
 import { AsyncButton } from "../../../components/exception/AsyncButton";
-import { FormErrors, FormProvider } from 
"../../../components/form/FormProvider";
+import {
+  FormErrors,
+  FormProvider,
+} from "../../../components/form/FormProvider";
 import { SetTokenNewInstanceModal } from "../../../components/modal";
 import { MerchantBackend } from "../../../declaration";
 import { Translate, useTranslator } from "../../../i18n";
@@ -31,10 +34,9 @@ import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultI
 import { INSTANCE_ID_REGEX, PAYTO_REGEX } from "../../../utils/constants";
 import { Amounts } from "@gnu-taler/taler-util";
 
-export type Entity = MerchantBackend.Instances.InstanceConfigurationMessage & 
{ 
-  auth_token?: string 
-}
-
+export type Entity = MerchantBackend.Instances.InstanceConfigurationMessage & {
+  auth_token?: string;
+};
 
 interface Props {
   onCreate: (d: Entity) => Promise<void>;
@@ -53,137 +55,180 @@ function with_defaults(id?: string): Partial<Entity> {
 }
 
 function undefinedIfEmpty<T>(obj: T): T | undefined {
-  return Object.keys(obj).some(k => (obj as any)[k] !== undefined) ? obj : 
undefined
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
 }
 
 export function CreatePage({ onCreate, onBack, forceId }: Props): VNode {
-  const [value, valueHandler] = useState(with_defaults(forceId))
+  const [value, valueHandler] = useState(with_defaults(forceId));
   const [isTokenSet, updateIsTokenSet] = useState<boolean>(false);
-  const [isTokenDialogActive, updateIsTokenDialogActive] = 
useState<boolean>(false);
+  const [isTokenDialogActive, updateIsTokenDialogActive] =
+    useState<boolean>(false);
 
-  const i18n = useTranslator()
+  const i18n = useTranslator();
 
   const errors: FormErrors<Entity> = {
-    id: !value.id ? i18n`required` : (!INSTANCE_ID_REGEX.test(value.id) ? 
i18n`is not valid` : undefined),
+    id: !value.id
+      ? i18n`required`
+      : !INSTANCE_ID_REGEX.test(value.id)
+      ? i18n`is not valid`
+      : undefined,
     name: !value.name ? i18n`required` : undefined,
     payto_uris:
-      !value.payto_uris || !value.payto_uris.length ? i18n`required` : (
-        undefinedIfEmpty(value.payto_uris.map(p => {
-          return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined
-        }))
-      ),
-    default_max_deposit_fee:
-      !value.default_max_deposit_fee ? i18n`required` : (
-        !Amounts.parse(value.default_max_deposit_fee) ? i18n`invalid format` :
-          undefined
-      ),
-    default_max_wire_fee:
-      !value.default_max_wire_fee ? i18n`required` : (
-        !Amounts.parse(value.default_max_wire_fee) ? i18n`invalid format` :
-          undefined
-      ),
+      !value.payto_uris || !value.payto_uris.length
+        ? i18n`required`
+        : undefinedIfEmpty(
+            value.payto_uris.map((p) => {
+              return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined;
+            })
+          ),
+    default_max_deposit_fee: !value.default_max_deposit_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_deposit_fee)
+      ? i18n`invalid format`
+      : undefined,
+    default_max_wire_fee: !value.default_max_wire_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_wire_fee)
+      ? i18n`invalid format`
+      : undefined,
     default_wire_fee_amortization:
-      value.default_wire_fee_amortization === undefined ? i18n`required` : (
-        isNaN(value.default_wire_fee_amortization) ? i18n`is not a number` : (
-          value.default_wire_fee_amortization < 1 ? i18n`must be 1 or greater` 
:
-            undefined
-        )
-      ),
-    default_pay_delay:
-      !value.default_pay_delay ? i18n`required` : undefined,
-    default_wire_transfer_delay:
-      !value.default_wire_transfer_delay ? i18n`required` : undefined,
+      value.default_wire_fee_amortization === undefined
+        ? i18n`required`
+        : isNaN(value.default_wire_fee_amortization)
+        ? i18n`is not a number`
+        : value.default_wire_fee_amortization < 1
+        ? i18n`must be 1 or greater`
+        : undefined,
+    default_pay_delay: !value.default_pay_delay ? i18n`required` : undefined,
+    default_wire_transfer_delay: !value.default_wire_transfer_delay
+      ? i18n`required`
+      : undefined,
     address: undefinedIfEmpty({
       address_lines:
-        value.address?.address_lines && value.address?.address_lines.length > 
7 ? i18n`max 7 lines` :
-          undefined
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
     }),
     jurisdiction: undefinedIfEmpty({
-      address_lines: value.address?.address_lines && 
value.address?.address_lines.length > 7 ? i18n`max 7 lines` :
-        undefined
+      address_lines:
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
     }),
   };
 
-  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
 
   const submit = (): Promise<void> => {
     // use conversion instead of this
     const newToken = value.auth_token;
     value.auth_token = undefined;
-    value.auth = newToken === null || newToken === undefined ? { method: 
"external" } : { method: "token", token: `secret-token:${newToken}` };
-    if (!value.address) value.address = {}
-    if (!value.jurisdiction) value.jurisdiction = {}
+    value.auth =
+      newToken === null || newToken === undefined
+        ? { method: "external" }
+        : { method: "token", token: `secret-token:${newToken}` };
+    if (!value.address) value.address = {};
+    if (!value.jurisdiction) value.jurisdiction = {};
     // remove above use conversion
     // schema.validateSync(value, { abortEarly: false })
     return onCreate(value as Entity);
-  }
+  };
 
   function updateToken(token: string | null) {
-    valueHandler(old => ({ ...old, auth_token: token === null ? undefined : 
token }))
+    valueHandler((old) => ({
+      ...old,
+      auth_token: token === null ? undefined : token,
+    }));
   }
 
-  return <div>
-    <div class="columns">
-      <div class="column" />
-      <div class="column is-four-fifths">
-        {isTokenDialogActive && <SetTokenNewInstanceModal
-          onCancel={() => {
-            updateIsTokenDialogActive(false);
-            updateIsTokenSet(false);
-          }}
-          onClear={() => {
-            updateToken(null);
-            updateIsTokenDialogActive(false);
-            updateIsTokenSet(true);
-          }}
-          onConfirm={(newToken) => {
-            updateToken(newToken); updateIsTokenDialogActive(false);
-            updateIsTokenSet(true);
-          }}
-        />}
-      </div>
-      <div class="column" />
-    </div>
-
-    <section class="hero is-hero-bar">
-      <div class="hero-body">
-        <div class="level">
-          <div class="level-item has-text-centered">
-            <h1 class="title">
-              <button class="button is-danger has-tooltip-bottom"
-                data-tooltip={i18n`change authorization configuration`}
-                onClick={() => updateIsTokenDialogActive(true)} >
-                <div class="icon is-centered"><i class="mdi mdi-lock-reset" 
/></div>
-                <span><Translate>Set access token</Translate></span>
-              </button>
-            </h1>
-          </div>
-        </div>
-      </div></section>
-
-
-    <section class="section is-main-section">
+  return (
+    <div>
       <div class="columns">
         <div class="column" />
         <div class="column is-four-fifths">
-
-          <FormProvider<Entity> errors={errors} object={value} 
valueHandler={valueHandler} >
-
-            <DefaultInstanceFormFields readonlyId={!!forceId} showId={true} />
-
-          </FormProvider>
-
-          <div class="buttons is-right mt-5">
-            {onBack && <button class="button" 
onClick={onBack}><Translate>Cancel</Translate></button>}
-            <AsyncButton onClick={submit} disabled={!isTokenSet || hasErrors} 
data-tooltip={
-              hasErrors ? i18n`Need to complete marked fields and choose 
authorization method` : 'confirm operation'
-            }><Translate>Confirm</Translate></AsyncButton>
-          </div>
-
+          {isTokenDialogActive && (
+            <SetTokenNewInstanceModal
+              onCancel={() => {
+                updateIsTokenDialogActive(false);
+                updateIsTokenSet(false);
+              }}
+              onClear={() => {
+                updateToken(null);
+                updateIsTokenDialogActive(false);
+                updateIsTokenSet(true);
+              }}
+              onConfirm={(newToken) => {
+                updateToken(newToken);
+                updateIsTokenDialogActive(false);
+                updateIsTokenSet(true);
+              }}
+            />
+          )}
         </div>
         <div class="column" />
       </div>
-    </section>
 
-  </div>
+      <section class="hero is-hero-bar">
+        <div class="hero-body">
+          <div class="level">
+            <div class="level-item has-text-centered">
+              <h1 class="title">
+                <button
+                  class="button is-danger has-tooltip-bottom"
+                  data-tooltip={i18n`change authorization configuration`}
+                  onClick={() => updateIsTokenDialogActive(true)}
+                >
+                  <div class="icon is-centered">
+                    <i class="mdi mdi-lock-reset" />
+                  </div>
+                  <span>
+                    <Translate>Set access token</Translate>
+                  </span>
+                </button>
+              </h1>
+            </div>
+          </div>
+        </div>
+      </section>
+
+      <section class="section is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            <FormProvider<Entity>
+              errors={errors}
+              object={value}
+              valueHandler={valueHandler}
+            >
+              <DefaultInstanceFormFields readonlyId={!!forceId} showId={true} 
/>
+            </FormProvider>
+
+            <div class="buttons is-right mt-5">
+              {onBack && (
+                <button class="button" onClick={onBack}>
+                  <Translate>Cancel</Translate>
+                </button>
+              )}
+              <AsyncButton
+                onClick={submit}
+                disabled={!isTokenSet || hasErrors}
+                data-tooltip={
+                  hasErrors
+                    ? i18n`Need to complete marked fields and choose 
authorization method`
+                    : "confirm operation"
+                }
+              >
+                <Translate>Confirm</Translate>
+              </AsyncButton>
+            </div>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
 }
diff --git a/packages/merchant-backoffice/src/paths/admin/create/index.tsx 
b/packages/merchant-backoffice/src/paths/admin/create/index.tsx
index e240bb6..3f31b3d 100644
--- a/packages/merchant-backoffice/src/paths/admin/create/index.tsx
+++ b/packages/merchant-backoffice/src/paths/admin/create/index.tsx
@@ -14,9 +14,9 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 import { Fragment, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { NotificationCard } from "../../../components/menu";
@@ -36,31 +36,39 @@ export type Entity = 
MerchantBackend.Instances.InstanceConfigurationMessage;
 
 export default function Create({ onBack, onConfirm, forceId }: Props): VNode {
   const { createInstance } = useAdminAPI();
-  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+  const [notif, setNotif] = useState<Notification | undefined>(undefined);
   const [createdOk, setCreatedOk] = useState<Entity | undefined>(undefined);
-  const i18n = useTranslator()
+  const i18n = useTranslator();
 
   if (createdOk) {
-    return <InstanceCreatedSuccessfully entity={createdOk} 
onConfirm={onConfirm} />
+    return (
+      <InstanceCreatedSuccessfully entity={createdOk} onConfirm={onConfirm} />
+    );
   }
 
-  return <Fragment>
-    <NotificationCard notification={notif} />
-
-    <CreatePage
-      onBack={onBack}
-      forceId={forceId}
-      onCreate={(d: MerchantBackend.Instances.InstanceConfigurationMessage) => 
{
-        return createInstance(d).then(() => {
-          setCreatedOk(d)
-        }).catch((error) => {
-          setNotif({
-            message: i18n`Failed to create instance`,
-            type: "ERROR",
-            description: error.message
-          })
-        })
-      }} />
-  </Fragment>
+  return (
+    <Fragment>
+      <NotificationCard notification={notif} />
 
+      <CreatePage
+        onBack={onBack}
+        forceId={forceId}
+        onCreate={(
+          d: MerchantBackend.Instances.InstanceConfigurationMessage
+        ) => {
+          return createInstance(d)
+            .then(() => {
+              setCreatedOk(d);
+            })
+            .catch((error) => {
+              setNotif({
+                message: i18n`Failed to create instance`,
+                type: "ERROR",
+                description: error.message,
+              });
+            });
+        }}
+      />
+    </Fragment>
+  );
 }
diff --git 
a/packages/merchant-backoffice/src/paths/instance/orders/create/CreatePage.tsx 
b/packages/merchant-backoffice/src/paths/instance/orders/create/CreatePage.tsx
index e0e9970..4a5af6b 100644
--- 
a/packages/merchant-backoffice/src/paths/instance/orders/create/CreatePage.tsx
+++ 
b/packages/merchant-backoffice/src/paths/instance/orders/create/CreatePage.tsx
@@ -15,15 +15,18 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import { add, isAfter, isBefore, isFuture } from "date-fns";
 import { Amounts } from "@gnu-taler/taler-util";
 import { Fragment, h, VNode } from "preact";
 import { useEffect, useState } from "preact/hooks";
-import { FormProvider, FormErrors } from 
"../../../../components/form/FormProvider";
+import {
+  FormProvider,
+  FormErrors,
+} from "../../../../components/form/FormProvider";
 import { Input } from "../../../../components/form/Input";
 import { InputCurrency } from "../../../../components/form/InputCurrency";
 import { InputDate } from "../../../../components/form/InputDate";
@@ -33,7 +36,7 @@ import { ProductList } from 
"../../../../components/product/ProductList";
 import { useConfigContext } from "../../../../context/config";
 import { Duration, MerchantBackend, WithId } from "../../../../declaration";
 import { Translate, useTranslator } from "../../../../i18n";
-import { OrderCreateSchema as schema } from '../../../../schemas/index';
+import { OrderCreateSchema as schema } from "../../../../schemas/index";
 import { rate } from "../../../../utils/amount";
 import { InventoryProductForm } from 
"../../../../components/product/InventoryProductForm";
 import { NonInventoryProductFrom } from 
"../../../../components/product/NonInventoryProductForm";
@@ -43,7 +46,7 @@ interface Props {
   onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
   onBack?: () => void;
   instanceConfig: InstanceConfig;
-  instanceInventory: (MerchantBackend.Products.ProductDetail & WithId)[],
+  instanceInventory: (MerchantBackend.Products.ProductDetail & WithId)[];
 }
 interface InstanceConfig {
   default_max_wire_fee: string;
@@ -53,9 +56,10 @@ interface InstanceConfig {
 }
 
 function with_defaults(config: InstanceConfig): Partial<Entity> {
-  const defaultPayDeadline = !config.default_pay_delay || 
config.default_pay_delay.d_ms === "forever" ?
-    undefined :
-    add(new Date(), { seconds: config.default_pay_delay.d_ms / 1000 })
+  const defaultPayDeadline =
+    !config.default_pay_delay || config.default_pay_delay.d_ms === "forever"
+      ? undefined
+      : add(new Date(), { seconds: config.default_pay_delay.d_ms / 1000 });
 
   return {
     inventoryProducts: {},
@@ -69,12 +73,12 @@ function with_defaults(config: InstanceConfig): 
Partial<Entity> {
       refund_deadline: defaultPayDeadline,
     },
     shipping: {},
-    extra: ''
+    extra: "",
   };
 }
 
 interface ProductAndQuantity {
-  product: MerchantBackend.Products.ProductDetail & WithId,
+  product: MerchantBackend.Products.ProductDetail & WithId;
   quantity: number;
 }
 export interface ProductMap {
@@ -100,8 +104,8 @@ interface Payments {
   wire_fee_amortization?: number;
 }
 interface Entity {
-  inventoryProducts: ProductMap,
-  products: MerchantBackend.Product[],
+  inventoryProducts: ProductMap;
+  products: MerchantBackend.Product[];
   pricing: Partial<Pricing>;
   payments: Partial<Payments>;
   shipping: Partial<Shipping>;
@@ -110,65 +114,88 @@ interface Entity {
 
 const stringIsValidJSON = (value: string) => {
   try {
-    JSON.parse(value.trim())
-    return true
+    JSON.parse(value.trim());
+    return true;
   } catch {
-    return false
+    return false;
   }
-}
+};
 
 function undefinedIfEmpty<T>(obj: T): T | undefined {
-  return Object.keys(obj).some(k => (obj as any)[k] !== undefined) ? obj : 
undefined
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
 }
 
-export function CreatePage({ onCreate, onBack, instanceConfig, 
instanceInventory }: Props): VNode {
-  const [value, valueHandler] = useState(with_defaults(instanceConfig))
-  const config = useConfigContext()
-  const zero = Amounts.getZero(config.currency)
+export function CreatePage({
+  onCreate,
+  onBack,
+  instanceConfig,
+  instanceInventory,
+}: Props): VNode {
+  const [value, valueHandler] = useState(with_defaults(instanceConfig));
+  const config = useConfigContext();
+  const zero = Amounts.getZero(config.currency);
 
   const inventoryList = Object.values(value.inventoryProducts || {});
   const productList = Object.values(value.products || {});
 
   const i18n = useTranslator();
-  
+
   const errors: FormErrors<Entity> = {
     pricing: undefinedIfEmpty({
       summary: !value.pricing?.summary ? i18n`required` : undefined,
-      order_price: !value.pricing?.order_price ? i18n`required` : (
-        (Amounts.parse(value.pricing.order_price)?.value || 0) <= 0 ?
-          i18n`must be greater than 0` : undefined
-      )
+      order_price: !value.pricing?.order_price
+        ? i18n`required`
+        : (Amounts.parse(value.pricing.order_price)?.value || 0) <= 0
+        ? i18n`must be greater than 0`
+        : undefined,
     }),
-    extra: value.extra && !stringIsValidJSON(value.extra) ? i18n`not a valid 
json` : undefined,
+    extra:
+      value.extra && !stringIsValidJSON(value.extra)
+        ? i18n`not a valid json`
+        : undefined,
     payments: undefinedIfEmpty({
-      refund_deadline: !value.payments?.refund_deadline ? i18n`required` : (
-        !isFuture(value.payments.refund_deadline) ? i18n`should be in the 
future` : (
-          value.payments.pay_deadline && 
isBefore(value.payments.refund_deadline, value.payments.pay_deadline) ?
-            i18n`pay deadline cannot be before refund deadline` : undefined
-        )
-      ),
-      pay_deadline: !value.payments?.pay_deadline ? i18n`required` : (
-        !isFuture(value.payments.pay_deadline) ? i18n`should be in the future` 
: undefined
-      ),
-      auto_refund_deadline: !value.payments?.auto_refund_deadline ? undefined 
: (
-        !isFuture(value.payments.auto_refund_deadline) ? i18n`should be in the 
future` : (
-          !value.payments?.refund_deadline ? i18n`should have a refund 
deadline` : (
-            !isAfter(value.payments.refund_deadline, 
value.payments.auto_refund_deadline) ?
-              i18n`auto refund cannot be after refund deadline` : undefined
+      refund_deadline: !value.payments?.refund_deadline
+        ? i18n`required`
+        : !isFuture(value.payments.refund_deadline)
+        ? i18n`should be in the future`
+        : value.payments.pay_deadline &&
+          isBefore(value.payments.refund_deadline, value.payments.pay_deadline)
+        ? i18n`pay deadline cannot be before refund deadline`
+        : undefined,
+      pay_deadline: !value.payments?.pay_deadline
+        ? i18n`required`
+        : !isFuture(value.payments.pay_deadline)
+        ? i18n`should be in the future`
+        : undefined,
+      auto_refund_deadline: !value.payments?.auto_refund_deadline
+        ? undefined
+        : !isFuture(value.payments.auto_refund_deadline)
+        ? i18n`should be in the future`
+        : !value.payments?.refund_deadline
+        ? i18n`should have a refund deadline`
+        : !isAfter(
+            value.payments.refund_deadline,
+            value.payments.auto_refund_deadline
           )
-        )
-      ),
+        ? i18n`auto refund cannot be after refund deadline`
+        : undefined,
     }),
     shipping: undefinedIfEmpty({
-      delivery_date: !value.shipping?.delivery_date ? undefined : (
-        !isFuture(value.shipping.delivery_date) ? i18n`should be in the 
future` : undefined
-      ),
+      delivery_date: !value.shipping?.delivery_date
+        ? undefined
+        : !isFuture(value.shipping.delivery_date)
+        ? i18n`should be in the future`
+        : undefined,
     }),
-  }
-  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+  };
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
 
   const submit = (): void => {
-    const order = schema.cast(value)
+    const order = schema.cast(value);
     if (!value.payments) return;
     if (!value.shipping) return;
 
@@ -178,198 +205,322 @@ export function CreatePage({ onCreate, onBack, 
instanceConfig, instanceInventory
         summary: order.pricing.summary,
         products: productList,
         extra: value.extra,
-        pay_deadline: value.payments.pay_deadline ? { t_ms: 
Math.floor(value.payments.pay_deadline.getTime() / 1000) * 1000 } : undefined,
-        wire_transfer_deadline: value.payments.pay_deadline ? { t_ms: 
Math.floor(value.payments.pay_deadline.getTime() / 1000) * 1000 } : undefined,
-        refund_deadline: value.payments.refund_deadline ? { t_ms: 
Math.floor(value.payments.refund_deadline.getTime() / 1000) * 1000 } : 
undefined,
+        pay_deadline: value.payments.pay_deadline
+          ? {
+              t_ms:
+                Math.floor(value.payments.pay_deadline.getTime() / 1000) * 
1000,
+            }
+          : undefined,
+        wire_transfer_deadline: value.payments.pay_deadline
+          ? {
+              t_ms:
+                Math.floor(value.payments.pay_deadline.getTime() / 1000) * 
1000,
+            }
+          : undefined,
+        refund_deadline: value.payments.refund_deadline
+          ? {
+              t_ms:
+                Math.floor(value.payments.refund_deadline.getTime() / 1000) *
+                1000,
+            }
+          : undefined,
         wire_fee_amortization: value.payments.wire_fee_amortization,
         max_fee: value.payments.max_fee,
         max_wire_fee: value.payments.max_wire_fee,
 
-        delivery_date: value.shipping.delivery_date ? { t_ms: 
value.shipping.delivery_date.getTime() } : undefined,
+        delivery_date: value.shipping.delivery_date
+          ? { t_ms: value.shipping.delivery_date.getTime() }
+          : undefined,
         delivery_location: value.shipping.delivery_location,
         fulfillment_url: value.shipping.fullfilment_url,
       },
-      inventory_products: inventoryList.map(p => ({
+      inventory_products: inventoryList.map((p) => ({
         product_id: p.product.id,
-        quantity: p.quantity
+        quantity: p.quantity,
       })),
-    }
+    };
 
     onCreate(request);
-  }
+  };
 
-  const addProductToTheInventoryList = (product: 
MerchantBackend.Products.ProductDetail & WithId, quantity: number) => {
-    valueHandler(v => {
-      const inventoryProducts = { ...v.inventoryProducts }
-      inventoryProducts[product.id] = { product, quantity }
-      return ({ ...v, inventoryProducts })
-    })
-  }
+  const addProductToTheInventoryList = (
+    product: MerchantBackend.Products.ProductDetail & WithId,
+    quantity: number
+  ) => {
+    valueHandler((v) => {
+      const inventoryProducts = { ...v.inventoryProducts };
+      inventoryProducts[product.id] = { product, quantity };
+      return { ...v, inventoryProducts };
+    });
+  };
 
   const removeProductFromTheInventoryList = (id: string) => {
-    valueHandler(v => {
-      const inventoryProducts = { ...v.inventoryProducts }
-      delete inventoryProducts[id]
-      return ({ ...v, inventoryProducts })
-    })
-  }
+    valueHandler((v) => {
+      const inventoryProducts = { ...v.inventoryProducts };
+      delete inventoryProducts[id];
+      return { ...v, inventoryProducts };
+    });
+  };
 
   const addNewProduct = async (product: MerchantBackend.Product) => {
-    return valueHandler(v => {
-      const products = v.products ? [...v.products, product] : []
-      return ({ ...v, products })
-    })
-  }
+    return valueHandler((v) => {
+      const products = v.products ? [...v.products, product] : [];
+      return { ...v, products };
+    });
+  };
 
   const removeFromNewProduct = (index: number) => {
-    valueHandler(v => {
-      const products = v.products ? [...v.products] : []
-      products.splice(index, 1)
-      return ({ ...v, products })
-    })
-  }
+    valueHandler((v) => {
+      const products = v.products ? [...v.products] : [];
+      products.splice(index, 1);
+      return { ...v, products };
+    });
+  };
 
-  const [editingProduct, setEditingProduct] = useState<MerchantBackend.Product 
| undefined>(undefined)
+  const [editingProduct, setEditingProduct] = useState<
+    MerchantBackend.Product | undefined
+  >(undefined);
 
   const totalPriceInventory = inventoryList.reduce((prev, cur) => {
-    const p = Amounts.parseOrThrow(cur.product.price)
-    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount
-  }, zero)
+    const p = Amounts.parseOrThrow(cur.product.price);
+    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount;
+  }, zero);
 
   const totalPriceProducts = productList.reduce((prev, cur) => {
-    if (!cur.price) return zero
-    const p = Amounts.parseOrThrow(cur.price)
-    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount
-  }, zero)
+    if (!cur.price) return zero;
+    const p = Amounts.parseOrThrow(cur.price);
+    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount;
+  }, zero);
 
-  const hasProducts = inventoryList.length > 0 || productList.length > 0
-  const totalPrice = Amounts.add(totalPriceInventory, totalPriceProducts)
+  const hasProducts = inventoryList.length > 0 || productList.length > 0;
+  const totalPrice = Amounts.add(totalPriceInventory, totalPriceProducts);
 
   const totalAsString = Amounts.stringify(totalPrice.amount);
-  const allProducts = productList.concat(inventoryList.map(asProduct))
+  const allProducts = productList.concat(inventoryList.map(asProduct));
 
   useEffect(() => {
-    valueHandler(v => {
-      return ({
-        ...v, pricing: {
+    valueHandler((v) => {
+      return {
+        ...v,
+        pricing: {
           ...v.pricing,
           products_price: hasProducts ? totalAsString : undefined,
           order_price: hasProducts ? totalAsString : undefined,
-        }
-      })
-    })
-  }, [hasProducts, totalAsString])
-
-  const discountOrRise = rate(value.pricing?.order_price || 
`${config.currency}:0`, totalAsString)
-
-  return <div>
-
-    <section class="section is-main-section">
-      <div class="columns">
-        <div class="column" />
-        <div class="column is-four-fifths">
-
-          {/* // FIXME: translating plural singular */}
-          <InputGroup name="inventory_products" label={i18n`Manage products in 
order`} alternative={
-            allProducts.length > 0 && <p>
-              {allProducts.length} products
-              with a total price of {totalAsString}.
-            </p>
-          } tooltip={i18n`Manage list of products in the order.`}>
-
-            <InventoryProductForm
-              currentProducts={value.inventoryProducts || {}}
-              onAddProduct={addProductToTheInventoryList}
-              inventory={instanceInventory}
-            />
-
-            <NonInventoryProductFrom productToEdit={editingProduct} 
onAddProduct={(p) => {
-              setEditingProduct(undefined)
-              return addNewProduct(p)
-            }} />
-
-            {allProducts.length > 0 &&
-              <ProductList list={allProducts}
-                actions={[{
-                  name: i18n`Remove`,
-                  tooltip: i18n`Remove this product from the order.`,
-                  handler: (e, index) => {
-                    if (e.product_id) {
-                      removeProductFromTheInventoryList(e.product_id)
-                    } else {
-                      removeFromNewProduct(index);
-                      setEditingProduct(e);
-                    }
-                  }
-                }]}
+        },
+      };
+    });
+  }, [hasProducts, totalAsString]);
+
+  const discountOrRise = rate(
+    value.pricing?.order_price || `${config.currency}:0`,
+    totalAsString
+  );
+
+  return (
+    <div>
+      <section class="section is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            {/* // FIXME: translating plural singular */}
+            <InputGroup
+              name="inventory_products"
+              label={i18n`Manage products in order`}
+              alternative={
+                allProducts.length > 0 && (
+                  <p>
+                    {allProducts.length} products with a total price of{" "}
+                    {totalAsString}.
+                  </p>
+                )
+              }
+              tooltip={i18n`Manage list of products in the order.`}
+            >
+              <InventoryProductForm
+                currentProducts={value.inventoryProducts || {}}
+                onAddProduct={addProductToTheInventoryList}
+                inventory={instanceInventory}
               />
-            }
-          </InputGroup>
-
-          <FormProvider<Entity> errors={errors} object={value} 
valueHandler={valueHandler as any}>
-            {hasProducts ?
-              <Fragment>
-                <InputCurrency name="pricing.products_price" label={i18n`Total 
price`} readonly tooltip={i18n`total product price added up`} />
-                <InputCurrency name="pricing.order_price"
-                  label={i18n`Total price`}
-                  addonAfter={discountOrRise > 0 && (discountOrRise < 1 ?
-                    `discount of %${Math.round((1 - discountOrRise) * 100)}` :
-                    `rise of %${Math.round((discountOrRise - 1) * 100)}`)
-                  }
-                  tooltip={i18n`Amount to be paid by the customer`}
-                />
-              </Fragment> :
-              <InputCurrency name="pricing.order_price" label={i18n`Order 
price`} tooltip={i18n`final order price`} />
-            }
 
-            <Input name="pricing.summary" inputType="multiline" 
label={i18n`Summary`} tooltip={i18n`Title of the order to be shown to the 
customer`} />
+              <NonInventoryProductFrom
+                productToEdit={editingProduct}
+                onAddProduct={(p) => {
+                  setEditingProduct(undefined);
+                  return addNewProduct(p);
+                }}
+              />
 
-            <InputGroup name="shipping" label={i18n`Shipping and Fulfillment`} 
initialActive >
-              <InputDate name="shipping.delivery_date" label={i18n`Delivery 
date`} tooltip={i18n`Deadline for physical delivery assured by the merchant.`} 
/>
-              {value.shipping?.delivery_date &&
-                <InputGroup name="shipping.delivery_location" 
label={i18n`Location`} tooltip={i18n`address where the products will be 
delivered`} >
-                  <InputLocation name="shipping.delivery_location" />
-                </InputGroup>
-              }
-              <Input name="shipping.fullfilment_url" label={i18n`Fulfillment 
URL`} tooltip={i18n`URL to which the user will be redirected after successful 
payment.`} />
+              {allProducts.length > 0 && (
+                <ProductList
+                  list={allProducts}
+                  actions={[
+                    {
+                      name: i18n`Remove`,
+                      tooltip: i18n`Remove this product from the order.`,
+                      handler: (e, index) => {
+                        if (e.product_id) {
+                          removeProductFromTheInventoryList(e.product_id);
+                        } else {
+                          removeFromNewProduct(index);
+                          setEditingProduct(e);
+                        }
+                      },
+                    },
+                  ]}
+                />
+              )}
             </InputGroup>
 
-            <InputGroup name="payments" label={i18n`Taler payment options`} 
tooltip={i18n`Override default Taler payment settings for this order`}>
-              <InputDate name="payments.pay_deadline" label={i18n`Payment 
deadline`} tooltip={i18n`Deadline for the customer to pay for the offer before 
it expires. Inventory products will be reserved until this deadline.`} />
-              <InputDate name="payments.refund_deadline" label={i18n`Refund 
deadline`} tooltip={i18n`Time until which the order can be refunded by the 
merchant.`} />
-              <InputDate name="payments.auto_refund_deadline" 
label={i18n`Auto-refund deadline`} tooltip={i18n`Time until which the wallet 
will automatically check for refunds without user interaction.`} />
+            <FormProvider<Entity>
+              errors={errors}
+              object={value}
+              valueHandler={valueHandler as any}
+            >
+              {hasProducts ? (
+                <Fragment>
+                  <InputCurrency
+                    name="pricing.products_price"
+                    label={i18n`Total price`}
+                    readonly
+                    tooltip={i18n`total product price added up`}
+                  />
+                  <InputCurrency
+                    name="pricing.order_price"
+                    label={i18n`Total price`}
+                    addonAfter={
+                      discountOrRise > 0 &&
+                      (discountOrRise < 1
+                        ? `discount of %${Math.round(
+                            (1 - discountOrRise) * 100
+                          )}`
+                        : `rise of %${Math.round((discountOrRise - 1) * 100)}`)
+                    }
+                    tooltip={i18n`Amount to be paid by the customer`}
+                  />
+                </Fragment>
+              ) : (
+                <InputCurrency
+                  name="pricing.order_price"
+                  label={i18n`Order price`}
+                  tooltip={i18n`final order price`}
+                />
+              )}
 
-              <InputCurrency name="payments.max_fee" label={i18n`Maximum 
deposit fee`} tooltip={i18n`Maximum deposit fees the merchant is willing to 
cover for this order. Higher deposit fees must be covered in full by the 
consumer.`} />
-              <InputCurrency name="payments.max_wire_fee" label={i18n`Maximum 
wire fee`} tooltip={i18n`Maximum aggregate wire fees the merchant is willing to 
cover for this order. Wire fees exceeding this amount are to be covered by the 
customers.`} />
-              <InputNumber name="payments.wire_fee_amortization" 
label={i18n`Wire fee amortization`} tooltip={i18n`Factor by which wire fees 
exceeding the above threshold are divided to determine the share of excess wire 
fees to be paid explicitly by the consumer.`} />
-            </InputGroup>
+              <Input
+                name="pricing.summary"
+                inputType="multiline"
+                label={i18n`Summary`}
+                tooltip={i18n`Title of the order to be shown to the customer`}
+              />
 
-            <InputGroup name="extra" label={i18n`Additional information`} 
tooltip={i18n`Custom information to be included in the contract for this 
order.`}>
-              <Input name="extra" inputType="multiline" label={`Value`} 
tooltip={i18n`You must enter a value in JavaScript Object Notation (JSON).`} />
-            </InputGroup>
-          </FormProvider>
+              <InputGroup
+                name="shipping"
+                label={i18n`Shipping and Fulfillment`}
+                initialActive
+              >
+                <InputDate
+                  name="shipping.delivery_date"
+                  label={i18n`Delivery date`}
+                  tooltip={i18n`Deadline for physical delivery assured by the 
merchant.`}
+                />
+                {value.shipping?.delivery_date && (
+                  <InputGroup
+                    name="shipping.delivery_location"
+                    label={i18n`Location`}
+                    tooltip={i18n`address where the products will be 
delivered`}
+                  >
+                    <InputLocation name="shipping.delivery_location" />
+                  </InputGroup>
+                )}
+                <Input
+                  name="shipping.fullfilment_url"
+                  label={i18n`Fulfillment URL`}
+                  tooltip={i18n`URL to which the user will be redirected after 
successful payment.`}
+                />
+              </InputGroup>
+
+              <InputGroup
+                name="payments"
+                label={i18n`Taler payment options`}
+                tooltip={i18n`Override default Taler payment settings for this 
order`}
+              >
+                <InputDate
+                  name="payments.pay_deadline"
+                  label={i18n`Payment deadline`}
+                  tooltip={i18n`Deadline for the customer to pay for the offer 
before it expires. Inventory products will be reserved until this deadline.`}
+                />
+                <InputDate
+                  name="payments.refund_deadline"
+                  label={i18n`Refund deadline`}
+                  tooltip={i18n`Time until which the order can be refunded by 
the merchant.`}
+                />
+                <InputDate
+                  name="payments.auto_refund_deadline"
+                  label={i18n`Auto-refund deadline`}
+                  tooltip={i18n`Time until which the wallet will automatically 
check for refunds without user interaction.`}
+                />
 
-          <div class="buttons is-right mt-5">
-            {onBack && <button class="button" onClick={onBack} 
><Translate>Cancel</Translate></button>}
-            <button class="button is-success" onClick={submit} 
disabled={hasErrors} ><Translate>Confirm</Translate></button>
+                <InputCurrency
+                  name="payments.max_fee"
+                  label={i18n`Maximum deposit fee`}
+                  tooltip={i18n`Maximum deposit fees the merchant is willing 
to cover for this order. Higher deposit fees must be covered in full by the 
consumer.`}
+                />
+                <InputCurrency
+                  name="payments.max_wire_fee"
+                  label={i18n`Maximum wire fee`}
+                  tooltip={i18n`Maximum aggregate wire fees the merchant is 
willing to cover for this order. Wire fees exceeding this amount are to be 
covered by the customers.`}
+                />
+                <InputNumber
+                  name="payments.wire_fee_amortization"
+                  label={i18n`Wire fee amortization`}
+                  tooltip={i18n`Factor by which wire fees exceeding the above 
threshold are divided to determine the share of excess wire fees to be paid 
explicitly by the consumer.`}
+                />
+              </InputGroup>
+
+              <InputGroup
+                name="extra"
+                label={i18n`Additional information`}
+                tooltip={i18n`Custom information to be included in the 
contract for this order.`}
+              >
+                <Input
+                  name="extra"
+                  inputType="multiline"
+                  label={`Value`}
+                  tooltip={i18n`You must enter a value in JavaScript Object 
Notation (JSON).`}
+                />
+              </InputGroup>
+            </FormProvider>
+
+            <div class="buttons is-right mt-5">
+              {onBack && (
+                <button class="button" onClick={onBack}>
+                  <Translate>Cancel</Translate>
+                </button>
+              )}
+              <button
+                class="button is-success"
+                onClick={submit}
+                disabled={hasErrors}
+              >
+                <Translate>Confirm</Translate>
+              </button>
+            </div>
           </div>
-
+          <div class="column" />
         </div>
-        <div class="column" />
-      </div>
-    </section>
-
-  </div>
+      </section>
+    </div>
+  );
 }
 
 function asProduct(p: ProductAndQuantity) {
-  return ({
+  return {
     product_id: p.product.id,
     image: p.product.image,
     price: p.product.price,
     unit: p.product.unit,
     quantity: p.quantity,
     description: p.product.description,
-    taxes: p.product.taxes
-  })
+    taxes: p.product.taxes,
+  };
 }
diff --git 
a/packages/merchant-backoffice/src/paths/instance/update/UpdatePage.tsx 
b/packages/merchant-backoffice/src/paths/instance/update/UpdatePage.tsx
index 0fa96ed..863f977 100644
--- a/packages/merchant-backoffice/src/paths/instance/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice/src/paths/instance/update/UpdatePage.tsx
@@ -15,191 +15,247 @@
  */
 
 /**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
 
 import { h, VNode } from "preact";
 import { useState } from "preact/hooks";
-import * as yup from 'yup';
+import * as yup from "yup";
 import { AsyncButton } from "../../../components/exception/AsyncButton";
-import { FormProvider, FormErrors } from 
"../../../components/form/FormProvider";
+import {
+  FormProvider,
+  FormErrors,
+} from "../../../components/form/FormProvider";
 import { UpdateTokenModal } from "../../../components/modal";
 import { useInstanceContext } from "../../../context/instance";
 import { MerchantBackend } from "../../../declaration";
 import { Translate, useTranslator } from "../../../i18n";
-import { InstanceUpdateSchema as schema } from '../../../schemas';
+import { InstanceUpdateSchema as schema } from "../../../schemas";
 import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultInstanceFormFields";
 import { PAYTO_REGEX } from "../../../utils/constants";
 import { Amounts } from "@gnu-taler/taler-util";
 
-
-type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & { 
-  auth_token?: string 
-}
+type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & {
+  auth_token?: string;
+};
 
 //MerchantBackend.Instances.InstanceAuthConfigurationMessage
 interface Props {
   onUpdate: (d: Entity) => void;
-  onChangeAuth: (d: 
MerchantBackend.Instances.InstanceAuthConfigurationMessage) => Promise<void>;
+  onChangeAuth: (
+    d: MerchantBackend.Instances.InstanceAuthConfigurationMessage
+  ) => Promise<void>;
   selected: MerchantBackend.Instances.QueryInstancesResponse;
   isLoading: boolean;
   onBack: () => void;
 }
 
-function convert(from: MerchantBackend.Instances.QueryInstancesResponse): 
Entity {
-  const { accounts, ...rest } = from
-  const payto_uris = accounts.filter(a => a.active).map(a => a.payto_uri)
+function convert(
+  from: MerchantBackend.Instances.QueryInstancesResponse
+): Entity {
+  const { accounts, ...rest } = from;
+  const payto_uris = accounts.filter((a) => a.active).map((a) => a.payto_uri);
   const defaults = {
     default_wire_fee_amortization: 1,
     default_pay_delay: { d_ms: 1000 * 60 * 60 }, //one hour
     default_wire_transfer_delay: { d_ms: 1000 * 60 * 60 * 2 }, //two hours
-  }
+  };
   return { ...defaults, ...rest, payto_uris };
 }
 
 function getTokenValuePart(t?: string): string | undefined {
-  if (!t) return t
+  if (!t) return t;
   const match = /secret-token:(.*)/.exec(t);
   if (!match || !match[1]) return undefined;
-  return match[1]
+  return match[1];
 }
 
 function undefinedIfEmpty<T>(obj: T): T | undefined {
-  return Object.keys(obj).some(k => (obj as any)[k] !== undefined) ? obj : 
undefined
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
 }
 
-export function UpdatePage({ onUpdate, onChangeAuth, selected, onBack }: 
Props): VNode {
-  const { id, token } = useInstanceContext()
-  const currentTokenValue = getTokenValuePart(token)
+export function UpdatePage({
+  onUpdate,
+  onChangeAuth,
+  selected,
+  onBack,
+}: Props): VNode {
+  const { id, token } = useInstanceContext();
+  const currentTokenValue = getTokenValuePart(token);
 
   function updateToken(token: string | undefined | null) {
-    const value = token && token.startsWith('secret-token:') ?
-      token.substring('secret-token:'.length) : token
+    const value =
+      token && token.startsWith("secret-token:")
+        ? token.substring("secret-token:".length)
+        : token;
 
     if (!token) {
-      onChangeAuth({ method: 'external' })
+      onChangeAuth({ method: "external" });
     } else {
-      onChangeAuth({ method: 'token', token: `secret-token:${value}` })
+      onChangeAuth({ method: "token", token: `secret-token:${value}` });
     }
   }
 
-  const [value, valueHandler] = useState<Partial<Entity>>(convert(selected))
+  const [value, valueHandler] = useState<Partial<Entity>>(convert(selected));
 
-  const i18n = useTranslator()
+  const i18n = useTranslator();
 
   const errors: FormErrors<Entity> = {
     name: !value.name ? i18n`required` : undefined,
     payto_uris:
-      !value.payto_uris || !value.payto_uris.length ? i18n`required` : (
-        undefinedIfEmpty(value.payto_uris.map(p => {
-          return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined
-        }))
-      ),
-    default_max_deposit_fee:
-      !value.default_max_deposit_fee ? i18n`required` : (
-        !Amounts.parse(value.default_max_deposit_fee) ? i18n`invalid format` :
-          undefined
-      ),
-    default_max_wire_fee:
-      !value.default_max_wire_fee ? i18n`required` : (
-        !Amounts.parse(value.default_max_wire_fee) ? i18n`invalid format` :
-          undefined
-      ),
+      !value.payto_uris || !value.payto_uris.length
+        ? i18n`required`
+        : undefinedIfEmpty(
+            value.payto_uris.map((p) => {
+              return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined;
+            })
+          ),
+    default_max_deposit_fee: !value.default_max_deposit_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_deposit_fee)
+      ? i18n`invalid format`
+      : undefined,
+    default_max_wire_fee: !value.default_max_wire_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_wire_fee)
+      ? i18n`invalid format`
+      : undefined,
     default_wire_fee_amortization:
-      value.default_wire_fee_amortization === undefined ? i18n`required` : (
-        isNaN(value.default_wire_fee_amortization) ? i18n`is not a number` : (
-          value.default_wire_fee_amortization < 1 ? i18n`must be 1 or greater` 
:
-            undefined
-        )
-      ),
-    default_pay_delay:
-      !value.default_pay_delay ? i18n`required` : undefined,
-    default_wire_transfer_delay:
-      !value.default_wire_transfer_delay ? i18n`required` : undefined,
+      value.default_wire_fee_amortization === undefined
+        ? i18n`required`
+        : isNaN(value.default_wire_fee_amortization)
+        ? i18n`is not a number`
+        : value.default_wire_fee_amortization < 1
+        ? i18n`must be 1 or greater`
+        : undefined,
+    default_pay_delay: !value.default_pay_delay ? i18n`required` : undefined,
+    default_wire_transfer_delay: !value.default_wire_transfer_delay
+      ? i18n`required`
+      : undefined,
     address: undefinedIfEmpty({
       address_lines:
-        value.address?.address_lines && value.address?.address_lines.length > 
7 ? i18n`max 7 lines` :
-          undefined
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
     }),
     jurisdiction: undefinedIfEmpty({
-      address_lines: value.address?.address_lines && 
value.address?.address_lines.length > 7 ? i18n`max 7 lines` :
-        undefined
+      address_lines:
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
     }),
   };
 
-  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
   const submit = async (): Promise<void> => {
     await onUpdate(schema.cast(value));
-    await onBack()
-    return Promise.resolve()
-  }
+    await onBack();
+    return Promise.resolve();
+  };
   const [active, setActive] = useState(false);
 
-  return <div>
-    <section class="section">
-
-      <section class="hero is-hero-bar">
-        <div class="hero-body">
-
-          <div class="level">
-            <div class="level-left">
-              <div class="level-item">
-                <span class="is-size-4"><Translate>Instance id</Translate>: 
<b>{id}</b></span>
+  return (
+    <div>
+      <section class="section">
+        <section class="hero is-hero-bar">
+          <div class="hero-body">
+            <div class="level">
+              <div class="level-left">
+                <div class="level-item">
+                  <span class="is-size-4">
+                    <Translate>Instance id</Translate>: <b>{id}</b>
+                  </span>
+                </div>
               </div>
-            </div>
-            <div class="level-right">
-              <div class="level-item">
-                <h1 class="title">
-                  <button class="button is-danger" 
-                    data-tooltip={i18n`Change the authorization method use for 
this instance.`}
-                    onClick={(): void => { setActive(!active); }} >
-                    <div class="icon is-left"><i class="mdi mdi-lock-reset" 
/></div>
-                    <span><Translate>Manage access token</Translate></span>
-                  </button>
-                </h1>
+              <div class="level-right">
+                <div class="level-item">
+                  <h1 class="title">
+                    <button
+                      class="button is-danger"
+                      data-tooltip={i18n`Change the authorization method use 
for this instance.`}
+                      onClick={(): void => {
+                        setActive(!active);
+                      }}
+                    >
+                      <div class="icon is-left">
+                        <i class="mdi mdi-lock-reset" />
+                      </div>
+                      <span>
+                        <Translate>Manage access token</Translate>
+                      </span>
+                    </button>
+                  </h1>
+                </div>
               </div>
             </div>
           </div>
-        </div></section>
-
-      <div class="columns">
-        <div class="column" />
-        <div class="column is-four-fifths">
-          {active && <UpdateTokenModal oldToken={currentTokenValue}
-            onCancel={() => { setActive(false); }}
-            onClear={() => { updateToken(null); setActive(false); }}
-            onConfirm={(newToken) => {
-              updateToken(newToken); setActive(false)
-            }}
-          />}
-        </div>
-        <div class="column" />
-      </div>
-      <hr />
-
-      <div class="columns">
-        <div class="column" />
-        <div class="column is-four-fifths">
-          <FormProvider<Entity> errors={errors} object={value} 
valueHandler={valueHandler} >
-
-            <DefaultInstanceFormFields showId={false} />
-
-          </FormProvider>
+        </section>
 
-          <div class="buttons is-right mt-4">
-            <button class="button" onClick={onBack} data-tooltip="cancel 
operation"><Translate>Cancel</Translate></button>
-
-            <AsyncButton onClick={submit} data-tooltip={
-              hasErrors ? i18n`Need to complete marked fields` : 'confirm 
operation'
-            } disabled={hasErrors} 
><Translate>Confirm</Translate></AsyncButton>
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            {active && (
+              <UpdateTokenModal
+                oldToken={currentTokenValue}
+                onCancel={() => {
+                  setActive(false);
+                }}
+                onClear={() => {
+                  updateToken(null);
+                  setActive(false);
+                }}
+                onConfirm={(newToken) => {
+                  updateToken(newToken);
+                  setActive(false);
+                }}
+              />
+            )}
           </div>
+          <div class="column" />
         </div>
-        <div class="column" />
-      </div>
+        <hr />
 
-    </section>
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            <FormProvider<Entity>
+              errors={errors}
+              object={value}
+              valueHandler={valueHandler}
+            >
+              <DefaultInstanceFormFields showId={false} />
+            </FormProvider>
 
-  </div >
+            <div class="buttons is-right mt-4">
+              <button
+                class="button"
+                onClick={onBack}
+                data-tooltip="cancel operation"
+              >
+                <Translate>Cancel</Translate>
+              </button>
 
+              <AsyncButton
+                onClick={submit}
+                data-tooltip={
+                  hasErrors
+                    ? i18n`Need to complete marked fields`
+                    : "confirm operation"
+                }
+                disabled={hasErrors}
+              >
+                <Translate>Confirm</Translate>
+              </AsyncButton>
+            </div>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
 }
diff --git a/packages/merchant-backoffice/src/paths/instance/update/index.tsx 
b/packages/merchant-backoffice/src/paths/instance/update/index.tsx
index 33dc476..38a652d 100644
--- a/packages/merchant-backoffice/src/paths/instance/update/index.tsx
+++ b/packages/merchant-backoffice/src/paths/instance/update/index.tsx
@@ -18,7 +18,12 @@ import { Loading } from 
"../../../components/exception/loading";
 import { useInstanceContext } from "../../../context/instance";
 import { MerchantBackend } from "../../../declaration";
 import { HttpError, HttpResponse } from "../../../hooks/backend";
-import { useInstanceAPI, useInstanceDetails, useManagedInstanceDetails, 
useManagementAPI } from "../../../hooks/instance";
+import {
+  useInstanceAPI,
+  useInstanceDetails,
+  useManagedInstanceDetails,
+  useManagementAPI,
+} from "../../../hooks/instance";
 import { UpdatePage } from "./UpdatePage";
 
 export interface Props {
@@ -29,41 +34,65 @@ export interface Props {
   onNotFound: () => VNode;
   onLoadError: (e: HttpError) => VNode;
   onUpdateError: (e: HttpError) => void;
-
 }
 
 export default function Update(props: Props): VNode {
   const { updateInstance, clearToken, setNewToken } = useInstanceAPI();
-  const result = useInstanceDetails()
-  return CommonUpdate(props, result, updateInstance, clearToken, setNewToken)
+  const result = useInstanceDetails();
+  return CommonUpdate(props, result, updateInstance, clearToken, setNewToken);
 }
 
-export function AdminUpdate(props:Props & {instanceId:string}): VNode {
-  const { updateInstance, clearToken, setNewToken } = 
useManagementAPI(props.instanceId);
-  const result = useManagedInstanceDetails(props.instanceId)
-  return CommonUpdate(props, result, updateInstance, clearToken, setNewToken)
+export function AdminUpdate(props: Props & { instanceId: string }): VNode {
+  const { updateInstance, clearToken, setNewToken } = useManagementAPI(
+    props.instanceId
+  );
+  const result = useManagedInstanceDetails(props.instanceId);
+  return CommonUpdate(props, result, updateInstance, clearToken, setNewToken);
 }
 
-function CommonUpdate({ onBack, onConfirm, onLoadError, onNotFound, 
onUpdateError, onUnauthorized }: Props, result: 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse>, updateInstance: 
any, clearToken: any, setNewToken: any): VNode {
-  const { changeToken } = useInstanceContext()
+function CommonUpdate(
+  {
+    onBack,
+    onConfirm,
+    onLoadError,
+    onNotFound,
+    onUpdateError,
+    onUnauthorized,
+  }: Props,
+  result: HttpResponse<MerchantBackend.Instances.QueryInstancesResponse>,
+  updateInstance: any,
+  clearToken: any,
+  setNewToken: any
+): VNode {
+  const { changeToken } = useInstanceContext();
 
-  if (result.clientError && result.isUnauthorized) return onUnauthorized()
-  if (result.clientError && result.isNotfound) return onNotFound()
-  if (result.loading) return <Loading />
-  if (!result.ok) return onLoadError(result)
+  if (result.clientError && result.isUnauthorized) return onUnauthorized();
+  if (result.clientError && result.isNotfound) return onNotFound();
+  if (result.loading) return <Loading />;
+  if (!result.ok) return onLoadError(result);
 
-  return <Fragment>
-    <UpdatePage
-      onBack={onBack}
-      isLoading={false}
-      selected={result.data}
-      onUpdate={(d: MerchantBackend.Instances.InstanceReconfigurationMessage): 
Promise<void> => {
-        return updateInstance(d).then(onConfirm).catch(onUpdateError)
-      }} 
-      onChangeAuth={(d: 
MerchantBackend.Instances.InstanceAuthConfigurationMessage): Promise<void> => {
-        const apiCall = d.method === 'external' ? clearToken() : 
setNewToken(d.token!);
-        return apiCall.then(() => 
changeToken(d.token)).then(onConfirm).catch(onUpdateError)
-      }} 
+  return (
+    <Fragment>
+      <UpdatePage
+        onBack={onBack}
+        isLoading={false}
+        selected={result.data}
+        onUpdate={(
+          d: MerchantBackend.Instances.InstanceReconfigurationMessage
+        ): Promise<void> => {
+          return updateInstance(d).then(onConfirm).catch(onUpdateError);
+        }}
+        onChangeAuth={(
+          d: MerchantBackend.Instances.InstanceAuthConfigurationMessage
+        ): Promise<void> => {
+          const apiCall =
+            d.method === "external" ? clearToken() : setNewToken(d.token!);
+          return apiCall
+            .then(() => changeToken(d.token))
+            .then(onConfirm)
+            .catch(onUpdateError);
+        }}
       />
-  </Fragment>
-}
\ No newline at end of file
+    </Fragment>
+  );
+}

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