/* 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 { AmountJson, Amounts } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { ErrorMessage } from "../components/ErrorMessage"; import { SelectList } from "../components/SelectList"; import { BoldLight, ButtonPrimary, Centered, Input, InputWithLabel, LightText, LinkPrimary, } from "../components/styled"; import { useTranslationContext } from "../context/translation"; import { Pages } from "../NavigationBar"; export interface Props { error: string | undefined; initialAmount?: string; exchangeUrlWithCurrency: Record; onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise; initialCurrency?: string; } export interface State { noExchangeFound: boolean; parsedAmount: AmountJson | undefined; amount: TextFieldHandler; currency: SelectFieldHandler; exchange: SelectFieldHandler; } export interface TextFieldHandler { onInput: (value: string) => void; value: string; } export interface SelectFieldHandler { onChange: (value: string) => void; value: string; list: Record; } export function useComponentState( exchangeUrlWithCurrency: Record, initialAmount: string | undefined, initialCurrency: string | undefined, ): State { const exchangeSelectList = Object.keys(exchangeUrlWithCurrency); const currencySelectList = Object.values(exchangeUrlWithCurrency); const exchangeMap = exchangeSelectList.reduce( (p, c) => ({ ...p, [c]: `${c} (${exchangeUrlWithCurrency[c]})` }), {} as Record, ); const currencyMap = currencySelectList.reduce( (p, c) => ({ ...p, [c]: c }), {} as Record, ); const foundExchangeForCurrency = exchangeSelectList.findIndex( (e) => exchangeUrlWithCurrency[e] === initialCurrency, ); const initialExchange = foundExchangeForCurrency !== -1 ? exchangeSelectList[foundExchangeForCurrency] : !initialCurrency && exchangeSelectList.length > 0 ? exchangeSelectList[0] : undefined; const [exchange, setExchange] = useState(initialExchange || ""); const [currency, setCurrency] = useState( initialExchange ? exchangeUrlWithCurrency[initialExchange] : "", ); const [amount, setAmount] = useState(initialAmount || ""); const parsedAmount = Amounts.parse(`${currency}:${amount}`); function changeExchange(exchange: string): void { setExchange(exchange); setCurrency(exchangeUrlWithCurrency[exchange]); } function changeCurrency(currency: string): void { setCurrency(currency); const found = Object.entries(exchangeUrlWithCurrency).find( (e) => e[1] === currency, ); if (found) { setExchange(found[0]); } else { setExchange(""); } } return { noExchangeFound: initialExchange === undefined, currency: { list: currencyMap, value: currency, onChange: changeCurrency, }, exchange: { list: exchangeMap, value: exchange, onChange: changeExchange, }, amount: { value: amount, onInput: (e: string) => setAmount(e), }, parsedAmount, }; } export interface InputHandler { value: string; onInput: (s: string) => void; } export interface SelectInputHandler { list: Record; value: string; onChange: (s: string) => void; } export function CreateManualWithdraw({ initialAmount, exchangeUrlWithCurrency, error, initialCurrency, onCreate, }: Props): VNode { const { i18n } = useTranslationContext(); const state = useComponentState( exchangeUrlWithCurrency, initialAmount, initialCurrency, ); if (state.noExchangeFound) { if (initialCurrency !== undefined) { return (

Manual Withdrawal for {initialCurrency}

Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject. No exchange found for {initialCurrency} Add Exchange
); } return (

Manual Withdrawal

Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject. No exchange configured Add Exchange
); } return (
{error && ( Can't create the reserve} description={error} /> )}

Manual Withdrawal

Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.

Currency} name="currency" {...state.currency} /> Exchange} name="exchange" {...state.exchange} />

Add Exchange
{state.currency.value && (
{state.currency.value} state.amount.onInput(e.currentTarget.value)} />
)}

); }