/* 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 { styled } from "@linaria/react"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { Loading } from "../components/Loading.js"; import { LoadingError } from "../components/LoadingError.js"; import { SelectList } from "../components/SelectList.js"; import { Input, LightText, LinkPrimary, SvgIcon, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; import { Grid } from "../mui/Grid.js"; import { Paper } from "../mui/Paper.js"; import { TextField } from "../mui/TextField.js"; import { Pages } from "../NavigationBar.js"; import arrowIcon from "../svg/chevron-down.svg"; import bankIcon from "../svg/ri-bank-line.svg"; import * as wxApi from "../wxApi.js"; const Container = styled.div` display: flex; flex-direction: column; & > * { margin: 8px; } `; interface PropsGet { amount?: string; goToWalletManualWithdraw: (amount: string) => void; goToWalletWalletInvoice: (amount: string) => void; } interface PropsSend { amount?: string; goToWalletBankDeposit: (amount: string) => void; goToWalletWalletSend: (amount: string) => void; } type Contact = { icon: string; name: string; description: string; }; const ContactTable = styled.table` width: 100%; & > tr > td { padding: 8px; & > div:not([data-disabled]):hover { background-color: lightblue; } color: black; div[data-disabled] > * { color: gray; } } & > tr:nth-child(2n) { background: #ebebeb; } `; const MediaExample = styled.div` text-size-adjust: 100%; color: inherit; font-family: inherit; font-size: inherit; line-height: inherit; text-transform: none; text-align: left; box-sizing: border-box; align-items: center; display: flex; padding: 8px 8px; &[data-disabled]:hover { cursor: inherit; } cursor: pointer; `; const MediaLeft = styled.div` text-size-adjust: 100%; color: inherit; font-family: inherit; font-size: inherit; line-height: inherit; text-transform: none; text-align: left; box-sizing: border-box; padding-right: 8px; display: block; `; const MediaBody = styled.div` text-size-adjust: 100%; font-family: inherit; text-transform: none; text-align: left; box-sizing: border-box; flex: 1 1; font-size: 14px; font-weight: 500; line-height: 1.42857; `; const MediaRight = styled.div` text-size-adjust: 100%; color: inherit; font-family: inherit; font-size: inherit; line-height: inherit; text-transform: none; text-align: left; box-sizing: border-box; padding-left: 8px; `; const CircleDiv = styled.div` box-sizing: border-box; align-items: center; background-position: 50%; background-repeat: no-repeat; background-size: cover; border-radius: 50%; display: flex; justify-content: center; margin-left: auto; margin-right: auto; overflow: hidden; text-align: center; text-decoration: none; text-transform: uppercase; transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease; font-size: 16px; background-color: #86a7bd1a; height: 40px; line-height: 40px; width: 40px; border: none; `; export function SelectCurrency({ onChange, }: { onChange: (s: string) => void; }): VNode { const { i18n } = useTranslationContext(); const hook = useAsyncAsHook(wxApi.listExchanges); if (!hook) { return ; } if (hook.hasError) { return ( Could not load list of exchange} /> ); } const list: Record = {}; hook.response.exchanges.forEach((e) => (list[e.currency] = e.currency)); list[""] = "Select a currency"; return ; } export function SelectCurrencyView({ onChange, list, }: { onChange: (s: string) => void; list: Record; }): VNode { const { i18n } = useTranslationContext(); return ( Choose a currency to proceed or add another exchange Known currencies} list={list} name="lang" value={""} onChange={(v) => onChange(v)} /> Add an exchange ); } function RowExample({ info, disabled, }: { info: Contact; disabled?: boolean; }): VNode { return ( {info.name} {info.description} ); } export function DestinationSelectionGetCash({ amount: initialAmount, goToWalletManualWithdraw, goToWalletWalletInvoice, }: PropsGet): VNode { const parsedInitialAmount = !initialAmount ? undefined : Amounts.parse(initialAmount); const parsedInitialAmountValue = !parsedInitialAmount ? "0" : Amounts.stringifyValue(parsedInitialAmount); const [currency, setCurrency] = useState(parsedInitialAmount?.currency); const [amount, setAmount] = useState(parsedInitialAmountValue); const { i18n } = useTranslationContext(); const previous1: Contact[] = []; const previous2: Contact[] = [ { name: "International Bank", icon: bankIcon, description: "account ending with 3454", }, { name: "Max", icon: bankIcon, description: "account ending with 3454", }, { name: "Alex", icon: bankIcon, description: "account ending with 3454", }, ]; const previous = previous1; if (!currency) { return ( setCurrency(c)} /> ); } const currencyAndAmount = `${currency}:${amount}`; const parsedAmount = Amounts.parse(currencyAndAmount); // const dirty = parsedInitialAmountValue !== amount; const invalid = !parsedAmount || Amounts.isZero(parsedAmount); return ( Specify the amount and the origin {currency} } value={amount} onChange={(e) => { setAmount(e); }} /> setCurrency(undefined)}> Change currency {previous.length > 0 ? ( Use previous origins: {previous.map((info, i) => ( ))} ) : undefined} {previous.length > 0 ? ( Or specify the origin of the money ) : ( Specify the origin of the money )} From my bank account goToWalletManualWithdraw(currencyAndAmount) } > Withdraw From another wallet goToWalletWalletInvoice(currencyAndAmount)} > Invoice ); } export function DestinationSelectionSendCash({ amount: initialAmount, goToWalletBankDeposit, goToWalletWalletSend, }: PropsSend): VNode { const parsedInitialAmount = !initialAmount ? undefined : Amounts.parse(initialAmount); const parsedInitialAmountValue = !parsedInitialAmount ? "" : Amounts.stringifyValue(parsedInitialAmount); const currency = parsedInitialAmount?.currency; const [amount, setAmount] = useState(parsedInitialAmountValue); const { i18n } = useTranslationContext(); const previous1: Contact[] = []; const previous2: Contact[] = [ { name: "International Bank", icon: bankIcon, description: "account ending with 3454", }, { name: "Max", icon: bankIcon, description: "account ending with 3454", }, { name: "Alex", icon: bankIcon, description: "account ending with 3454", }, ]; const previous = previous1; if (!currency) { return ( currency not provided ); } const currencyAndAmount = `${currency}:${amount}`; const parsedAmount = Amounts.parse(currencyAndAmount); const invalid = !parsedAmount || Amounts.isZero(parsedAmount); return ( Specify the amount and the destination {currency} } value={amount} onChange={(e) => { setAmount(e); }} /> {previous.length > 0 ? ( Use previous destinations: {previous.map((info, i) => ( ))} ) : undefined} {previous.length > 0 ? ( Or specify the destination of the money ) : ( Specify the destination of the money )} To my bank account goToWalletBankDeposit(currencyAndAmount)} > Deposit To another wallet goToWalletWalletSend(currencyAndAmount)} > Send ); }
Known currencies} list={list} name="lang" value={""} onChange={(v) => onChange(v)} />
Use previous origins:
Or specify the origin of the money
Specify the origin of the money
From my bank account
From another wallet
Use previous destinations:
Or specify the destination of the money
Specify the destination of the money
To my bank account
To another wallet