From 7a2fe8018faa4666ff681072682f16f8fb1bfc13 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 4 May 2022 16:25:53 -0300 Subject: add age restriction option to withdraw cta --- .../src/cta/Pay.stories.tsx | 36 +++++++++++++++ packages/taler-wallet-webextension/src/cta/Pay.tsx | 27 ++++++----- .../src/cta/Withdraw.stories.tsx | 53 ++++++++++++++++++++++ .../taler-wallet-webextension/src/cta/Withdraw.tsx | 38 +++++++++++++++- 4 files changed, 139 insertions(+), 15 deletions(-) (limited to 'packages/taler-wallet-webextension/src/cta') diff --git a/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx b/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx index 3656bbbd4..76bfa3ab3 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx @@ -101,6 +101,42 @@ export const NoEnoughBalance = createExample(TestedComponent, { goToWalletManualWithdraw: () => null, }); +export const EnoughBalanceButRestricted = createExample(TestedComponent, { + state: { + status: "ready", + hook: undefined, + amount: Amounts.parseOrThrow("USD:10"), + balance: { + currency: "USD", + fraction: 40000000, + value: 19, + }, + payHandler: { + onClick: async () => { + null; + }, + }, + totalFees: Amounts.parseOrThrow("USD:0"), + payResult: undefined, + uri: "", + payStatus: { + status: PreparePayResultType.InsufficientBalance, + noncePriv: "", + proposalId: "proposal1234", + contractTerms: { + merchant: { + name: "someone", + }, + summary: "some beers", + amount: "USD:10", + } as Partial as any, + amountRaw: "USD:10", + }, + }, + goBack: () => null, + goToWalletManualWithdraw: () => null, +}); + export const PaymentPossible = createExample(TestedComponent, { state: { status: "ready", diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx index 0e2530149..4f44ebab2 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx @@ -542,23 +542,22 @@ function ButtonsSection({ ); } if (payStatus.status === PreparePayResultType.InsufficientBalance) { + let BalanceMessage = ""; + if (!state.balance) { + BalanceMessage = i18n.str`You have no balance for this currency. Withdraw digital cash first.`; + } else { + const balanceShouldBeEnough = + Amounts.cmp(state.balance, state.amount) !== -1; + if (balanceShouldBeEnough) { + BalanceMessage = i18n.str`Could not find enough coins to pay this order. Even if you have enough ${state.balance.currency} some restriction may apply.`; + } else { + BalanceMessage = i18n.str`Your current balance is not enough for this order.`; + } + } return (
- {state.balance ? ( - - - Your balance of {} is not - enough to pay for this purchase - - - ) : ( - - - Your balance is not enough to pay for this purchase. - - - )} + {BalanceMessage}
= "6:12:18" + .split(":") + .reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {}); + +ageRestrictionOptions["0"] = "Not restricted"; + +const ageRestrictionSelectField = { + list: ageRestrictionOptions, + value: "0", +}; + export const TermsOfServiceNotYetLoaded = createExample(TestedComponent, { state: { hook: undefined, status: "success", cancelEditExchange: nullHandler, confirmEditExchange: nullHandler, + ageRestriction: ageRestrictionSelectField, chosenAmount: { currency: "USD", value: 2, @@ -91,6 +103,7 @@ export const WithSomeFee = createExample(TestedComponent, { status: "success", cancelEditExchange: nullHandler, confirmEditExchange: nullHandler, + ageRestriction: ageRestrictionSelectField, chosenAmount: { currency: "USD", value: 2, @@ -127,6 +140,7 @@ export const WithoutFee = createExample(TestedComponent, { status: "success", cancelEditExchange: nullHandler, confirmEditExchange: nullHandler, + ageRestriction: ageRestrictionSelectField, chosenAmount: { currency: "USD", value: 2, @@ -163,6 +177,7 @@ export const EditExchangeUntouched = createExample(TestedComponent, { status: "success", cancelEditExchange: nullHandler, confirmEditExchange: nullHandler, + ageRestriction: ageRestrictionSelectField, chosenAmount: { currency: "USD", value: 2, @@ -199,6 +214,7 @@ export const EditExchangeModified = createExample(TestedComponent, { status: "success", cancelEditExchange: nullHandler, confirmEditExchange: nullHandler, + ageRestriction: ageRestrictionSelectField, chosenAmount: { currency: "USD", value: 2, @@ -236,3 +252,40 @@ export const CompletedWithoutBankURL = createExample(TestedComponent, { hook: undefined, }, }); + +export const WithAgeRestrictionSelected = createExample(TestedComponent, { + state: { + hook: undefined, + status: "success", + cancelEditExchange: nullHandler, + confirmEditExchange: nullHandler, + ageRestriction: ageRestrictionSelectField, + chosenAmount: { + currency: "USD", + value: 2, + fraction: 10000000, + }, + doWithdrawal: nullHandler, + editExchange: nullHandler, + exchange: { + list: exchangeList, + value: "exchange.demo.taler.net", + onChange: async () => { + null; + }, + }, + showExchangeSelection: false, + mustAcceptFirst: false, + withdrawalFee: { + currency: "USD", + fraction: 0, + value: 0, + }, + toBeReceived: { + currency: "USD", + fraction: 0, + value: 2, + }, + tosProps: normalTosState, + }, +}); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx index cd0ba2cc3..c4bc3457a 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx @@ -35,6 +35,7 @@ import { SelectList } from "../components/SelectList.js"; import { ButtonSuccess, ButtonWarning, + Input, LinkSuccess, SubTitle, SuccessBox, @@ -43,12 +44,18 @@ import { import { useTranslationContext } from "../context/translation.js"; import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { buildTermsOfServiceState } from "../utils/index.js"; -import { ButtonHandler, SelectFieldHandler } from "../mui/handlers.js"; +import { + ButtonHandler, + SelectFieldHandler, + ToggleHandler, +} from "../mui/handlers.js"; import * as wxApi from "../wxApi.js"; import { Props as TermsOfServiceSectionProps, TermsOfServiceSection, } from "./TermsOfServiceSection.js"; +import { startOfWeekYear } from "date-fns/esm"; +import { Checkbox } from "../components/Checkbox.js"; interface Props { talerWithdrawUri?: string; @@ -97,6 +104,8 @@ type Success = { doWithdrawal: ButtonHandler; tosProps?: TermsOfServiceSectionProps; mustAcceptFirst: boolean; + + ageRestriction: SelectFieldHandler; }; export function useComponentState( @@ -106,6 +115,7 @@ export function useComponentState( const [customExchange, setCustomExchange] = useState( undefined, ); + const [ageRestricted, setAgeRestricted] = useState(0); /** * Ask the wallet about the withdraw URI @@ -228,6 +238,7 @@ export function useComponentState( const res = await api.acceptWithdrawal( talerWithdrawUri, selectedExchange, + !ageRestricted ? undefined : ageRestricted, ); if (res.confirmTransferUrl) { document.location.href = res.confirmTransferUrl; @@ -320,6 +331,14 @@ export function useComponentState( termsState !== undefined && (termsState.status === "changed" || termsState.status === "new"); + const ageRestrictionOptions: Record | undefined = "6:12:18" + .split(":") + .reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {}); + + if (ageRestrictionOptions) { + ageRestrictionOptions["0"] = "Not restricted"; + } + return { status: "success", hook: undefined, @@ -331,6 +350,11 @@ export function useComponentState( toBeReceived, withdrawalFee, chosenAmount: amount, + ageRestriction: { + list: ageRestrictionOptions, + value: String(ageRestricted), + onChange: async (v) => setAgeRestricted(parseInt(v, 10)), + }, doWithdrawal: { onClick: doingWithdraw || (mustAcceptFirst && !reviewed) @@ -486,6 +510,18 @@ export function View({ state }: { state: State }): VNode { )}
+
+ + Age restriction} + list={state.ageRestriction.list} + name="age" + maxWidth + value={state.ageRestriction.value} + onChange={state.ageRestriction.onChange} + /> + +
{state.tosProps && } {state.tosProps ? (
-- cgit v1.2.3