diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src')
6 files changed, 130 insertions, 81 deletions
diff --git a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx index efcca302f..ae1bb27d1 100644 --- a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx +++ b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx @@ -28,16 +28,16 @@ import { InputDuration } from "../form/InputDuration.js"; import { InputGroup } from "../form/InputGroup.js"; import { InputImage } from "../form/InputImage.js"; import { InputLocation } from "../form/InputLocation.js"; -import { InputSelector } from "../form/InputSelector.js"; import { InputToggle } from "../form/InputToggle.js"; import { InputWithAddon } from "../form/InputWithAddon.js"; -import { TextField } from "../form/TextField.js"; export function DefaultInstanceFormFields({ readonlyId, showId, + showLessFields, }: { readonlyId?: boolean; + showLessFields?: boolean; showId: boolean; }): VNode { const { i18n } = useTranslationContext(); @@ -60,59 +60,63 @@ export function DefaultInstanceFormFields({ tooltip={i18n.str`Legal name of the business represented by this instance.`} /> - <Input<Entity> - name="email" - label={i18n.str`Email`} - tooltip={i18n.str`Contact email`} - /> + {showLessFields ? undefined : ( + <Fragment> + <Input<Entity> + name="email" + label={i18n.str`Email`} + tooltip={i18n.str`Contact email`} + /> - <Input<Entity> - name="website" - label={i18n.str`Website URL`} - tooltip={i18n.str`URL.`} - /> + <Input<Entity> + name="website" + label={i18n.str`Website URL`} + tooltip={i18n.str`URL.`} + /> - <InputImage<Entity> - name="logo" - label={i18n.str`Logo`} - tooltip={i18n.str`Logo image.`} - /> + <InputImage<Entity> + name="logo" + label={i18n.str`Logo`} + tooltip={i18n.str`Logo image.`} + /> - <InputGroup - name="address" - label={i18n.str`Address`} - tooltip={i18n.str`Physical location of the merchant.`} - > - <InputLocation name="address" /> - </InputGroup> + <InputGroup + name="address" + label={i18n.str`Address`} + tooltip={i18n.str`Physical location of the merchant.`} + > + <InputLocation name="address" /> + </InputGroup> - <InputGroup - name="jurisdiction" - label={i18n.str`Jurisdiction`} - tooltip={i18n.str`Jurisdiction for legal disputes with the merchant.`} - > - <InputLocation name="jurisdiction" /> - </InputGroup> + <InputGroup + name="jurisdiction" + label={i18n.str`Jurisdiction`} + tooltip={i18n.str`Jurisdiction for legal disputes with the merchant.`} + > + <InputLocation name="jurisdiction" /> + </InputGroup> - <InputToggle<Entity> - name="use_stefan" - label={i18n.str`Pay transaction fee`} - tooltip={i18n.str`Assume the cost of the transaction of let the user pay for it.`} - /> + <InputToggle<Entity> + name="use_stefan" + label={i18n.str`Pay transaction fee`} + tooltip={i18n.str`Assume the cost of the transaction of let the user pay for it.`} + /> - <InputDuration<Entity> - name="default_pay_delay" - label={i18n.str`Default payment delay`} - withForever - tooltip={i18n.str`Time customers have to pay an order before the offer expires by default.`} - /> + <InputDuration<Entity> + name="default_pay_delay" + label={i18n.str`Default payment delay`} + withForever + tooltip={i18n.str`Time customers have to pay an order before the offer expires by default.`} + /> - <InputDuration<Entity> - name="default_wire_transfer_delay" - label={i18n.str`Default wire transfer delay`} - tooltip={i18n.str`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.`} - withForever - /> + <InputDuration<Entity> + name="default_wire_transfer_delay" + label={i18n.str`Default wire transfer delay`} + tooltip={i18n.str`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.`} + withForever + /> + </Fragment> + )} </Fragment> ); } diff --git a/packages/merchant-backoffice-ui/src/hooks/preference.ts b/packages/merchant-backoffice-ui/src/hooks/preference.ts index a21d2921c..fddbc6e08 100644 --- a/packages/merchant-backoffice-ui/src/hooks/preference.ts +++ b/packages/merchant-backoffice-ui/src/hooks/preference.ts @@ -27,6 +27,7 @@ import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser"; export interface Preferences { advanceOrderMode: boolean; + advanceInstanceMode: boolean; hideKycUntil: AbsoluteTime; hideMissingAccountUntil: AbsoluteTime; dateFormat: "ymd" | "dmy" | "mdy"; @@ -34,6 +35,7 @@ export interface Preferences { const defaultSettings: Preferences = { advanceOrderMode: false, + advanceInstanceMode: false, hideKycUntil: AbsoluteTime.never(), hideMissingAccountUntil: AbsoluteTime.never(), dateFormat: "ymd", @@ -42,6 +44,7 @@ const defaultSettings: Preferences = { export const codecForPreferences = (): Codec<Preferences> => buildCodecForObject<Preferences>() .property("advanceOrderMode", codecForBoolean()) + .property("advanceInstanceMode", codecForBoolean()) .property("hideKycUntil", codecForAbsoluteTime) .property("hideMissingAccountUntil", codecForAbsoluteTime) .property( diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx index a28992a2f..6a94109a0 100644 --- a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx @@ -25,7 +25,7 @@ import { createRFC8959AccessTokenPlain, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { h, VNode } from "preact"; +import { VNode, h } from "preact"; import { useState } from "preact/hooks"; import { AsyncButton } from "../../../components/exception/AsyncButton.js"; import { @@ -34,6 +34,7 @@ import { } from "../../../components/form/FormProvider.js"; import { DefaultInstanceFormFields } from "../../../components/instance/DefaultInstanceFormFields.js"; import { SetTokenNewInstanceModal } from "../../../components/modal/index.js"; +import { usePreference } from "../../../hooks/preference.js"; import { INSTANCE_ID_REGEX } from "../../../utils/constants.js"; import { undefinedIfEmpty } from "../../../utils/table.js"; @@ -64,13 +65,13 @@ function with_defaults(id?: string): Partial<Entity> { } export function CreatePage({ onCreate, onBack, forceId }: Props): VNode { + const [pref, updatePref] = usePreference(); + const { i18n } = useTranslationContext(); const [value, valueHandler] = useState(with_defaults(forceId)); const [isTokenSet, updateIsTokenSet] = useState<boolean>(false); const [isTokenDialogActive, updateIsTokenDialogActive] = useState<boolean>(false); - const { i18n } = useTranslationContext(); - const errors: FormErrors<Entity> = { id: !value.id ? i18n.str`required` @@ -186,6 +187,34 @@ export function CreatePage({ onCreate, onBack, forceId }: Props): VNode { </div> <section class="section is-main-section"> + <div class="tabs is-toggle is-fullwidth is-small"> + <ul> + <li + class={!pref.advanceInstanceMode ? "is-active" : ""} + onClick={() => { + updatePref("advanceInstanceMode", false); + }} + > + <a> + <span> + <i18n.Translate>Simple</i18n.Translate> + </span> + </a> + </li> + <li + class={pref.advanceInstanceMode ? "is-active" : ""} + onClick={() => { + updatePref("advanceInstanceMode", true); + }} + > + <a> + <span> + <i18n.Translate>Advanced</i18n.Translate> + </span> + </a> + </li> + </ul> + </div>{" "} <div class="columns"> <div class="column" /> <div class="column is-four-fifths"> @@ -194,7 +223,11 @@ export function CreatePage({ onCreate, onBack, forceId }: Props): VNode { object={value} valueHandler={valueHandler} > - <DefaultInstanceFormFields readonlyId={!!forceId} showId={true} /> + <DefaultInstanceFormFields + readonlyId={!!forceId} + showId={true} + showLessFields={!pref.advanceInstanceMode} + /> </FormProvider> <div class="level"> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx index 7be3d23f6..29c50fb07 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx @@ -138,7 +138,7 @@ export function CreatePage({ const instance_default = with_defaults(instanceConfig, config.currency); const [value, valueHandler] = useState(instance_default); const zero = Amounts.zeroOfCurrency(config.currency); - const [settings, updateSettings] = usePreference(); + const [pref, updatePrefs] = usePreference(); const inventoryList = Object.values(value.inventoryProducts || {}); const productList = Object.values(value.products || {}); @@ -360,9 +360,9 @@ export function CreatePage({ <div class="tabs is-toggle is-fullwidth is-small"> <ul> <li - class={!settings.advanceOrderMode ? "is-active" : ""} + class={!pref.advanceOrderMode ? "is-active" : ""} onClick={() => { - updateSettings("advanceOrderMode", false); + updatePrefs("advanceOrderMode", false); }} > <a> @@ -372,9 +372,9 @@ export function CreatePage({ </a> </li> <li - class={settings.advanceOrderMode ? "is-active" : ""} + class={pref.advanceOrderMode ? "is-active" : ""} onClick={() => { - updateSettings("advanceOrderMode", true); + updatePrefs("advanceOrderMode", true); }} > <a> @@ -408,7 +408,7 @@ export function CreatePage({ inventory={instanceInventory} /> - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <NonInventoryProductFrom productToEdit={editingProduct} onAddProduct={(p) => { @@ -481,7 +481,7 @@ export function CreatePage({ tooltip={i18n.str`Title of the order to be shown to the customer`} /> - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputGroup name="shipping" label={i18n.str`Shipping and Fulfillment`} @@ -509,13 +509,13 @@ export function CreatePage({ </InputGroup> )} - {(settings.advanceOrderMode || requiresSomeTalerOptions) && ( + {(pref.advanceOrderMode || requiresSomeTalerOptions) && ( <InputGroup name="payments" label={i18n.str`Taler payment options`} tooltip={i18n.str`Override default Taler payment settings for this order`} > - {(settings.advanceOrderMode || noDefault_payDeadline) && ( + {(pref.advanceOrderMode || noDefault_payDeadline) && ( <InputDuration name="payments.pay_deadline" label={i18n.str`Payment time`} @@ -547,7 +547,7 @@ export function CreatePage({ } /> )} - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputDuration name="payments.refund_deadline" label={i18n.str`Refund time`} @@ -580,7 +580,7 @@ export function CreatePage({ } /> )} - {(settings.advanceOrderMode || noDefault_wireDeadline) && ( + {(pref.advanceOrderMode || noDefault_wireDeadline) && ( <InputDuration name="payments.wire_transfer_deadline" label={i18n.str`Wire transfer time`} @@ -614,7 +614,7 @@ export function CreatePage({ } /> )} - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputDuration name="payments.auto_refund_deadline" label={i18n.str`Auto-refund time`} @@ -628,21 +628,21 @@ export function CreatePage({ /> )} - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputCurrency name="payments.max_fee" label={i18n.str`Maximum fee`} tooltip={i18n.str`Maximum fees the merchant is willing to cover for this order. Higher deposit fees must be covered in full by the consumer.`} /> )} - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputToggle name="payments.createToken" label={i18n.str`Create token`} tooltip={i18n.str`If the order ID is easy to guess the token will prevent user to steal orders from others.`} /> )} - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputNumber name="payments.minimum_age" label={i18n.str`Minimum age required`} @@ -657,7 +657,7 @@ export function CreatePage({ </InputGroup> )} - {settings.advanceOrderMode && ( + {pref.advanceOrderMode && ( <InputGroup name="extra" label={i18n.str`Additional information`} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx index 861114014..04f0b2482 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx @@ -19,7 +19,12 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util"; +import { + HttpStatusCode, + TalerError, + TalerMerchantApi, + assertUnreachable, +} from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; @@ -41,24 +46,21 @@ interface Props { onBack?: () => void; onConfirm: (id: string) => void; } -export default function OrderCreate({ - onConfirm, - onBack, -}: Props): VNode { +export default function OrderCreate({ onConfirm, onBack }: Props): VNode { const { lib } = useSessionContext(); const [notif, setNotif] = useState<Notification | undefined>(undefined); const { state } = useSessionContext(); const detailsResult = useInstanceDetails(); const inventoryResult = useInstanceProducts(); - if (!detailsResult) return <Loading /> + if (!detailsResult) return <Loading />; if (detailsResult instanceof TalerError) { - return <ErrorLoadingMerchant error={detailsResult} /> + return <ErrorLoadingMerchant error={detailsResult} />; } if (detailsResult.type === "fail") { switch (detailsResult.case) { case HttpStatusCode.Unauthorized: { - return <LoginPage /> + return <LoginPage />; } case HttpStatusCode.NotFound: { return <NotFoundPageOrAdminCreate />; @@ -68,9 +70,9 @@ export default function OrderCreate({ } } } - if (!inventoryResult) return <Loading /> + if (!inventoryResult) return <Loading />; if (inventoryResult instanceof TalerError) { - return <ErrorLoadingMerchant error={inventoryResult} /> + return <ErrorLoadingMerchant error={inventoryResult} />; } if (inventoryResult.type === "fail") { switch (inventoryResult.case) { @@ -78,7 +80,7 @@ export default function OrderCreate({ return <NotFoundPageOrAdminCreate />; } case HttpStatusCode.Unauthorized: { - return <LoginPage /> + return <LoginPage />; } default: { assertUnreachable(inventoryResult); @@ -93,10 +95,11 @@ export default function OrderCreate({ <CreatePage onBack={onBack} onCreate={(request: TalerMerchantApi.PostOrderRequest) => { - lib.instance.createOrder(state.token, request) + lib.instance + .createOrder(state.token, request) .then((r) => { if (r.type === "ok") { - return onConfirm(r.body.order_id) + return onConfirm(r.body.order_id); } else { setNotif({ message: "could not create order", diff --git a/packages/merchant-backoffice-ui/src/paths/settings/index.tsx b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx index 0c4b9dd1a..ac23f7f09 100644 --- a/packages/merchant-backoffice-ui/src/paths/settings/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/settings/index.tsx @@ -45,6 +45,7 @@ export function Settings({ onClose }: { onClose?: () => void }): VNode { const next = s(value); const v: Preferences = { advanceOrderMode: next.advanceOrderMode ?? false, + advanceInstanceMode: next.advanceInstanceMode ?? false, hideMissingAccountUntil: next.hideMissingAccountUntil ?? AbsoluteTime.never(), hideKycUntil: next.hideKycUntil ?? AbsoluteTime.never(), dateFormat: next.dateFormat ?? "ymd", @@ -101,6 +102,11 @@ export function Settings({ onClose }: { onClose?: () => void }): VNode { tooltip={i18n.str`Shows more options in the order creation form`} name="advanceOrderMode" /> + <InputToggle<Preferences> + label={i18n.str`Advance instance settings`} + tooltip={i18n.str`Shows more options in the instance settings form`} + name="advanceInstanceMode" + /> <InputSelector<Preferences> name="dateFormat" label={i18n.str`Date format`} |