add age restriction option to withdraw cta
This commit is contained in:
parent
4491118494
commit
7a2fe8018f
@ -17,8 +17,8 @@
|
|||||||
import { h, VNode } from "preact";
|
import { h, VNode } from "preact";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
enabled: boolean;
|
enabled?: boolean;
|
||||||
onToggle: () => void;
|
onToggle?: () => void;
|
||||||
label: VNode;
|
label: VNode;
|
||||||
name: string;
|
name: string;
|
||||||
description?: VNode;
|
description?: VNode;
|
||||||
|
@ -20,7 +20,7 @@ import { NiceSelect } from "./styled/index.js";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value?: string;
|
value?: string;
|
||||||
onChange: (s: string) => void;
|
onChange?: (s: string) => void;
|
||||||
label: VNode;
|
label: VNode;
|
||||||
list: {
|
list: {
|
||||||
[label: string]: string;
|
[label: string]: string;
|
||||||
@ -28,6 +28,7 @@ interface Props {
|
|||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
canBeNull?: boolean;
|
canBeNull?: boolean;
|
||||||
|
maxWidth?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SelectList({
|
export function SelectList({
|
||||||
@ -36,6 +37,7 @@ export function SelectList({
|
|||||||
list,
|
list,
|
||||||
onChange,
|
onChange,
|
||||||
label,
|
label,
|
||||||
|
maxWidth,
|
||||||
description,
|
description,
|
||||||
canBeNull,
|
canBeNull,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
@ -53,8 +55,9 @@ export function SelectList({
|
|||||||
<select
|
<select
|
||||||
name={name}
|
name={name}
|
||||||
value={value}
|
value={value}
|
||||||
|
style={maxWidth ? { width: "100%" } : undefined}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onChange(e.currentTarget.value);
|
if (onChange) onChange(e.currentTarget.value);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{value === undefined ||
|
{value === undefined ||
|
||||||
|
@ -101,6 +101,42 @@ export const NoEnoughBalance = createExample(TestedComponent, {
|
|||||||
goToWalletManualWithdraw: () => null,
|
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<ContractTerms> as any,
|
||||||
|
amountRaw: "USD:10",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
goBack: () => null,
|
||||||
|
goToWalletManualWithdraw: () => null,
|
||||||
|
});
|
||||||
|
|
||||||
export const PaymentPossible = createExample(TestedComponent, {
|
export const PaymentPossible = createExample(TestedComponent, {
|
||||||
state: {
|
state: {
|
||||||
status: "ready",
|
status: "ready",
|
||||||
|
@ -542,23 +542,22 @@ function ButtonsSection({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (payStatus.status === PreparePayResultType.InsufficientBalance) {
|
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 (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<section>
|
<section>
|
||||||
{state.balance ? (
|
<WarningBox>{BalanceMessage}</WarningBox>
|
||||||
<WarningBox>
|
|
||||||
<i18n.Translate>
|
|
||||||
Your balance of {<Amount value={state.balance} />} is not
|
|
||||||
enough to pay for this purchase
|
|
||||||
</i18n.Translate>
|
|
||||||
</WarningBox>
|
|
||||||
) : (
|
|
||||||
<WarningBox>
|
|
||||||
<i18n.Translate>
|
|
||||||
Your balance is not enough to pay for this purchase.
|
|
||||||
</i18n.Translate>
|
|
||||||
</WarningBox>
|
|
||||||
)}
|
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess
|
<ButtonSuccess
|
||||||
|
@ -50,12 +50,24 @@ const normalTosState = {
|
|||||||
reviewing: false,
|
reviewing: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ageRestrictionOptions: Record<string, string> = "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, {
|
export const TermsOfServiceNotYetLoaded = createExample(TestedComponent, {
|
||||||
state: {
|
state: {
|
||||||
hook: undefined,
|
hook: undefined,
|
||||||
status: "success",
|
status: "success",
|
||||||
cancelEditExchange: nullHandler,
|
cancelEditExchange: nullHandler,
|
||||||
confirmEditExchange: nullHandler,
|
confirmEditExchange: nullHandler,
|
||||||
|
ageRestriction: ageRestrictionSelectField,
|
||||||
chosenAmount: {
|
chosenAmount: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
value: 2,
|
value: 2,
|
||||||
@ -91,6 +103,7 @@ export const WithSomeFee = createExample(TestedComponent, {
|
|||||||
status: "success",
|
status: "success",
|
||||||
cancelEditExchange: nullHandler,
|
cancelEditExchange: nullHandler,
|
||||||
confirmEditExchange: nullHandler,
|
confirmEditExchange: nullHandler,
|
||||||
|
ageRestriction: ageRestrictionSelectField,
|
||||||
chosenAmount: {
|
chosenAmount: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
value: 2,
|
value: 2,
|
||||||
@ -127,6 +140,7 @@ export const WithoutFee = createExample(TestedComponent, {
|
|||||||
status: "success",
|
status: "success",
|
||||||
cancelEditExchange: nullHandler,
|
cancelEditExchange: nullHandler,
|
||||||
confirmEditExchange: nullHandler,
|
confirmEditExchange: nullHandler,
|
||||||
|
ageRestriction: ageRestrictionSelectField,
|
||||||
chosenAmount: {
|
chosenAmount: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
value: 2,
|
value: 2,
|
||||||
@ -163,6 +177,7 @@ export const EditExchangeUntouched = createExample(TestedComponent, {
|
|||||||
status: "success",
|
status: "success",
|
||||||
cancelEditExchange: nullHandler,
|
cancelEditExchange: nullHandler,
|
||||||
confirmEditExchange: nullHandler,
|
confirmEditExchange: nullHandler,
|
||||||
|
ageRestriction: ageRestrictionSelectField,
|
||||||
chosenAmount: {
|
chosenAmount: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
value: 2,
|
value: 2,
|
||||||
@ -199,6 +214,7 @@ export const EditExchangeModified = createExample(TestedComponent, {
|
|||||||
status: "success",
|
status: "success",
|
||||||
cancelEditExchange: nullHandler,
|
cancelEditExchange: nullHandler,
|
||||||
confirmEditExchange: nullHandler,
|
confirmEditExchange: nullHandler,
|
||||||
|
ageRestriction: ageRestrictionSelectField,
|
||||||
chosenAmount: {
|
chosenAmount: {
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
value: 2,
|
value: 2,
|
||||||
@ -236,3 +252,40 @@ export const CompletedWithoutBankURL = createExample(TestedComponent, {
|
|||||||
hook: undefined,
|
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,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
@ -35,6 +35,7 @@ import { SelectList } from "../components/SelectList.js";
|
|||||||
import {
|
import {
|
||||||
ButtonSuccess,
|
ButtonSuccess,
|
||||||
ButtonWarning,
|
ButtonWarning,
|
||||||
|
Input,
|
||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
SubTitle,
|
SubTitle,
|
||||||
SuccessBox,
|
SuccessBox,
|
||||||
@ -43,12 +44,18 @@ import {
|
|||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
import { buildTermsOfServiceState } from "../utils/index.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 * as wxApi from "../wxApi.js";
|
||||||
import {
|
import {
|
||||||
Props as TermsOfServiceSectionProps,
|
Props as TermsOfServiceSectionProps,
|
||||||
TermsOfServiceSection,
|
TermsOfServiceSection,
|
||||||
} from "./TermsOfServiceSection.js";
|
} from "./TermsOfServiceSection.js";
|
||||||
|
import { startOfWeekYear } from "date-fns/esm";
|
||||||
|
import { Checkbox } from "../components/Checkbox.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talerWithdrawUri?: string;
|
talerWithdrawUri?: string;
|
||||||
@ -97,6 +104,8 @@ type Success = {
|
|||||||
doWithdrawal: ButtonHandler;
|
doWithdrawal: ButtonHandler;
|
||||||
tosProps?: TermsOfServiceSectionProps;
|
tosProps?: TermsOfServiceSectionProps;
|
||||||
mustAcceptFirst: boolean;
|
mustAcceptFirst: boolean;
|
||||||
|
|
||||||
|
ageRestriction: SelectFieldHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useComponentState(
|
export function useComponentState(
|
||||||
@ -106,6 +115,7 @@ export function useComponentState(
|
|||||||
const [customExchange, setCustomExchange] = useState<string | undefined>(
|
const [customExchange, setCustomExchange] = useState<string | undefined>(
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
|
const [ageRestricted, setAgeRestricted] = useState(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the wallet about the withdraw URI
|
* Ask the wallet about the withdraw URI
|
||||||
@ -228,6 +238,7 @@ export function useComponentState(
|
|||||||
const res = await api.acceptWithdrawal(
|
const res = await api.acceptWithdrawal(
|
||||||
talerWithdrawUri,
|
talerWithdrawUri,
|
||||||
selectedExchange,
|
selectedExchange,
|
||||||
|
!ageRestricted ? undefined : ageRestricted,
|
||||||
);
|
);
|
||||||
if (res.confirmTransferUrl) {
|
if (res.confirmTransferUrl) {
|
||||||
document.location.href = res.confirmTransferUrl;
|
document.location.href = res.confirmTransferUrl;
|
||||||
@ -320,6 +331,14 @@ export function useComponentState(
|
|||||||
termsState !== undefined &&
|
termsState !== undefined &&
|
||||||
(termsState.status === "changed" || termsState.status === "new");
|
(termsState.status === "changed" || termsState.status === "new");
|
||||||
|
|
||||||
|
const ageRestrictionOptions: Record<string, string> | undefined = "6:12:18"
|
||||||
|
.split(":")
|
||||||
|
.reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {});
|
||||||
|
|
||||||
|
if (ageRestrictionOptions) {
|
||||||
|
ageRestrictionOptions["0"] = "Not restricted";
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: "success",
|
status: "success",
|
||||||
hook: undefined,
|
hook: undefined,
|
||||||
@ -331,6 +350,11 @@ export function useComponentState(
|
|||||||
toBeReceived,
|
toBeReceived,
|
||||||
withdrawalFee,
|
withdrawalFee,
|
||||||
chosenAmount: amount,
|
chosenAmount: amount,
|
||||||
|
ageRestriction: {
|
||||||
|
list: ageRestrictionOptions,
|
||||||
|
value: String(ageRestricted),
|
||||||
|
onChange: async (v) => setAgeRestricted(parseInt(v, 10)),
|
||||||
|
},
|
||||||
doWithdrawal: {
|
doWithdrawal: {
|
||||||
onClick:
|
onClick:
|
||||||
doingWithdraw || (mustAcceptFirst && !reviewed)
|
doingWithdraw || (mustAcceptFirst && !reviewed)
|
||||||
@ -486,6 +510,18 @@ export function View({ state }: { state: State }): VNode {
|
|||||||
</LinkSuccess>
|
</LinkSuccess>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<Input>
|
||||||
|
<SelectList
|
||||||
|
label={<i18n.Translate>Age restriction</i18n.Translate>}
|
||||||
|
list={state.ageRestriction.list}
|
||||||
|
name="age"
|
||||||
|
maxWidth
|
||||||
|
value={state.ageRestriction.value}
|
||||||
|
onChange={state.ageRestriction.onChange}
|
||||||
|
/>
|
||||||
|
</Input>
|
||||||
|
</section>
|
||||||
{state.tosProps && <TermsOfServiceSection {...state.tosProps} />}
|
{state.tosProps && <TermsOfServiceSection {...state.tosProps} />}
|
||||||
{state.tosProps ? (
|
{state.tosProps ? (
|
||||||
<section>
|
<section>
|
||||||
|
@ -17,7 +17,7 @@ export interface ToggleHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SelectFieldHandler {
|
export interface SelectFieldHandler {
|
||||||
onChange: (value: string) => Promise<void>;
|
onChange?: (value: string) => Promise<void>;
|
||||||
error?: string;
|
error?: string;
|
||||||
value: string;
|
value: string;
|
||||||
isDirty?: boolean;
|
isDirty?: boolean;
|
||||||
|
@ -87,7 +87,7 @@ describe("CreateManualWithdraw states", () => {
|
|||||||
const { exchange, currency } = getLastResultOrThrow()
|
const { exchange, currency } = getLastResultOrThrow()
|
||||||
|
|
||||||
expect(exchange.value).equal("url2")
|
expect(exchange.value).equal("url2")
|
||||||
|
if (currency.onChange === undefined) expect.fail();
|
||||||
currency.onChange("USD")
|
currency.onChange("USD")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +111,7 @@ describe("CreateManualWithdraw states", () => {
|
|||||||
expect(exchange.value).equal("url2")
|
expect(exchange.value).equal("url2")
|
||||||
expect(currency.value).equal("ARS")
|
expect(currency.value).equal("ARS")
|
||||||
|
|
||||||
|
if (exchange.onChange === undefined) expect.fail();
|
||||||
exchange.onChange("url1")
|
exchange.onChange("url1")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +206,7 @@ async function defaultTestForInputSelect(awaiter: () => Promise<void>, getField:
|
|||||||
throw new Error('no enough values')
|
throw new Error('no enough values')
|
||||||
}
|
}
|
||||||
nextValue = keys[nextIdx]
|
nextValue = keys[nextIdx]
|
||||||
|
if (field.onChange === undefined) expect.fail();
|
||||||
field.onChange(nextValue)
|
field.onChange(nextValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +258,7 @@ describe("DepositPage states", () => {
|
|||||||
expect(r.depositHandler.onClick).undefined;
|
expect(r.depositHandler.onClick).undefined;
|
||||||
expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`))
|
expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`))
|
||||||
|
|
||||||
|
if (r.account.onChange === undefined) expect.fail();
|
||||||
r.account.onChange("1")
|
r.account.onChange("1")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,6 +291,7 @@ describe("DepositPage states", () => {
|
|||||||
expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`))
|
expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`))
|
||||||
expect(r.depositHandler.onClick).undefined;
|
expect(r.depositHandler.onClick).undefined;
|
||||||
|
|
||||||
|
if (r.account.onChange === undefined) expect.fail();
|
||||||
r.account.onChange("0")
|
r.account.onChange("0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ export function DeveloperPage(): VNode {
|
|||||||
|
|
||||||
type CoinsInfo = CoinDumpJson["coins"];
|
type CoinsInfo = CoinDumpJson["coins"];
|
||||||
type CalculatedCoinfInfo = {
|
type CalculatedCoinfInfo = {
|
||||||
|
ageKeysCount: number | undefined;
|
||||||
denom_value: number;
|
denom_value: number;
|
||||||
remain_value: number;
|
remain_value: number;
|
||||||
status: string;
|
status: string;
|
||||||
@ -132,11 +133,13 @@ export function View({
|
|||||||
const money_by_exchange = coins.reduce(
|
const money_by_exchange = coins.reduce(
|
||||||
(prev, cur) => {
|
(prev, cur) => {
|
||||||
const denom = Amounts.parseOrThrow(cur.denom_value);
|
const denom = Amounts.parseOrThrow(cur.denom_value);
|
||||||
|
console.log(cur);
|
||||||
if (!prev[cur.exchange_base_url]) {
|
if (!prev[cur.exchange_base_url]) {
|
||||||
prev[cur.exchange_base_url] = [];
|
prev[cur.exchange_base_url] = [];
|
||||||
currencies[cur.exchange_base_url] = denom.currency;
|
currencies[cur.exchange_base_url] = denom.currency;
|
||||||
}
|
}
|
||||||
prev[cur.exchange_base_url].push({
|
prev[cur.exchange_base_url].push({
|
||||||
|
ageKeysCount: cur.ageCommitmentProof?.proof.privateKeys.length,
|
||||||
denom_value: parseFloat(Amounts.stringifyValue(denom)),
|
denom_value: parseFloat(Amounts.stringifyValue(denom)),
|
||||||
remain_value: parseFloat(
|
remain_value: parseFloat(
|
||||||
Amounts.stringifyValue(Amounts.parseOrThrow(cur.remaining_value)),
|
Amounts.stringifyValue(Amounts.parseOrThrow(cur.remaining_value)),
|
||||||
@ -305,7 +308,7 @@ function ShowAllCoins({
|
|||||||
<p>
|
<p>
|
||||||
<b>{ex}</b>: {total} {currencies[ex]}
|
<b>{ex}</b>: {total} {currencies[ex]}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p onClick={() => setCollapsedUnspent(true)}>
|
||||||
<b>
|
<b>
|
||||||
<i18n.Translate>usable coins</i18n.Translate>
|
<i18n.Translate>usable coins</i18n.Translate>
|
||||||
</b>
|
</b>
|
||||||
@ -313,7 +316,7 @@ function ShowAllCoins({
|
|||||||
{collapsedUnspent ? (
|
{collapsedUnspent ? (
|
||||||
<div onClick={() => setCollapsedUnspent(false)}>click to show</div>
|
<div onClick={() => setCollapsedUnspent(false)}>click to show</div>
|
||||||
) : (
|
) : (
|
||||||
<table onClick={() => setCollapsedUnspent(true)}>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<i18n.Translate>id</i18n.Translate>
|
<i18n.Translate>id</i18n.Translate>
|
||||||
@ -330,6 +333,9 @@ function ShowAllCoins({
|
|||||||
<td>
|
<td>
|
||||||
<i18n.Translate>from refresh?</i18n.Translate>
|
<i18n.Translate>from refresh?</i18n.Translate>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<i18n.Translate>age key count</i18n.Translate>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{coins.usable.map((c, idx) => {
|
{coins.usable.map((c, idx) => {
|
||||||
return (
|
return (
|
||||||
@ -339,12 +345,13 @@ function ShowAllCoins({
|
|||||||
<td>{c.remain_value}</td>
|
<td>{c.remain_value}</td>
|
||||||
<td>{c.status}</td>
|
<td>{c.status}</td>
|
||||||
<td>{c.from_refresh ? "true" : "false"}</td>
|
<td>{c.from_refresh ? "true" : "false"}</td>
|
||||||
|
<td>{String(c.ageKeysCount)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</table>
|
</table>
|
||||||
)}
|
)}
|
||||||
<p>
|
<p onClick={() => setCollapsedSpent(true)}>
|
||||||
<i18n.Translate>spent coins</i18n.Translate>
|
<i18n.Translate>spent coins</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
{collapsedSpent ? (
|
{collapsedSpent ? (
|
||||||
@ -352,7 +359,7 @@ function ShowAllCoins({
|
|||||||
<i18n.Translate>click to show</i18n.Translate>
|
<i18n.Translate>click to show</i18n.Translate>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<table onClick={() => setCollapsedSpent(true)}>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<i18n.Translate>id</i18n.Translate>
|
<i18n.Translate>id</i18n.Translate>
|
||||||
|
@ -324,10 +324,12 @@ export function preparePay(talerPayUri: string): Promise<PreparePayResult> {
|
|||||||
export function acceptWithdrawal(
|
export function acceptWithdrawal(
|
||||||
talerWithdrawUri: string,
|
talerWithdrawUri: string,
|
||||||
selectedExchange: string,
|
selectedExchange: string,
|
||||||
|
restrictAge?: number,
|
||||||
): Promise<AcceptWithdrawalResponse> {
|
): Promise<AcceptWithdrawalResponse> {
|
||||||
return callBackend("acceptBankIntegratedWithdrawal", {
|
return callBackend("acceptBankIntegratedWithdrawal", {
|
||||||
talerWithdrawUri,
|
talerWithdrawUri,
|
||||||
exchangeBaseUrl: selectedExchange,
|
exchangeBaseUrl: selectedExchange,
|
||||||
|
restrictAge
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +342,12 @@ export function acceptWithdrawal(
|
|||||||
export function acceptManualWithdrawal(
|
export function acceptManualWithdrawal(
|
||||||
exchangeBaseUrl: string,
|
exchangeBaseUrl: string,
|
||||||
amount: string,
|
amount: string,
|
||||||
|
restrictAge?: number,
|
||||||
): Promise<AcceptManualWithdrawalResult> {
|
): Promise<AcceptManualWithdrawalResult> {
|
||||||
return callBackend("acceptManualWithdrawal", {
|
return callBackend("acceptManualWithdrawal", {
|
||||||
amount,
|
amount,
|
||||||
exchangeBaseUrl,
|
exchangeBaseUrl,
|
||||||
|
restrictAge
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user