/* This file is part of GNU Taler (C) 2021 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ /** * * @author Sebastian Javier Marchano (sebasjm) */ import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import * as yup from 'yup'; import { AsyncButton } from "../../../components/exception/AsyncButton"; import { FormErrors, FormProvider } from "../../../components/form/FormProvider"; import { SetTokenNewInstanceModal } from "../../../components/modal"; import { MerchantBackend } from "../../../declaration"; import { Translate, useTranslator } from "../../../i18n"; import { DefaultInstanceFormFields } from "../../../components/instance/DefaultInstanceFormFields"; 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 } interface Props { onCreate: (d: Entity) => Promise; onBack?: () => void; forceId?: string; } function with_defaults(id?: string): Partial { return { id, payto_uris: [], default_pay_delay: { d_ms: 1000 * 60 * 60 }, // one hour default_wire_fee_amortization: 1, default_wire_transfer_delay: { d_ms: 1000 * 2 * 60 * 60 * 24 }, // one day }; } function undefinedIfEmpty(obj: T): T | 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 [isTokenSet, updateIsTokenSet] = useState(false); const [isTokenDialogActive, updateIsTokenDialogActive] = useState(false); const i18n = useTranslator() const errors: FormErrors = { 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 ), 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, address: undefinedIfEmpty({ address_lines: 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 }), }; const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== undefined) const submit = (): Promise => { // 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 = {} // 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 })) } return
{isTokenDialogActive && { updateIsTokenDialogActive(false); updateIsTokenSet(false); }} onClear={() => { updateToken(null); updateIsTokenDialogActive(false); updateIsTokenSet(true); }} onConfirm={(newToken) => { updateToken(newToken); updateIsTokenDialogActive(false); updateIsTokenSet(true); }} />}

errors={errors} object={value} valueHandler={valueHandler} >
{onBack && } Confirm
}