diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts')
-rw-r--r-- | packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts new file mode 100644 index 000000000..a7b2fe90f --- /dev/null +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts @@ -0,0 +1,145 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { + KnownBankAccountsInfo, + parsePaytoUri, + stringifyPaytoUri, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { useState } from "preact/hooks"; +import { alertFromError, useAlertContext } from "../../context/alert.js"; +import { useBackendContext } from "../../context/backend.js"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; +import { AccountByType, Props, State } from "./index.js"; +import { useSettings } from "../../hooks/useSettings.js"; + +export function useComponentState({ + currency, + onAccountAdded, + onCancel, +}: Props): State { + const api = useBackendContext(); + const { pushAlertOnError } = useAlertContext(); + const { i18n } = useTranslationContext(); + const hook = useAsyncAsHook(() => + api.wallet.call(WalletApiOperation.ListKnownBankAccounts, { currency }), + ); + const accountType: Record<string, string> = { + iban: "IBAN", + }; + const [settings] = useSettings(); + if (settings.extendedAccountTypes) { + accountType["bitcoin"] = "Bitcoin"; + accountType["x-taler-bank"] = "Taler Bank"; + } + + const [payto, setPayto] = useState(""); + const [alias, setAlias] = useState(""); + const [type, setType] = useState("iban"); + + if (!hook) { + return { + status: "loading", + error: undefined, + }; + } + if (hook.hasError) { + return { + status: "error", + error: alertFromError( + i18n, + i18n.str`Could not load known bank accounts`, + hook), + }; + } + + const uri = parsePaytoUri(payto); + const found = + hook.response.accounts.findIndex( + (a) => stringifyPaytoUri(a.uri) === payto, + ) !== -1; + + async function addAccount(): Promise<void> { + if (!uri || found) return; + + const normalizedPayto = stringifyPaytoUri(uri); + await api.wallet.call(WalletApiOperation.AddKnownBankAccounts, { + alias, + currency, + payto: normalizedPayto, + }); + onAccountAdded(payto); + } + + const paytoUriError = found ? "that account is already present" : undefined; + + const unableToAdd = + !type || !alias || paytoUriError !== undefined || uri === undefined; + + const accountByType: AccountByType = { + iban: [], + bitcoin: [], + "x-taler-bank": [], + }; + + hook.response.accounts.forEach((acc) => { + accountByType[acc.uri.targetType].push(acc); + }); + + async function deleteAccount(account: KnownBankAccountsInfo): Promise<void> { + const payto = stringifyPaytoUri(account.uri); + await api.wallet.call(WalletApiOperation.ForgetKnownBankAccounts, { + payto, + }); + hook?.retry(); + } + + return { + status: "ready", + error: undefined, + currency, + accountType: { + list: accountType, + value: type, + onChange: pushAlertOnError(async (v) => { + setType(v); + }), + }, + alias: { + value: alias, + onInput: pushAlertOnError(async (v) => { + setAlias(v); + }), + }, + uri: { + value: payto, + error: paytoUriError, + onInput: pushAlertOnError(async (v) => { + setPayto(v); + }), + }, + accountByType, + deleteAccount: pushAlertOnError(deleteAccount), + onAccountAdded: { + onClick: unableToAdd ? undefined : pushAlertOnError(addAccount), + }, + onCancel: { + onClick: pushAlertOnError(async () => onCancel()), + }, + }; +} |