aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta/Withdraw
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-06-27 08:20:49 -0300
committerSebastian <sebasjm@gmail.com>2023-06-27 08:21:03 -0300
commit97a9e92d8b104a94c376ae4fad8c5c811f5ef7e1 (patch)
treedee1f4e8861298d5bdf3987fcd24824bd7a6d3cf /packages/taler-wallet-webextension/src/cta/Withdraw
parent18a3d764deb534dfa0f46981539ec4119dcc6c0f (diff)
downloadwallet-core-97a9e92d8b104a94c376ae4fad8c5c811f5ef7e1.tar.xz
set amount for manual withdraw when the qr does not have it
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/Withdraw')
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/index.ts21
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/state.ts83
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx40
3 files changed, 129 insertions, 15 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
index ae4b3c436..f80e5a648 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
@@ -14,10 +14,18 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { AmountJson, ExchangeListItem } from "@gnu-taler/taler-util";
+import {
+ AmountJson,
+ AmountString,
+ ExchangeListItem,
+} from "@gnu-taler/taler-util";
import { Loading } from "../../components/Loading.js";
import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js";
-import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js";
+import {
+ AmountFieldHandler,
+ ButtonHandler,
+ SelectFieldHandler,
+} from "../../mui/handlers.js";
import { StateViewMap, compose } from "../../utils/index.js";
import {
useComponentStateFromParams,
@@ -37,10 +45,11 @@ export interface PropsFromURI {
}
export interface PropsFromParams {
- talerExchangeWithdrawUri: string;
- amount: string;
+ talerExchangeWithdrawUri: string | undefined;
+ amount: string | undefined;
cancel: () => Promise<void>;
onSuccess: (txid: string) => Promise<void>;
+ onAmountChanged: (amount: AmountString) => Promise<void>;
}
export type State =
@@ -64,7 +73,9 @@ export namespace State {
export interface SelectAmount {
status: "select-amount";
error: undefined;
- currentExchange: ExchangeListItem;
+ exchangeBaseUrl: string;
+ confirm: ButtonHandler;
+ amount: AmountFieldHandler;
currency: string;
}
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index f19f32ec0..46a72ac87 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -26,7 +26,7 @@ import {
stringifyWithdrawUri,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { useState } from "preact/hooks";
+import { useEffect, 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";
@@ -39,16 +39,20 @@ export function useComponentStateFromParams({
talerExchangeWithdrawUri: maybeTalerUri,
amount,
cancel,
+ onAmountChanged,
onSuccess,
}: PropsFromParams): RecursiveState<State> {
const api = useBackendContext();
const { i18n } = useTranslationContext();
+ const paramsAmount = amount ? Amounts.parse(amount) : undefined;
const uriInfoHook = useAsyncAsHook(async () => {
const exchanges = await api.wallet.call(
WalletApiOperation.ListExchanges,
{},
);
- const uri = parseWithdrawExchangeUri(maybeTalerUri);
+ const uri = maybeTalerUri
+ ? parseWithdrawExchangeUri(maybeTalerUri)
+ : undefined;
const exchangeByTalerUri = uri?.exchangeBaseUrl;
let ex: ExchangeFullDetails | undefined;
if (exchangeByTalerUri && uri.exchangePub) {
@@ -65,11 +69,8 @@ export function useComponentStateFromParams({
ex = info.exchange;
}
- const chosenAmount = uri
- ? uri.amount
- ? Amounts.parseOrThrow(uri.amount)
- : Amounts.parseOrThrow(`${ex ? ex.currency : "KUDOS"}:66`)
- : Amounts.parseOrThrow(amount);
+ const chosenAmount =
+ !uri || !uri.amount ? undefined : Amounts.parse(uri.amount);
return { amount: chosenAmount, exchanges, exchange: ex };
});
@@ -85,10 +86,76 @@ export function useComponentStateFromParams({
};
}
- const chosenAmount = uriInfoHook.response.amount;
+ useEffect(() => {
+ uriInfoHook?.retry();
+ }, [amount]);
+
const exchangeByTalerUri = uriInfoHook.response.exchange?.exchangeBaseUrl;
const exchangeList = uriInfoHook.response.exchanges.exchanges;
+ const maybeAmount = uriInfoHook.response.amount ?? paramsAmount;
+
+ if (!maybeAmount) {
+ const exchangeBaseUrl =
+ uriInfoHook.response.exchange?.exchangeBaseUrl ??
+ (exchangeList.length > 0 ? exchangeList[0].exchangeBaseUrl : undefined);
+ const currency =
+ uriInfoHook.response.exchange?.currency ??
+ (exchangeList.length > 0 ? exchangeList[0].currency : undefined);
+
+ if (!exchangeBaseUrl) {
+ return {
+ status: "error",
+ error: {
+ message: i18n.str`Can't withdraw from exchange`,
+ description: i18n.str`Missing base URL`,
+ cause: undefined,
+ context: {},
+ type: "error",
+ },
+ };
+ }
+ if (!currency) {
+ return {
+ status: "error",
+ error: {
+ message: i18n.str`Can't withdraw from exchange`,
+ description: i18n.str`Missing unknown currency`,
+ cause: undefined,
+ context: {},
+ type: "error",
+ },
+ };
+ }
+ return () => {
+ const { pushAlertOnError } = useAlertContext();
+ const [amount, setAmount] = useState<AmountJson>(
+ Amounts.zeroOfCurrency(currency),
+ );
+ const isValid = Amounts.isNonZero(amount);
+ return {
+ status: "select-amount",
+ currency,
+ exchangeBaseUrl,
+ error: undefined,
+ confirm: {
+ onClick: isValid
+ ? pushAlertOnError(async () => {
+ onAmountChanged(Amounts.stringify(amount));
+ })
+ : undefined,
+ },
+ amount: {
+ value: amount,
+ onInput: pushAlertOnError(async (e) => {
+ setAmount(e);
+ }),
+ },
+ };
+ };
+ }
+ const chosenAmount = maybeAmount;
+
async function doManualWithdraw(
exchange: string,
ageRestricted: number | undefined,
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
index 57d6238b2..8a01edaaf 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
@@ -32,6 +32,8 @@ import {
WithdrawDetails,
} from "../../wallet/Transaction.js";
import { State } from "./index.js";
+import { Grid } from "../../mui/Grid.js";
+import { AmountField } from "../../components/AmountField.js";
export function SuccessView(state: State.Success): VNode {
const { i18n } = useTranslationContext();
@@ -143,11 +145,45 @@ function WithdrawWithMobile({
);
}
-export function SelectAmountView({ currency }: State.SelectAmount): VNode {
+export function SelectAmountView({
+ currency,
+ amount,
+ exchangeBaseUrl,
+ confirm,
+}: State.SelectAmount): VNode {
const { i18n } = useTranslationContext();
return (
<Fragment>
- <p>select the amount for ${currency}</p>
+ <section style={{ textAlign: "left" }}>
+ <Part
+ title={
+ <div
+ style={{
+ display: "flex",
+ alignItems: "center",
+ }}
+ >
+ <i18n.Translate>Exchange</i18n.Translate>
+ </div>
+ }
+ text={<ExchangeDetails exchange={exchangeBaseUrl} />}
+ kind="neutral"
+ big
+ />
+ <Grid container columns={2} justifyContent="space-between">
+ <AmountField label={i18n.str`Amount`} required handler={amount} />
+ </Grid>
+ </section>
+ <section>
+ <Button
+ variant="contained"
+ color="info"
+ disabled={!confirm.onClick}
+ onClick={confirm.onClick}
+ >
+ <i18n.Translate>See details</i18n.Translate>
+ </Button>
+ </section>
</Fragment>
);
}