/* 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 */ import { Amounts } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useState } from "preact/hooks"; import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { RecursiveState, assertUnreachable } from "../../utils/index.js"; import { Contact, Props, State } from "./index.js"; export function useComponentState(props: Props): RecursiveState { const api = useBackendContext(); const { pushAlertOnError } = useAlertContext(); const parsedInitialAmount = !props.amount ? undefined : Amounts.parse(props.amount); const hook = useAsyncAsHook(async () => { if (!parsedInitialAmount) return undefined; const balance = await api.wallet.call(WalletApiOperation.GetBalanceDetail, { currency: parsedInitialAmount.currency, }); return { balance }; }); const info = hook && !hook.hasError ? hook.response : undefined; // const initialCurrency = parsedInitialAmount?.currency; const [amount, setAmount] = useState( !parsedInitialAmount ? undefined : parsedInitialAmount, ); //FIXME: get this information from wallet // eslint-disable-next-line no-constant-condition const previous: Contact[] = true ? [] : [ { name: "International Bank", icon_type: "bank", description: "account ending with 3454", }, { name: "Max", icon_type: "bank", description: "account ending with 3454", }, { name: "Alex", icon_type: "bank", description: "account ending with 3454", }, ]; if (!amount) { return () => { // eslint-disable-next-line react-hooks/rules-of-hooks const { i18n } = useTranslationContext(); // eslint-disable-next-line react-hooks/rules-of-hooks const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListExchanges, {}), ); if (!hook) { return { status: "loading", error: undefined, }; } if (hook.hasError) { return { status: "error", error: alertFromError(i18n, i18n.str`Could not load exchanges`, hook), }; } const currencies: Record = {}; hook.response.exchanges.forEach((e) => { if (e.currency) { currencies[e.currency] = e.currency; } }); currencies[""] = "Select a currency"; return { status: "select-currency", error: undefined, onCurrencySelected: (c: string) => { setAmount(Amounts.zeroOfCurrency(c)); }, currencies, }; }; } const currencyAndAmount = Amounts.stringify(amount); const invalid = Amounts.isZero(amount); switch (props.type) { case "send": return { status: "ready", error: undefined, previous, selectCurrency: { onClick: pushAlertOnError(async () => { setAmount(undefined); }), }, goToBank: { onClick: invalid ? undefined : pushAlertOnError(async () => { props.goToWalletBankDeposit(currencyAndAmount); }), }, selectMax: { onClick: pushAlertOnError(async () => { const resp = await api.wallet.call( WalletApiOperation.GetMaxDepositAmount, { currency: amount.currency, }, ); setAmount(Amounts.parseOrThrow(resp.effectiveAmount)); }), }, goToWallet: { onClick: invalid ? undefined : pushAlertOnError(async () => { props.goToWalletWalletSend(currencyAndAmount); }), }, amountHandler: { onInput: pushAlertOnError(async (s) => setAmount(s)), value: amount, }, type: props.type, }; case "get": return { status: "ready", error: undefined, previous, selectCurrency: { onClick: pushAlertOnError(async () => { setAmount(undefined); }), }, selectMax: { onClick: invalid ? undefined : pushAlertOnError(async () => { props.goToWalletManualWithdraw(currencyAndAmount); }), }, goToBank: { onClick: invalid ? undefined : pushAlertOnError(async () => { props.goToWalletManualWithdraw(currencyAndAmount); }), }, goToWallet: { onClick: invalid ? undefined : pushAlertOnError(async () => { props.goToWalletWalletInvoice(currencyAndAmount); }), }, amountHandler: { onInput: pushAlertOnError(async (s) => setAmount(s)), value: amount, }, type: props.type, }; default: assertUnreachable(props); } }