fulfillment url on payment ticket
This commit is contained in:
parent
b650750bcc
commit
49948eea98
@ -20,7 +20,7 @@ import { h, VNode } from "preact";
|
|||||||
export type Kind = "positive" | "negative" | "neutral";
|
export type Kind = "positive" | "negative" | "neutral";
|
||||||
interface Props {
|
interface Props {
|
||||||
title: VNode;
|
title: VNode;
|
||||||
text: AmountLike;
|
text: VNode | string;
|
||||||
kind: Kind;
|
kind: Kind;
|
||||||
big?: boolean;
|
big?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,8 @@ import { Part } from "../components/Part";
|
|||||||
import { QR } from "../components/QR";
|
import { QR } from "../components/QR";
|
||||||
import {
|
import {
|
||||||
ButtonSuccess,
|
ButtonSuccess,
|
||||||
|
Link,
|
||||||
|
LinkPrimary,
|
||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
SmallLightText,
|
SmallLightText,
|
||||||
SuccessBox,
|
SuccessBox,
|
||||||
@ -406,6 +408,11 @@ export function PaymentRequestView({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
<ButtonsSection />
|
<ButtonsSection />
|
||||||
|
<section>
|
||||||
|
<Link upperCased>
|
||||||
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
</WalletAction>
|
</WalletAction>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import { AddNewActionView } from "../wallet/AddNewActionView";
|
|||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
import { NoBalanceHelp } from "./NoBalanceHelp";
|
import { NoBalanceHelp } from "./NoBalanceHelp";
|
||||||
|
|
||||||
interface Props {
|
export interface Props {
|
||||||
goToWalletDeposit: (currency: string) => void;
|
goToWalletDeposit: (currency: string) => void;
|
||||||
goToWalletHistory: (currency: string) => void;
|
goToWalletHistory: (currency: string) => void;
|
||||||
goToWalletManualWithdraw: () => void;
|
goToWalletManualWithdraw: () => void;
|
||||||
|
@ -38,11 +38,8 @@ import { useTalerActionURL } from "./hooks/useTalerActionURL";
|
|||||||
import { strings } from "./i18n/strings";
|
import { strings } from "./i18n/strings";
|
||||||
import { Pages, PopupNavBar } from "./NavigationBar";
|
import { Pages, PopupNavBar } from "./NavigationBar";
|
||||||
import { BalancePage } from "./popup/BalancePage";
|
import { BalancePage } from "./popup/BalancePage";
|
||||||
import { DeveloperPage } from "./popup/DeveloperPage";
|
|
||||||
import { TalerActionFound } from "./popup/TalerActionFound";
|
import { TalerActionFound } from "./popup/TalerActionFound";
|
||||||
import { BackupPage } from "./wallet/BackupPage";
|
import { BackupPage } from "./wallet/BackupPage";
|
||||||
import { ExchangeAddPage } from "./wallet/ExchangeAddPage";
|
|
||||||
import { ProviderAddPage } from "./wallet/ProviderAddPage";
|
|
||||||
import { ProviderDetailPage } from "./wallet/ProviderDetailPage";
|
import { ProviderDetailPage } from "./wallet/ProviderDetailPage";
|
||||||
|
|
||||||
function main(): void {
|
function main(): void {
|
||||||
|
@ -49,22 +49,6 @@ interface Props {
|
|||||||
onAddProvider: () => void;
|
onAddProvider: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interface BackupStatus {
|
|
||||||
// deviceName: string;
|
|
||||||
// providers: ProviderInfo[];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function getBackupInfoOrdered(): BackupStatus {
|
|
||||||
// //create a first list of backup info by currency
|
|
||||||
// const status = await wxApi.getBackupInfo();
|
|
||||||
|
|
||||||
// return { deviceName: status.deviceId, providers };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function sync() {
|
|
||||||
// await wxApi.syncAllProviders();
|
|
||||||
// }
|
|
||||||
|
|
||||||
export function BackupPage({ onAddProvider }: Props): VNode {
|
export function BackupPage({ onAddProvider }: Props): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
const status = useAsyncAsHook(wxApi.getBackupInfo);
|
const status = useAsyncAsHook(wxApi.getBackupInfo);
|
||||||
|
@ -27,7 +27,6 @@ import { SelectList } from "../components/SelectList";
|
|||||||
import {
|
import {
|
||||||
BoldLight,
|
BoldLight,
|
||||||
ButtonPrimary,
|
ButtonPrimary,
|
||||||
ButtonSuccess,
|
|
||||||
Centered,
|
Centered,
|
||||||
Input,
|
Input,
|
||||||
InputWithLabel,
|
InputWithLabel,
|
||||||
@ -35,25 +34,21 @@ import {
|
|||||||
LinkPrimary,
|
LinkPrimary,
|
||||||
} from "../components/styled";
|
} from "../components/styled";
|
||||||
import { useTranslationContext } from "../context/translation";
|
import { useTranslationContext } from "../context/translation";
|
||||||
|
import { Pages } from "../NavigationBar";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
error: string | undefined;
|
error: string | undefined;
|
||||||
initialAmount?: string;
|
initialAmount?: string;
|
||||||
exchangeList: Record<string, string>;
|
exchangeList: Record<string, string>;
|
||||||
onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
|
onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
|
||||||
onAddExchange: () => void;
|
|
||||||
initialCurrency?: string;
|
initialCurrency?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CreateManualWithdraw({
|
export function useComponentState(
|
||||||
initialAmount,
|
exchangeList: Record<string, string>,
|
||||||
exchangeList,
|
initialAmount: string | undefined,
|
||||||
error,
|
initialCurrency: string | undefined,
|
||||||
initialCurrency,
|
) {
|
||||||
onCreate,
|
|
||||||
onAddExchange,
|
|
||||||
}: Props): VNode {
|
|
||||||
const { i18n } = useTranslationContext();
|
|
||||||
const exchangeSelectList = Object.keys(exchangeList);
|
const exchangeSelectList = Object.keys(exchangeList);
|
||||||
const currencySelectList = Object.values(exchangeList);
|
const currencySelectList = Object.values(exchangeList);
|
||||||
const exchangeMap = exchangeSelectList.reduce(
|
const exchangeMap = exchangeSelectList.reduce(
|
||||||
@ -74,10 +69,12 @@ export function CreateManualWithdraw({
|
|||||||
? exchangeSelectList[foundExchangeForCurrency]
|
? exchangeSelectList[foundExchangeForCurrency]
|
||||||
: exchangeSelectList.length > 0
|
: exchangeSelectList.length > 0
|
||||||
? exchangeSelectList[0]
|
? exchangeSelectList[0]
|
||||||
: "";
|
: undefined;
|
||||||
|
|
||||||
const [exchange, setExchange] = useState(initialExchange || "");
|
const [exchange, setExchange] = useState(initialExchange || "");
|
||||||
const [currency, setCurrency] = useState(exchangeList[initialExchange] ?? "");
|
const [currency, setCurrency] = useState(
|
||||||
|
initialExchange ? exchangeList[initialExchange] : "",
|
||||||
|
);
|
||||||
|
|
||||||
const [amount, setAmount] = useState(initialAmount || "");
|
const [amount, setAmount] = useState(initialAmount || "");
|
||||||
const parsedAmount = Amounts.parse(`${currency}:${amount}`);
|
const parsedAmount = Amounts.parse(`${currency}:${amount}`);
|
||||||
@ -97,8 +94,49 @@ export function CreateManualWithdraw({
|
|||||||
setExchange("");
|
setExchange("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
initialExchange,
|
||||||
|
currency: {
|
||||||
|
list: currencyMap,
|
||||||
|
value: currency,
|
||||||
|
onChange: changeCurrency,
|
||||||
|
},
|
||||||
|
exchange: {
|
||||||
|
list: exchangeMap,
|
||||||
|
value: exchange,
|
||||||
|
onChange: changeExchange,
|
||||||
|
},
|
||||||
|
amount: {
|
||||||
|
value: amount,
|
||||||
|
onInput: (e: string) => setAmount(e),
|
||||||
|
},
|
||||||
|
parsedAmount,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (!initialExchange) {
|
interface InputHandler {
|
||||||
|
value: string;
|
||||||
|
onInput: (s: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SelectInputHandler {
|
||||||
|
list: Record<string, string>;
|
||||||
|
value: string;
|
||||||
|
onChange: (s: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CreateManualWithdraw({
|
||||||
|
initialAmount,
|
||||||
|
exchangeList,
|
||||||
|
error,
|
||||||
|
initialCurrency,
|
||||||
|
onCreate,
|
||||||
|
}: Props): VNode {
|
||||||
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
|
const state = useComponentState(exchangeList, initialAmount, initialCurrency);
|
||||||
|
|
||||||
|
if (!state.initialExchange) {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h2>
|
<h2>
|
||||||
@ -115,9 +153,12 @@ export function CreateManualWithdraw({
|
|||||||
<BoldLight>
|
<BoldLight>
|
||||||
<i18n.Translate>No exchange configured</i18n.Translate>
|
<i18n.Translate>No exchange configured</i18n.Translate>
|
||||||
</BoldLight>
|
</BoldLight>
|
||||||
<ButtonSuccess onClick={onAddExchange}>
|
<LinkPrimary
|
||||||
<i18n.Translate>Add exchange</i18n.Translate>
|
href={Pages.settings_exchange_add}
|
||||||
</ButtonSuccess>
|
style={{ marginLeft: "auto" }}
|
||||||
|
>
|
||||||
|
<i18n.Translate>Add Exchange</i18n.Translate>
|
||||||
|
</LinkPrimary>
|
||||||
</Centered>
|
</Centered>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
@ -146,37 +187,38 @@ export function CreateManualWithdraw({
|
|||||||
<Input>
|
<Input>
|
||||||
<SelectList
|
<SelectList
|
||||||
label={<i18n.Translate>Currency</i18n.Translate>}
|
label={<i18n.Translate>Currency</i18n.Translate>}
|
||||||
list={currencyMap}
|
|
||||||
name="currency"
|
name="currency"
|
||||||
value={currency}
|
{...state.currency}
|
||||||
onChange={changeCurrency}
|
|
||||||
/>
|
/>
|
||||||
</Input>
|
</Input>
|
||||||
<Input>
|
<Input>
|
||||||
<SelectList
|
<SelectList
|
||||||
label={<i18n.Translate>Exchange</i18n.Translate>}
|
label={<i18n.Translate>Exchange</i18n.Translate>}
|
||||||
list={exchangeMap}
|
name="exchange"
|
||||||
name="currency"
|
{...state.exchange}
|
||||||
value={exchange}
|
|
||||||
onChange={changeExchange}
|
|
||||||
/>
|
/>
|
||||||
</Input>
|
</Input>
|
||||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
<LinkPrimary onClick={onAddExchange} style={{ marginLeft: "auto" }}>
|
<LinkPrimary
|
||||||
|
href={Pages.settings_exchange_add}
|
||||||
|
style={{ marginLeft: "auto" }}
|
||||||
|
>
|
||||||
<i18n.Translate>Add Exchange</i18n.Translate>
|
<i18n.Translate>Add Exchange</i18n.Translate>
|
||||||
</LinkPrimary>
|
</LinkPrimary>
|
||||||
</div>
|
</div>
|
||||||
{currency && (
|
{state.currency.value && (
|
||||||
<InputWithLabel invalid={!!amount && !parsedAmount}>
|
<InputWithLabel
|
||||||
|
invalid={!!state.amount.value && !state.parsedAmount}
|
||||||
|
>
|
||||||
<label>
|
<label>
|
||||||
<i18n.Translate>Amount</i18n.Translate>
|
<i18n.Translate>Amount</i18n.Translate>
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<span>{currency}</span>
|
<span>{state.currency.value}</span>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={amount}
|
value={state.amount.value}
|
||||||
onInput={(e) => setAmount(e.currentTarget.value)}
|
onInput={(e) => state.amount.onInput(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</InputWithLabel>
|
</InputWithLabel>
|
||||||
@ -186,8 +228,8 @@ export function CreateManualWithdraw({
|
|||||||
<footer>
|
<footer>
|
||||||
<div />
|
<div />
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
disabled={!parsedAmount || !exchange}
|
disabled={!state.parsedAmount || !state.exchange.value}
|
||||||
onClick={() => onCreate(exchange, parsedAmount!)}
|
onClick={() => onCreate(state.exchange.value, state.parsedAmount!)}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Start withdrawal</i18n.Translate>
|
<i18n.Translate>Start withdrawal</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</ButtonPrimary>
|
||||||
|
@ -73,12 +73,6 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [addingExchange, setAddingExchange] = useState(false);
|
|
||||||
|
|
||||||
if (addingExchange) {
|
|
||||||
return <ExchangeAddPage onBack={() => setAddingExchange(false)} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
return (
|
return (
|
||||||
<ReserveCreated
|
<ReserveCreated
|
||||||
@ -117,7 +111,6 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CreateManualWithdraw
|
<CreateManualWithdraw
|
||||||
onAddExchange={() => setAddingExchange(true)}
|
|
||||||
error={error}
|
error={error}
|
||||||
exchangeList={exchangeList}
|
exchangeList={exchangeList}
|
||||||
onCreate={doCreate}
|
onCreate={doCreate}
|
||||||
|
@ -369,7 +369,19 @@ export function TransactionView({
|
|||||||
/>
|
/>
|
||||||
<Part
|
<Part
|
||||||
title={<i18n.Translate>Purchase</i18n.Translate>}
|
title={<i18n.Translate>Purchase</i18n.Translate>}
|
||||||
text={transaction.info.summary}
|
text={
|
||||||
|
transaction.info.fulfillmentUrl ? (
|
||||||
|
<a
|
||||||
|
href={transaction.info.fulfillmentUrl}
|
||||||
|
target="_bank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
{transaction.info.summary}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
transaction.info.summary
|
||||||
|
)
|
||||||
|
}
|
||||||
kind="neutral"
|
kind="neutral"
|
||||||
/>
|
/>
|
||||||
<Part
|
<Part
|
||||||
@ -542,7 +554,19 @@ export function TransactionView({
|
|||||||
/>
|
/>
|
||||||
<Part
|
<Part
|
||||||
title={<i18n.Translate>Purchase</i18n.Translate>}
|
title={<i18n.Translate>Purchase</i18n.Translate>}
|
||||||
text={transaction.info.summary}
|
text={
|
||||||
|
transaction.info.fulfillmentUrl ? (
|
||||||
|
<a
|
||||||
|
href={transaction.info.fulfillmentUrl}
|
||||||
|
target="_bank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
{transaction.info.summary}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
transaction.info.summary
|
||||||
|
)
|
||||||
|
}
|
||||||
kind="neutral"
|
kind="neutral"
|
||||||
/>
|
/>
|
||||||
<Part
|
<Part
|
||||||
|
Loading…
Reference in New Issue
Block a user