add i18n where was missing
This commit is contained in:
parent
7647d077e7
commit
41850c9f14
@ -18,17 +18,23 @@
|
||||
* Popup shown to the user when they click
|
||||
* the Taler browser action button.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
import { i18n } from "@gnu-taler/taler-util";
|
||||
import { i18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { VNode, h } from "preact";
|
||||
import { JustInDevMode } from "./components/JustInDevMode";
|
||||
import { NavigationHeader, NavigationHeaderHolder } from "./components/styled";
|
||||
|
||||
/**
|
||||
* List of pages used by the wallet
|
||||
*
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
export enum Pages {
|
||||
welcome = "/welcome",
|
||||
|
||||
@ -60,17 +66,15 @@ export function PopupNavBar({ path = "" }: { path?: string }): VNode {
|
||||
: "#";
|
||||
return (
|
||||
<NavigationHeader>
|
||||
<a
|
||||
href="/balance"
|
||||
class={path.startsWith("/balance") ? "active" : ""}
|
||||
>{i18n.str`Balance`}</a>
|
||||
<a
|
||||
href="/backup"
|
||||
class={path.startsWith("/backup") ? "active" : ""}
|
||||
>{i18n.str`Backup`}</a>
|
||||
<a href="/balance" class={path.startsWith("/balance") ? "active" : ""}>
|
||||
<Translate>Balance</Translate>
|
||||
</a>
|
||||
<a href="/backup" class={path.startsWith("/backup") ? "active" : ""}>
|
||||
<Translate>Backup</Translate>
|
||||
</a>
|
||||
<a />
|
||||
<a href={innerUrl} target="_blank" rel="noreferrer">
|
||||
<div class="settings-icon" title="Settings" />
|
||||
<div class="settings-icon" title={i18n.str`Settings`} />
|
||||
</a>
|
||||
</NavigationHeader>
|
||||
);
|
||||
@ -80,20 +84,17 @@ export function WalletNavBar({ path = "" }: { path?: string }): VNode {
|
||||
return (
|
||||
<NavigationHeaderHolder>
|
||||
<NavigationHeader>
|
||||
<a
|
||||
href="/balance"
|
||||
class={path.startsWith("/balance") ? "active" : ""}
|
||||
>{i18n.str`Balance`}</a>
|
||||
<a
|
||||
href="/backup"
|
||||
class={path.startsWith("/backup") ? "active" : ""}
|
||||
>{i18n.str`Backup`}</a>
|
||||
<a href="/balance" class={path.startsWith("/balance") ? "active" : ""}>
|
||||
<Translate>Balance</Translate>
|
||||
</a>
|
||||
<a href="/backup" class={path.startsWith("/backup") ? "active" : ""}>
|
||||
<Translate>Backup</Translate>
|
||||
</a>
|
||||
|
||||
<JustInDevMode>
|
||||
<a
|
||||
href="/dev"
|
||||
class={path.startsWith("/dev") ? "active" : ""}
|
||||
>{i18n.str`Dev`}</a>
|
||||
<a href="/dev" class={path.startsWith("/dev") ? "active" : ""}>
|
||||
<Translate>Dev</Translate>
|
||||
</a>
|
||||
</JustInDevMode>
|
||||
|
||||
<a />
|
||||
@ -101,7 +102,7 @@ export function WalletNavBar({ path = "" }: { path?: string }): VNode {
|
||||
href="/settings"
|
||||
class={path.startsWith("/settings") ? "active" : ""}
|
||||
>
|
||||
<div class="settings-icon" title="Settings" />
|
||||
<Translate>Settings</Translate>
|
||||
</a>
|
||||
</NavigationHeader>
|
||||
</NavigationHeaderHolder>
|
||||
|
@ -17,7 +17,7 @@
|
||||
/**
|
||||
* Entry point for the background page.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -1,43 +0,0 @@
|
||||
"use strict";
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2016 GNUnet e.V.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BrowserCryptoWorkerFactory = void 0;
|
||||
/**
|
||||
* API to access the Taler crypto worker thread.
|
||||
* @author Florian Dold
|
||||
*/
|
||||
class BrowserCryptoWorkerFactory {
|
||||
startWorker() {
|
||||
const workerCtor = Worker;
|
||||
const workerPath = "/browserWorkerEntry.js";
|
||||
return new workerCtor(workerPath);
|
||||
}
|
||||
getConcurrency() {
|
||||
let concurrency = 2;
|
||||
try {
|
||||
// only works in the browser
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
concurrency = navigator["hardwareConcurrency"];
|
||||
concurrency = Math.max(1, Math.ceil(concurrency / 2));
|
||||
} catch (e) {
|
||||
concurrency = 2;
|
||||
}
|
||||
return concurrency;
|
||||
}
|
||||
}
|
||||
exports.BrowserCryptoWorkerFactory = BrowserCryptoWorkerFactory;
|
||||
//# sourceMappingURL=browserCryptoWorkerFactory.js.map
|
@ -1 +0,0 @@
|
||||
{"version":3,"file":"browserCryptoWorkerFactory.js","sourceRoot":"","sources":["browserCryptoWorkerFactory.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH;;;GAGG;AAEH,MAAa,0BAA0B;IACrC,WAAW;QACT,MAAM,UAAU,GAAG,MAAM,CAAC;QAC1B,MAAM,UAAU,GAAG,wBAAwB,CAAC;QAC5C,OAAO,IAAI,UAAU,CAAC,UAAU,CAAiB,CAAC;IACpD,CAAC;IAED,cAAc;QACZ,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI;YACF,4BAA4B;YAC5B,6CAA6C;YAC7C,WAAW,GAAI,SAAiB,CAAC,qBAAqB,CAAC,CAAC;YACxD,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;SACvD;QAAC,OAAO,CAAC,EAAE;YACV,WAAW,GAAG,CAAC,CAAC;SACjB;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;CACF;AAnBD,gEAmBC"}
|
@ -14,7 +14,7 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { PaytoUri } from "@gnu-taler/taler-util";
|
||||
import { PaytoUri, Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { CopiedIcon, CopyIcon } from "../svg";
|
||||
@ -34,23 +34,23 @@ export function BankDetailsByPaytoType({
|
||||
amount,
|
||||
}: BankDetailsProps): VNode {
|
||||
const firstPart = !payto ? undefined : !payto.isKnown ? (
|
||||
<Row name="Account" value={payto.targetPath} />
|
||||
<Row name={<Translate>Account</Translate>} value={payto.targetPath} />
|
||||
) : payto.targetType === "x-taler-bank" ? (
|
||||
<Fragment>
|
||||
<Row name="Bank host" value={payto.host} />
|
||||
<Row name="Bank account" value={payto.account} />
|
||||
<Row name={<Translate>Bank host</Translate>} value={payto.host} />
|
||||
<Row name={<Translate>Bank account</Translate>} value={payto.account} />
|
||||
</Fragment>
|
||||
) : payto.targetType === "iban" ? (
|
||||
<Row name="IBAN" value={payto.iban} />
|
||||
<Row name={<Translate>IBAN</Translate>} value={payto.iban} />
|
||||
) : undefined;
|
||||
return (
|
||||
<div style={{ textAlign: "left" }}>
|
||||
<p>Bank transfer details</p>
|
||||
<table>
|
||||
{firstPart}
|
||||
<Row name="Exchange" value={exchangeBaseUrl} />
|
||||
<Row name="Chosen amount" value={amount} />
|
||||
<Row name="Subject" value={subject} literal />
|
||||
<Row name={<Translate>Exchange</Translate>} value={exchangeBaseUrl} />
|
||||
<Row name={<Translate>Chosen amount</Translate>} value={amount} />
|
||||
<Row name={<Translate>Subject</Translate>} value={subject} literal />
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
@ -61,7 +61,7 @@ function Row({
|
||||
value,
|
||||
literal,
|
||||
}: {
|
||||
name: string;
|
||||
name: VNode;
|
||||
value: string;
|
||||
literal?: boolean;
|
||||
}): VNode {
|
||||
|
@ -19,9 +19,9 @@ import { h, VNode } from "preact";
|
||||
interface Props {
|
||||
enabled: boolean;
|
||||
onToggle: () => void;
|
||||
label: string;
|
||||
label: VNode;
|
||||
name: string;
|
||||
description?: string;
|
||||
description?: VNode;
|
||||
}
|
||||
export function Checkbox({
|
||||
name,
|
||||
|
@ -20,7 +20,7 @@ import { h, VNode } from "preact";
|
||||
interface Props {
|
||||
enabled: boolean;
|
||||
onToggle: () => void;
|
||||
label: string;
|
||||
label: VNode;
|
||||
name: string;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
|
||||
export function DebugCheckbox({
|
||||
@ -36,7 +37,7 @@ export function DebugCheckbox({
|
||||
htmlFor="checkbox-perm"
|
||||
style={{ marginLeft: "0.5em", fontWeight: "bold" }}
|
||||
>
|
||||
Automatically open wallet based on page content
|
||||
<Translate>Automatically open wallet based on page content</Translate>
|
||||
</label>
|
||||
<span
|
||||
style={{
|
||||
@ -46,8 +47,12 @@ export function DebugCheckbox({
|
||||
marginLeft: "2em",
|
||||
}}
|
||||
>
|
||||
(Enabling this option below will make using the wallet faster, but
|
||||
requires more permissions from your browser.)
|
||||
(
|
||||
<Translate>
|
||||
Enabling this option below will make using the wallet faster, but
|
||||
requires more permissions from your browser.
|
||||
</Translate>
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
@ -14,7 +14,7 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { WalletDiagnostics } from "@gnu-taler/taler-util";
|
||||
import { Translate, WalletDiagnostics } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { PageLink } from "../renderHtml";
|
||||
|
||||
@ -25,7 +25,13 @@ interface Props {
|
||||
|
||||
export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
|
||||
if (timedOut) {
|
||||
return <p>Diagnostics timed out. Could not talk to the wallet backend.</p>;
|
||||
return (
|
||||
<p>
|
||||
<Translate>
|
||||
Diagnostics timed out. Could not talk to the wallet backend.
|
||||
</Translate>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
if (diagnostics) {
|
||||
@ -41,7 +47,9 @@ export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
|
||||
paddingBottom: "0.2em",
|
||||
}}
|
||||
>
|
||||
<p>Problems detected:</p>
|
||||
<p>
|
||||
<Translate>Problems detected:</Translate>
|
||||
</p>
|
||||
<ol>
|
||||
{diagnostics.errors.map((errMsg) => (
|
||||
<li key={errMsg}>{errMsg}</li>
|
||||
@ -49,22 +57,32 @@ export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
|
||||
</ol>
|
||||
{diagnostics.firefoxIdbProblem ? (
|
||||
<p>
|
||||
Please check in your <code>about:config</code> settings that you
|
||||
have IndexedDB enabled (check the preference name{" "}
|
||||
<code>dom.indexedDB.enabled</code>).
|
||||
<Translate>
|
||||
Please check in your <code>about:config</code> settings that you
|
||||
have IndexedDB enabled (check the preference name{" "}
|
||||
<code>dom.indexedDB.enabled</code>).
|
||||
</Translate>
|
||||
</p>
|
||||
) : null}
|
||||
{diagnostics.dbOutdated ? (
|
||||
<p>
|
||||
Your wallet database is outdated. Currently automatic migration is
|
||||
not supported. Please go{" "}
|
||||
<PageLink pageName="/reset-required">here</PageLink> to reset the
|
||||
wallet database.
|
||||
<Translate>
|
||||
Your wallet database is outdated. Currently automatic migration is
|
||||
not supported. Please go{" "}
|
||||
<PageLink pageName="/reset-required">
|
||||
<Translate>here</Translate>
|
||||
</PageLink>{" "}
|
||||
to reset the wallet database.
|
||||
</Translate>
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <p>Running diagnostics ...</p>;
|
||||
return (
|
||||
<p>
|
||||
<Translate>Running diagnostics</Translate> ...
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
import { useRef, useState } from "preact/hooks";
|
||||
|
||||
@ -39,7 +40,9 @@ export function EditableText({
|
||||
return (
|
||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<p>{value}</p>
|
||||
<button onClick={() => setEditing(true)}>edit</button>
|
||||
<button onClick={() => setEditing(true)}>
|
||||
<Translate>Edit</Translate>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -54,7 +57,7 @@ export function EditableText({
|
||||
onChange(ref.current.value).then(() => setEditing(false));
|
||||
}}
|
||||
>
|
||||
confirm
|
||||
<Translate>Confirm</Translate>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -13,7 +13,7 @@
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
import { VNode, h } from "preact";
|
||||
import { VNode, h, ComponentChildren } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import arrowDown from "../../static/img/chevron-down.svg";
|
||||
import { ErrorBox } from "./styled";
|
||||
@ -22,11 +22,10 @@ export function ErrorMessage({
|
||||
title,
|
||||
description,
|
||||
}: {
|
||||
title?: string | VNode;
|
||||
title: VNode;
|
||||
description?: string;
|
||||
}): VNode | null {
|
||||
const [showErrorDetail, setShowErrorDetail] = useState(false);
|
||||
if (!title) return null;
|
||||
return (
|
||||
<ErrorBox style={{ paddingTop: 0, paddingBottom: 0 }}>
|
||||
<div>
|
||||
|
@ -24,7 +24,7 @@ export function ErrorTalerOperation({
|
||||
title,
|
||||
error,
|
||||
}: {
|
||||
title?: string;
|
||||
title?: VNode;
|
||||
error?: TalerErrorDetails;
|
||||
}): VNode | null {
|
||||
const { devMode } = useDevContext();
|
||||
|
@ -13,8 +13,13 @@
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
|
||||
export function Loading(): VNode {
|
||||
return <div>Loading...</div>;
|
||||
return (
|
||||
<div>
|
||||
<Translate>Loading</Translate>...
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import { ErrorMessage } from "./ErrorMessage";
|
||||
import { ErrorTalerOperation } from "./ErrorTalerOperation";
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
title: VNode;
|
||||
error: HookError;
|
||||
}
|
||||
export function LoadingError({ title, error }: Props): VNode {
|
||||
|
@ -4,7 +4,7 @@ import { ButtonBoxPrimary, ButtonPrimary, ParagraphClickable } from "./styled";
|
||||
import { useState } from "preact/hooks";
|
||||
|
||||
export interface Props {
|
||||
label: (s: string) => string;
|
||||
label: (s: string) => VNode;
|
||||
actions: string[];
|
||||
onClick: (s: string) => void;
|
||||
}
|
||||
|
@ -15,11 +15,11 @@
|
||||
*/
|
||||
import { AmountLike } from "@gnu-taler/taler-util";
|
||||
import { ExtraLargeText, LargeText, SmallLightText } from "./styled";
|
||||
import { h } from "preact";
|
||||
import { h, VNode } from "preact";
|
||||
|
||||
export type Kind = "positive" | "negative" | "neutral";
|
||||
interface Props {
|
||||
title: string;
|
||||
title: VNode;
|
||||
text: AmountLike;
|
||||
kind: Kind;
|
||||
big?: boolean;
|
||||
|
@ -14,13 +14,14 @@
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { NiceSelect } from "./styled";
|
||||
|
||||
interface Props {
|
||||
value?: string;
|
||||
onChange: (s: string) => void;
|
||||
label: string;
|
||||
label: VNode;
|
||||
list: {
|
||||
[label: string]: string;
|
||||
};
|
||||
@ -58,7 +59,7 @@ export function SelectList({
|
||||
{value === undefined ||
|
||||
(canBeNull && (
|
||||
<option selected disabled>
|
||||
Select one option
|
||||
<Translate>Select one option</Translate>
|
||||
</option>
|
||||
// ) : (
|
||||
// <option selected>{list[value]}</option>
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
Timestamp,
|
||||
Transaction,
|
||||
TransactionType,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
import imageBank from "../../static/img/ri-bank-line.svg";
|
||||
@ -133,7 +134,7 @@ function TransactionLayout(props: TransactionLayoutProps): VNode {
|
||||
</LargeText>
|
||||
{props.pending && (
|
||||
<LightText style={{ marginTop: 5, marginBottom: 5 }}>
|
||||
Waiting for confirmation
|
||||
<Translate>Waiting for confirmation</Translate>
|
||||
</LightText>
|
||||
)}
|
||||
<SmallLightText style={{ marginTop: 5 }}>
|
||||
@ -195,7 +196,11 @@ function TransactionAmount(props: TransactionAmountProps): VNode {
|
||||
{sign}
|
||||
{Amounts.stringifyValue(props.amount)}
|
||||
</ExtraLargeText>
|
||||
{props.pending && <div>PENDING</div>}
|
||||
{props.pending && (
|
||||
<div>
|
||||
<Translate>PENDING</Translate>
|
||||
</div>
|
||||
)}
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import {
|
||||
NotificationType,
|
||||
PreparePayResult,
|
||||
PreparePayResultType,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
@ -108,7 +109,11 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
|
||||
}, [talerPayUri, foundAmountStr]);
|
||||
|
||||
if (!talerPayUri) {
|
||||
return <span>missing pay uri</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>missing pay uri</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (!payStatus) {
|
||||
@ -116,10 +121,16 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
|
||||
return (
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
<h2>{i18n.str`Digital cash payment`}</h2>
|
||||
<h2>
|
||||
<Translate>Digital cash payment</Translate>
|
||||
</h2>
|
||||
<section>
|
||||
<ErrorTalerOperation
|
||||
title="Could not get the payment information for this order"
|
||||
title={
|
||||
<Translate>
|
||||
Could not get the payment information for this order
|
||||
</Translate>
|
||||
}
|
||||
error={payErrMsg?.operationError}
|
||||
/>
|
||||
</section>
|
||||
@ -130,15 +141,25 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
|
||||
return (
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
<h2>{i18n.str`Digital cash payment`}</h2>
|
||||
<h2>
|
||||
<Translate>Digital cash payment</Translate>
|
||||
</h2>
|
||||
<section>
|
||||
<p>Could not get the payment information for this order</p>
|
||||
<p>
|
||||
<Translate>
|
||||
Could not get the payment information for this order
|
||||
</Translate>
|
||||
</p>
|
||||
<ErrorBox>{payErrMsg}</ErrorBox>
|
||||
</section>
|
||||
</WalletAction>
|
||||
);
|
||||
}
|
||||
return <span>Loading payment information ...</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>Loading payment information</Translate> ...
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const onClick = async (): Promise<void> => {
|
||||
@ -183,20 +204,32 @@ export function PaymentRequestView({
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
|
||||
<h2>{i18n.str`Digital cash deposit`}</h2>
|
||||
<h2>
|
||||
<Translate>Digital cash deposit</Translate>
|
||||
</h2>
|
||||
{payStatus.status === PreparePayResultType.AlreadyConfirmed &&
|
||||
(payStatus.paid ? (
|
||||
<SuccessBox> Already paid </SuccessBox>
|
||||
<SuccessBox>
|
||||
<Translate>Already paid</Translate>
|
||||
</SuccessBox>
|
||||
) : (
|
||||
<WarningBox> Already claimed </WarningBox>
|
||||
<WarningBox>
|
||||
<Translate>Already claimed</Translate>
|
||||
</WarningBox>
|
||||
))}
|
||||
{payResult && payResult.type === ConfirmPayResultType.Done && (
|
||||
<SuccessBox>
|
||||
<h3>Payment complete</h3>
|
||||
<h3>
|
||||
<Translate>Payment complete</Translate>
|
||||
</h3>
|
||||
<p>
|
||||
{!payResult.contractTerms.fulfillment_message
|
||||
? "You will now be sent back to the merchant you came from."
|
||||
: payResult.contractTerms.fulfillment_message}
|
||||
{!payResult.contractTerms.fulfillment_message ? (
|
||||
<Translate>
|
||||
You will now be sent back to the merchant you came from.
|
||||
</Translate>
|
||||
) : (
|
||||
payResult.contractTerms.fulfillment_message
|
||||
)}
|
||||
</p>
|
||||
</SuccessBox>
|
||||
)}
|
||||
@ -205,7 +238,7 @@ export function PaymentRequestView({
|
||||
Amounts.isNonZero(totalFees) && (
|
||||
<Part
|
||||
big
|
||||
title="Total to pay"
|
||||
title={<Translate>Total to pay</Translate>}
|
||||
text={amountToPretty(
|
||||
Amounts.parseOrThrow(payStatus.amountEffective),
|
||||
)}
|
||||
@ -214,7 +247,7 @@ export function PaymentRequestView({
|
||||
)}
|
||||
<Part
|
||||
big
|
||||
title="Purchase amount"
|
||||
title={<Translate>Purchase amount</Translate>}
|
||||
text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))}
|
||||
kind="neutral"
|
||||
/>
|
||||
@ -222,21 +255,25 @@ export function PaymentRequestView({
|
||||
<Fragment>
|
||||
<Part
|
||||
big
|
||||
title="Fee"
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToPretty(totalFees)}
|
||||
kind="negative"
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
<Part
|
||||
title="Merchant"
|
||||
title={<Translate>Merchant</Translate>}
|
||||
text={contractTerms.merchant.name}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part title="Purchase" text={contractTerms.summary} kind="neutral" />
|
||||
<Part
|
||||
title={<Translate>Purchase</Translate>}
|
||||
text={contractTerms.summary}
|
||||
kind="neutral"
|
||||
/>
|
||||
{contractTerms.order_id && (
|
||||
<Part
|
||||
title="Receipt"
|
||||
title={<Translate>Receipt</Translate>}
|
||||
text={`#${contractTerms.order_id}`}
|
||||
kind="neutral"
|
||||
/>
|
||||
|
@ -37,10 +37,12 @@ import {
|
||||
PreparePayResult,
|
||||
PreparePayResultType,
|
||||
Product,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { ErrorMessage } from "../components/ErrorMessage";
|
||||
import { Loading } from "../components/Loading";
|
||||
import { LoadingError } from "../components/LoadingError";
|
||||
import { LogoHeader } from "../components/LogoHeader";
|
||||
@ -106,7 +108,12 @@ export function PayPage({
|
||||
}
|
||||
|
||||
if (hook.hasError) {
|
||||
return <LoadingError title="Could not load pay status" error={hook} />;
|
||||
return (
|
||||
<LoadingError
|
||||
title={<Translate>Could not load pay status</Translate>}
|
||||
error={hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const foundBalance = hook.response.balance.balances.find(
|
||||
@ -178,9 +185,13 @@ export function PaymentRequestView({
|
||||
|
||||
if (!contractTerms) {
|
||||
return (
|
||||
<span>
|
||||
Error: did not get contract terms from merchant or wallet backend.
|
||||
</span>
|
||||
<ErrorMessage
|
||||
title={
|
||||
<Translate>
|
||||
Could not load contract terms from merchant or wallet backend.
|
||||
</Translate>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -192,13 +203,6 @@ export function PaymentRequestView({
|
||||
totalFees = Amounts.sub(amountEffective, amountRaw).amount;
|
||||
}
|
||||
|
||||
// let merchantName: VNode;
|
||||
// if (contractTerms.merchant && contractTerms.merchant.name) {
|
||||
// merchantName = <strong>{contractTerms.merchant.name}</strong>;
|
||||
// } else {
|
||||
// merchantName = <strong>(pub: {contractTerms.merchant_pub})</strong>;
|
||||
// }
|
||||
|
||||
function Alternative(): VNode {
|
||||
const [showQR, setShowQR] = useState<boolean>(false);
|
||||
const privateUri =
|
||||
@ -209,12 +213,21 @@ export function PaymentRequestView({
|
||||
return (
|
||||
<section>
|
||||
<LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}>
|
||||
{!showQR ? i18n.str`Pay with a mobile phone` : i18n.str`Hide QR`}
|
||||
{!showQR ? (
|
||||
<Translate>Pay with a mobile phone</Translate>
|
||||
) : (
|
||||
<Translate>Hide QR</Translate>
|
||||
)}
|
||||
</LinkSuccess>
|
||||
{showQR && (
|
||||
<div>
|
||||
<QR text={privateUri} />
|
||||
Scan the QR code or <a href={privateUri}>click here</a>
|
||||
<Translate>
|
||||
Scan the QR code or
|
||||
<a href={privateUri}>
|
||||
<Translate>click here</Translate>
|
||||
</a>
|
||||
</Translate>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
@ -227,7 +240,9 @@ export function PaymentRequestView({
|
||||
return (
|
||||
<section>
|
||||
<div>
|
||||
<p>Processing...</p>
|
||||
<p>
|
||||
<Translate>Processing</Translate>...
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
@ -239,7 +254,9 @@ export function PaymentRequestView({
|
||||
<Fragment>
|
||||
<section>
|
||||
<ButtonSuccess upperCased onClick={onClick}>
|
||||
{i18n.str`Pay`} {amountToString(payStatus.amountEffective)}
|
||||
<Translate>
|
||||
Pay {amountToString(payStatus.amountEffective)}
|
||||
</Translate>
|
||||
</ButtonSuccess>
|
||||
</section>
|
||||
<Alternative />
|
||||
@ -252,18 +269,22 @@ export function PaymentRequestView({
|
||||
<section>
|
||||
{balance ? (
|
||||
<WarningBox>
|
||||
Your balance of {amountToString(balance)} is not enough to pay
|
||||
for this purchase
|
||||
<Translate>
|
||||
Your balance of {amountToString(balance)} is not enough to pay
|
||||
for this purchase
|
||||
</Translate>
|
||||
</WarningBox>
|
||||
) : (
|
||||
<WarningBox>
|
||||
Your balance is not enough to pay for this purchase.
|
||||
<Translate>
|
||||
Your balance is not enough to pay for this purchase.
|
||||
</Translate>
|
||||
</WarningBox>
|
||||
)}
|
||||
</section>
|
||||
<section>
|
||||
<ButtonSuccess upperCased onClick={goToWalletManualWithdraw}>
|
||||
{i18n.str`Withdraw digital cash`}
|
||||
<Translate>Withdraw digital cash</Translate>
|
||||
</ButtonSuccess>
|
||||
</section>
|
||||
<Alternative />
|
||||
@ -276,7 +297,7 @@ export function PaymentRequestView({
|
||||
<section>
|
||||
{payStatus.paid && contractTerms.fulfillment_message && (
|
||||
<Part
|
||||
title="Merchant message"
|
||||
title={<Translate>Merchant message</Translate>}
|
||||
text={contractTerms.fulfillment_message}
|
||||
kind="neutral"
|
||||
/>
|
||||
@ -293,31 +314,48 @@ export function PaymentRequestView({
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
|
||||
<h2>{i18n.str`Digital cash payment`}</h2>
|
||||
<h2>
|
||||
<Translate>Digital cash payment</Translate>
|
||||
</h2>
|
||||
{payStatus.status === PreparePayResultType.AlreadyConfirmed &&
|
||||
(payStatus.paid ? (
|
||||
payStatus.contractTerms.fulfillment_url ? (
|
||||
<SuccessBox>
|
||||
Already paid, you are going to be redirected to{" "}
|
||||
<a href={payStatus.contractTerms.fulfillment_url}>
|
||||
{payStatus.contractTerms.fulfillment_url}
|
||||
</a>
|
||||
<Translate>
|
||||
Already paid, you are going to be redirected to{" "}
|
||||
<a href={payStatus.contractTerms.fulfillment_url}>
|
||||
{payStatus.contractTerms.fulfillment_url}
|
||||
</a>
|
||||
</Translate>
|
||||
</SuccessBox>
|
||||
) : (
|
||||
<SuccessBox> Already paid </SuccessBox>
|
||||
<SuccessBox>
|
||||
<Translate>Already paid</Translate>
|
||||
</SuccessBox>
|
||||
)
|
||||
) : (
|
||||
<WarningBox> Already claimed </WarningBox>
|
||||
<WarningBox>
|
||||
<Translate>Already claimed</Translate>
|
||||
</WarningBox>
|
||||
))}
|
||||
{payResult && payResult.type === ConfirmPayResultType.Done && (
|
||||
<SuccessBox>
|
||||
<h3>Payment complete</h3>
|
||||
<h3>
|
||||
<Translate>Payment complete</Translate>
|
||||
</h3>
|
||||
<p>
|
||||
{!payResult.contractTerms.fulfillment_message
|
||||
? payResult.contractTerms.fulfillment_url
|
||||
? `You are going to be redirected to ${payResult.contractTerms.fulfillment_url}`
|
||||
: "You can close this page."
|
||||
: payResult.contractTerms.fulfillment_message}
|
||||
{!payResult.contractTerms.fulfillment_message ? (
|
||||
payResult.contractTerms.fulfillment_url ? (
|
||||
<Translate>
|
||||
You are going to be redirected to $
|
||||
{payResult.contractTerms.fulfillment_url}
|
||||
</Translate>
|
||||
) : (
|
||||
<Translate>You can close this page.</Translate>
|
||||
)
|
||||
) : (
|
||||
payResult.contractTerms.fulfillment_message
|
||||
)}
|
||||
</p>
|
||||
</SuccessBox>
|
||||
)}
|
||||
@ -326,14 +364,14 @@ export function PaymentRequestView({
|
||||
Amounts.isNonZero(totalFees) && (
|
||||
<Part
|
||||
big
|
||||
title="Total to pay"
|
||||
title={<Translate>Total to pay</Translate>}
|
||||
text={amountToString(payStatus.amountEffective)}
|
||||
kind="negative"
|
||||
/>
|
||||
)}
|
||||
<Part
|
||||
big
|
||||
title="Purchase amount"
|
||||
title={<Translate>Purchase amount</Translate>}
|
||||
text={amountToString(payStatus.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
@ -341,21 +379,25 @@ export function PaymentRequestView({
|
||||
<Fragment>
|
||||
<Part
|
||||
big
|
||||
title="Fee"
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToString(totalFees)}
|
||||
kind="negative"
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
<Part
|
||||
title="Merchant"
|
||||
title={<Translate>Merchant</Translate>}
|
||||
text={contractTerms.merchant.name}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part title="Purchase" text={contractTerms.summary} kind="neutral" />
|
||||
<Part
|
||||
title={<Translate>Purchase</Translate>}
|
||||
text={contractTerms.summary}
|
||||
kind="neutral"
|
||||
/>
|
||||
{contractTerms.order_id && (
|
||||
<Part
|
||||
title="Receipt"
|
||||
title={<Translate>Receipt</Translate>}
|
||||
text={`#${contractTerms.order_id}`}
|
||||
kind="neutral"
|
||||
/>
|
||||
@ -373,7 +415,7 @@ function ProductList({ products }: { products: Product[] }): VNode {
|
||||
return (
|
||||
<Fragment>
|
||||
<SmallLightText style={{ margin: ".5em" }}>
|
||||
List of products
|
||||
<Translate>List of products</Translate>
|
||||
</SmallLightText>
|
||||
<dl>
|
||||
{products.map((p, i) => {
|
||||
@ -415,15 +457,18 @@ function ProductList({ products }: { products: Product[] }): VNode {
|
||||
{p.quantity ?? 1} x {p.description}
|
||||
</dt>
|
||||
<dd>
|
||||
Total{` `}
|
||||
{p.price
|
||||
? `${Amounts.stringifyValue(
|
||||
Amounts.mult(
|
||||
Amounts.parseOrThrow(p.price),
|
||||
p.quantity ?? 1,
|
||||
).amount,
|
||||
)} ${p}`
|
||||
: "free"}
|
||||
<Translate>Total</Translate>
|
||||
{` `}
|
||||
{p.price ? (
|
||||
`${Amounts.stringifyValue(
|
||||
Amounts.mult(
|
||||
Amounts.parseOrThrow(p.price),
|
||||
p.quantity ?? 1,
|
||||
).amount,
|
||||
)} ${p}`
|
||||
) : (
|
||||
<Translate>free</Translate>
|
||||
)}
|
||||
</dd>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,10 +17,10 @@
|
||||
/**
|
||||
* Page that shows refund status for purchases.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
import { Amounts, ApplyRefundResponse } from "@gnu-taler/taler-util";
|
||||
import { Amounts, ApplyRefundResponse, Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { AmountView } from "../renderHtml";
|
||||
@ -37,20 +37,28 @@ export function View({ applyResult }: ViewProps): VNode {
|
||||
<section class="main">
|
||||
<h1>GNU Taler Wallet</h1>
|
||||
<article class="fade">
|
||||
<h2>Refund Status</h2>
|
||||
<h2>
|
||||
<Translate>Refund Status</Translate>
|
||||
</h2>
|
||||
<p>
|
||||
The product <em>{applyResult.info.summary}</em> has received a total
|
||||
effective refund of{" "}
|
||||
<Translate>
|
||||
The product <em>{applyResult.info.summary}</em> has received a total
|
||||
effective refund of{" "}
|
||||
</Translate>
|
||||
<AmountView amount={applyResult.amountRefundGranted} />.
|
||||
</p>
|
||||
{applyResult.pendingAtExchange ? (
|
||||
<p>Refund processing is still in progress.</p>
|
||||
<p>
|
||||
<Translate>Refund processing is still in progress.</Translate>
|
||||
</p>
|
||||
) : null}
|
||||
{!Amounts.isZero(applyResult.amountRefundGone) ? (
|
||||
<p>
|
||||
The refund amount of{" "}
|
||||
<AmountView amount={applyResult.amountRefundGone} /> could not be
|
||||
applied.
|
||||
<Translate>
|
||||
The refund amount of{" "}
|
||||
<AmountView amount={applyResult.amountRefundGone} /> could not be
|
||||
applied.
|
||||
</Translate>
|
||||
</p>
|
||||
) : null}
|
||||
</article>
|
||||
@ -82,15 +90,27 @@ export function RefundPage({ talerRefundUri }: Props): VNode {
|
||||
console.log("rendering");
|
||||
|
||||
if (!talerRefundUri) {
|
||||
return <span>missing taler refund uri</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>missing taler refund uri</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (errMsg) {
|
||||
return <span>Error: {errMsg}</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>Error: {errMsg}</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (!applyResult) {
|
||||
return <span>Updating refund status</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>Updating refund status</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return <View applyResult={applyResult} />;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { i18n } from "@gnu-taler/taler-util";
|
||||
import { i18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { CheckboxOutlined } from "../components/CheckboxOutlined";
|
||||
import { ExchangeXmlTos } from "../components/ExchangeToS";
|
||||
@ -34,7 +34,7 @@ export function TermsOfServiceSection({
|
||||
{terms.status === "notfound" && (
|
||||
<section>
|
||||
<WarningText>
|
||||
{i18n.str`Exchange doesn't have terms of service`}
|
||||
<Translate>Exchange doesn't have terms of service</Translate>
|
||||
</WarningText>
|
||||
</section>
|
||||
)}
|
||||
@ -46,21 +46,21 @@ export function TermsOfServiceSection({
|
||||
{terms.status === "notfound" && (
|
||||
<section>
|
||||
<WarningText>
|
||||
{i18n.str`Exchange doesn't have terms of service`}
|
||||
<Translate>Exchange doesn't have terms of service</Translate>
|
||||
</WarningText>
|
||||
</section>
|
||||
)}
|
||||
{terms.status === "new" && (
|
||||
<section>
|
||||
<ButtonSuccess upperCased onClick={() => onReview(true)}>
|
||||
{i18n.str`Review exchange terms of service`}
|
||||
<Translate>Review exchange terms of service</Translate>
|
||||
</ButtonSuccess>
|
||||
</section>
|
||||
)}
|
||||
{terms.status === "changed" && (
|
||||
<section>
|
||||
<ButtonWarning upperCased onClick={() => onReview(true)}>
|
||||
{i18n.str`Review new version of terms of service`}
|
||||
<Translate>Review new version of terms of service</Translate>
|
||||
</ButtonWarning>
|
||||
</section>
|
||||
)}
|
||||
@ -72,7 +72,7 @@ export function TermsOfServiceSection({
|
||||
{onReview && (
|
||||
<section>
|
||||
<LinkSuccess upperCased onClick={() => onReview(true)}>
|
||||
{i18n.str`Show terms of service`}
|
||||
<Translate>Show terms of service</Translate>
|
||||
</LinkSuccess>
|
||||
</section>
|
||||
)}
|
||||
@ -80,7 +80,9 @@ export function TermsOfServiceSection({
|
||||
<CheckboxOutlined
|
||||
name="terms"
|
||||
enabled={reviewed}
|
||||
label={i18n.str`I accept the exchange terms of service`}
|
||||
label={
|
||||
<Translate>I accept the exchange terms of service</Translate>
|
||||
}
|
||||
onToggle={() => {
|
||||
onAccept(!reviewed);
|
||||
if (onReview) onReview(false);
|
||||
@ -95,7 +97,9 @@ export function TermsOfServiceSection({
|
||||
{terms.status !== "notfound" && !terms.content && (
|
||||
<section>
|
||||
<WarningBox>
|
||||
The exchange reply with a empty terms of service
|
||||
<Translate>
|
||||
The exchange reply with a empty terms of service
|
||||
</Translate>
|
||||
</WarningBox>
|
||||
</section>
|
||||
)}
|
||||
@ -116,7 +120,7 @@ export function TermsOfServiceSection({
|
||||
)}
|
||||
{terms.content.type === "pdf" && (
|
||||
<a href={terms.content.location.toString()} download="tos.pdf">
|
||||
Download Terms of Service
|
||||
<Translate>Download Terms of Service</Translate>
|
||||
</a>
|
||||
)}
|
||||
</section>
|
||||
@ -124,7 +128,7 @@ export function TermsOfServiceSection({
|
||||
{reviewed && onReview && (
|
||||
<section>
|
||||
<LinkSuccess upperCased onClick={() => onReview(false)}>
|
||||
{i18n.str`Hide terms of service`}
|
||||
<Translate>Hide terms of service</Translate>
|
||||
</LinkSuccess>
|
||||
</section>
|
||||
)}
|
||||
@ -133,7 +137,9 @@ export function TermsOfServiceSection({
|
||||
<CheckboxOutlined
|
||||
name="terms"
|
||||
enabled={reviewed}
|
||||
label={i18n.str`I accept the exchange terms of service`}
|
||||
label={
|
||||
<Translate>I accept the exchange terms of service</Translate>
|
||||
}
|
||||
onToggle={() => {
|
||||
onAccept(!reviewed);
|
||||
if (onReview) onReview(false);
|
||||
|
@ -17,10 +17,10 @@
|
||||
/**
|
||||
* Page shown to the user to accept or ignore a tip from a merchant.
|
||||
*
|
||||
* @author Florian Dold <dold@taler.net>
|
||||
* @author sebasjm <dold@taler.net>
|
||||
*/
|
||||
|
||||
import { PrepareTipResult } from "@gnu-taler/taler-util";
|
||||
import { PrepareTipResult, Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { Loading } from "../components/Loading";
|
||||
@ -46,21 +46,29 @@ export function View({
|
||||
<article class="fade">
|
||||
{prepareTipResult.accepted ? (
|
||||
<span>
|
||||
Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted.
|
||||
Check your transactions list for more details.
|
||||
<Translate>
|
||||
Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted.
|
||||
Check your transactions list for more details.
|
||||
</Translate>
|
||||
</span>
|
||||
) : (
|
||||
<div>
|
||||
<p>
|
||||
The merchant <code>{prepareTipResult.merchantBaseUrl}</code> is
|
||||
offering you a tip of{" "}
|
||||
<strong>
|
||||
<AmountView amount={prepareTipResult.tipAmountEffective} />
|
||||
</strong>{" "}
|
||||
via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code>
|
||||
<Translate>
|
||||
The merchant <code>{prepareTipResult.merchantBaseUrl}</code> is
|
||||
offering you a tip of{" "}
|
||||
<strong>
|
||||
<AmountView amount={prepareTipResult.tipAmountEffective} />
|
||||
</strong>{" "}
|
||||
via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code>
|
||||
</Translate>
|
||||
</p>
|
||||
<button onClick={onAccept}>Accept tip</button>
|
||||
<button onClick={onIgnore}>Ignore</button>
|
||||
<button onClick={onAccept}>
|
||||
<Translate>Accept tip</Translate>
|
||||
</button>
|
||||
<button onClick={onIgnore}>
|
||||
<Translate>Ignore</Translate>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</article>
|
||||
@ -98,11 +106,19 @@ export function TipPage({ talerTipUri }: Props): VNode {
|
||||
};
|
||||
|
||||
if (!talerTipUri) {
|
||||
return <span>missing tip uri</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>missing tip uri</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (tipIgnored) {
|
||||
return <span>You've ignored the tip.</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>You've ignored the tip.</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (!prepareTipResult) {
|
||||
|
@ -18,7 +18,7 @@
|
||||
* Page shown to the user to confirm creation
|
||||
* of a reserve, usually requested by the bank.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
import {
|
||||
@ -26,6 +26,7 @@ import {
|
||||
Amounts,
|
||||
ExchangeListItem,
|
||||
i18n,
|
||||
Translate,
|
||||
WithdrawUriInfoResponse,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
|
||||
@ -117,37 +118,46 @@ export function View({
|
||||
return (
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
<h2>{i18n.str`Digital cash withdrawal`}</h2>
|
||||
<h2>
|
||||
<Translate>Digital cash withdrawal</Translate>
|
||||
</h2>
|
||||
|
||||
{withdrawError && (
|
||||
<ErrorTalerOperation
|
||||
title="Could not finish the withdrawal operation"
|
||||
title={
|
||||
<Translate>Could not finish the withdrawal operation</Translate>
|
||||
}
|
||||
error={withdrawError.operationError}
|
||||
/>
|
||||
)}
|
||||
|
||||
<section>
|
||||
<Part
|
||||
title="Total to withdraw"
|
||||
title={<Translate>Total to withdraw</Translate>}
|
||||
text={amountToString(Amounts.sub(amount, withdrawalFee).amount)}
|
||||
kind="positive"
|
||||
/>
|
||||
{Amounts.isNonZero(withdrawalFee) && (
|
||||
<Fragment>
|
||||
<Part
|
||||
title="Chosen amount"
|
||||
title={<Translate>Chosen amount</Translate>}
|
||||
text={amountToString(amount)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part
|
||||
title="Exchange fee"
|
||||
title={<Translate>Exchange fee</Translate>}
|
||||
text={amountToString(withdrawalFee)}
|
||||
kind="negative"
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
{exchangeBaseUrl && (
|
||||
<Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
|
||||
<Part
|
||||
title={<Translate>Exchange</Translate>}
|
||||
text={exchangeBaseUrl}
|
||||
kind="neutral"
|
||||
big
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
{!reviewing && (
|
||||
@ -156,7 +166,7 @@ export function View({
|
||||
<Fragment>
|
||||
<div>
|
||||
<SelectList
|
||||
label="Known exchanges"
|
||||
label={<Translate>Known exchanges</Translate>}
|
||||
list={exchanges}
|
||||
value={nextExchange}
|
||||
name="switchingExchange"
|
||||
@ -172,14 +182,16 @@ export function View({
|
||||
setSwitchingExchange(false);
|
||||
}}
|
||||
>
|
||||
{nextExchange === undefined
|
||||
? i18n.str`Cancel exchange selection`
|
||||
: i18n.str`Confirm exchange selection`}
|
||||
{nextExchange === undefined ? (
|
||||
<Translate>Cancel exchange selection</Translate>
|
||||
) : (
|
||||
<Translate>Confirm exchange selection</Translate>
|
||||
)}
|
||||
</LinkSuccess>
|
||||
</Fragment>
|
||||
) : (
|
||||
<LinkSuccess upperCased onClick={() => setSwitchingExchange(true)}>
|
||||
{i18n.str`Switch exchange`}
|
||||
<Translate>Switch exchange</Translate>
|
||||
</LinkSuccess>
|
||||
)}
|
||||
</section>
|
||||
@ -198,7 +210,7 @@ export function View({
|
||||
disabled={!exchangeBaseUrl || confirmDisabled}
|
||||
onClick={doWithdrawAndCheckError}
|
||||
>
|
||||
{i18n.str`Confirm withdrawal`}
|
||||
<Translate>Confirm withdrawal</Translate>
|
||||
</ButtonSuccess>
|
||||
)}
|
||||
{terms.status === "notfound" && (
|
||||
@ -207,7 +219,7 @@ export function View({
|
||||
disabled={!exchangeBaseUrl}
|
||||
onClick={doWithdrawAndCheckError}
|
||||
>
|
||||
{i18n.str`Withdraw anyway`}
|
||||
<Translate>Withdraw anyway</Translate>
|
||||
</ButtonWarning>
|
||||
)}
|
||||
</section>
|
||||
@ -270,7 +282,7 @@ export function WithdrawPageWithParsedURI({
|
||||
if (detailsHook.hasError) {
|
||||
return (
|
||||
<LoadingError
|
||||
title="Could not load the withdrawal details"
|
||||
title={<Translate>Could not load the withdrawal details</Translate>}
|
||||
error={detailsHook}
|
||||
/>
|
||||
);
|
||||
@ -293,9 +305,7 @@ export function WithdrawPageWithParsedURI({
|
||||
|
||||
const onWithdraw = async (): Promise<void> => {
|
||||
if (!exchange) return;
|
||||
console.log("accepting exchange", exchange);
|
||||
const res = await wxApi.acceptWithdrawal(uri, exchange);
|
||||
console.log("accept withdrawal response", res);
|
||||
if (res.confirmTransferUrl) {
|
||||
document.location.href = res.confirmTransferUrl;
|
||||
}
|
||||
@ -327,7 +337,7 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
|
||||
if (!talerWithdrawUri) {
|
||||
return (
|
||||
<span>
|
||||
<i18n.Translate>missing withdraw uri</i18n.Translate>
|
||||
<Translate>missing withdraw uri</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@ -337,7 +347,7 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
|
||||
if (uriInfoHook.hasError) {
|
||||
return (
|
||||
<LoadingError
|
||||
title="Could not get the info from the URI"
|
||||
title={<Translate>Could not get the info from the URI</Translate>}
|
||||
error={uriInfoHook}
|
||||
/>
|
||||
);
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2017 Inria
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { h, VNode } from "preact";
|
||||
|
||||
/**
|
||||
* View and edit auditors.
|
||||
*
|
||||
* @author Florian Dold
|
||||
*/
|
||||
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
|
||||
export function makePaybackPage(): VNode {
|
||||
return <div>not implemented</div>;
|
||||
}
|
@ -17,9 +17,10 @@
|
||||
/**
|
||||
* Page to inform the user when a database reset is required.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { Component, h, VNode } from "preact";
|
||||
import * as wxApi from "../wxApi";
|
||||
|
||||
@ -49,14 +50,20 @@ class ResetNotification extends Component<any, State> {
|
||||
if (this.state.resetRequired) {
|
||||
return (
|
||||
<div>
|
||||
<h1>Manual Reset Required</h1>
|
||||
<h1>
|
||||
<Translate>Manual Reset Required</Translate>
|
||||
</h1>
|
||||
<p>
|
||||
The wallet's database in your browser is incompatible with the{" "}
|
||||
currently installed wallet. Please reset manually.
|
||||
<Translate>
|
||||
The wallet's database in your browser is incompatible with
|
||||
the currently installed wallet. Please reset manually.
|
||||
</Translate>
|
||||
</p>
|
||||
<p>
|
||||
Once the database format has stabilized, we will provide automatic
|
||||
upgrades.
|
||||
<Translate>
|
||||
Once the database format has stabilized, we will provide automatic
|
||||
upgrades.
|
||||
</Translate>
|
||||
</p>
|
||||
<input
|
||||
id="check"
|
||||
@ -67,7 +74,7 @@ class ResetNotification extends Component<any, State> {
|
||||
}}
|
||||
/>{" "}
|
||||
<label htmlFor="check">
|
||||
I understand that I will lose all my data
|
||||
<Translate>I understand that I will lose all my data</Translate>
|
||||
</label>
|
||||
<br />
|
||||
<button
|
||||
@ -75,15 +82,21 @@ class ResetNotification extends Component<any, State> {
|
||||
disabled={!this.state.checked}
|
||||
onClick={() => wxApi.resetDb()}
|
||||
>
|
||||
Reset
|
||||
<Translate>Reset</Translate>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<h1>Everything is fine!</h1>A reset is not required anymore, you can
|
||||
close this page.
|
||||
<h1>
|
||||
<Translate>Everything is fine!</Translate>
|
||||
</h1>
|
||||
<p>
|
||||
<Translate>
|
||||
A reset is not required anymore, you can close this page.
|
||||
</Translate>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -14,16 +14,21 @@
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
/**
|
||||
* Return coins to own bank account.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
export function createReturnCoinsPage(): VNode {
|
||||
return <span>Not implemented yet.</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>Not implemented yet.</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,275 +17,38 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/NavigationBar.tsx:86
|
||||
#, c-format
|
||||
msgid "Balance"
|
||||
msgstr ""
|
||||
|
||||
#: src/NavigationBar.tsx:87
|
||||
#, c-format
|
||||
msgid "Pending"
|
||||
msgstr ""
|
||||
|
||||
#: src/NavigationBar.tsx:88
|
||||
#, c-format
|
||||
msgid "Backup"
|
||||
msgstr ""
|
||||
|
||||
#: src/NavigationBar.tsx:89
|
||||
#: src/NavigationBar.tsx:71
|
||||
#, c-format
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/NavigationBar.tsx:90
|
||||
#, c-format
|
||||
msgid "Dev"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/BackupPage.tsx:127
|
||||
#, c-format
|
||||
msgid "Add provider"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/BackupPage.tsx:137
|
||||
#, c-format
|
||||
msgid "Sync all backups"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/BackupPage.tsx:139
|
||||
#, c-format
|
||||
msgid "Sync now"
|
||||
msgstr ""
|
||||
|
||||
#: src/popup/BalancePage.tsx:79
|
||||
#, c-format
|
||||
msgid "You have no balance to show. Need some %1$s getting started?"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderAddPage.tsx:145
|
||||
#, c-format
|
||||
msgid "< Back"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderAddPage.tsx:156
|
||||
#, c-format
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:57
|
||||
#, c-format
|
||||
msgid "Loading..."
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:64
|
||||
#, c-format
|
||||
msgid "There was an error loading the provider detail for \"%1$s\""
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:75
|
||||
#, c-format
|
||||
msgid "There is not known provider with url \"%1$s\". Redirecting back..."
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:131
|
||||
#, c-format
|
||||
msgid "Back up"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:142
|
||||
#, c-format
|
||||
msgid "Extend"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:148
|
||||
#: src/popup/DeveloperPage.tsx:377
|
||||
#, c-format
|
||||
msgid ""
|
||||
"terms has changed, extending the service will imply accepting the new terms of "
|
||||
"service"
|
||||
"Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL "
|
||||
"YOUR COINS?"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:158
|
||||
#: src/wallet/CreateManualWithdraw.tsx:102
|
||||
#, c-format
|
||||
msgid "old"
|
||||
msgid "Manual Withdrawal"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:162
|
||||
#: src/wallet/CreateManualWithdraw.tsx:104
|
||||
#, c-format
|
||||
msgid "new"
|
||||
msgid ""
|
||||
"Choose a exchange from where the coins will be withdrawn. The exchange\n"
|
||||
" will send the coins to this wallet after receiving a wire transfer\n"
|
||||
" with the correct subject."
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:169
|
||||
#: src/wallet/CreateManualWithdraw.tsx:109
|
||||
#, c-format
|
||||
msgid "fee"
|
||||
msgid "No exchange configured"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:177
|
||||
#, c-format
|
||||
msgid "storage"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:190
|
||||
#, c-format
|
||||
msgid "< back"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:194
|
||||
#, c-format
|
||||
msgid "remove provider"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:213
|
||||
#, c-format
|
||||
msgid "There is conflict with another backup from %1$s"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:228
|
||||
#, c-format
|
||||
msgid "Unknown backup problem: %1$s"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ProviderDetailPage.tsx:247
|
||||
#, c-format
|
||||
msgid "service paid"
|
||||
msgstr ""
|
||||
|
||||
#: src/popup/Settings.tsx:46
|
||||
#, c-format
|
||||
msgid "Permissions"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/TermsOfServiceSection.tsx:37
|
||||
#, c-format
|
||||
msgid "Exchange doesn't have terms of service"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/TermsOfServiceSection.tsx:56
|
||||
#, c-format
|
||||
msgid "Review exchange terms of service"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/TermsOfServiceSection.tsx:63
|
||||
#, c-format
|
||||
msgid "Review new version of terms of service"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/TermsOfServiceSection.tsx:75
|
||||
#, c-format
|
||||
msgid "Show terms of service"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/TermsOfServiceSection.tsx:83
|
||||
#, c-format
|
||||
msgid "I accept the exchange terms of service"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/TermsOfServiceSection.tsx:127
|
||||
#, c-format
|
||||
msgid "Hide terms of service"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ExchangeAddConfirm.tsx:110
|
||||
#, c-format
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ExchangeAddConfirm.tsx:114
|
||||
#, c-format
|
||||
msgid "Loading terms.."
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ExchangeAddConfirm.tsx:121
|
||||
#: src/wallet/CreateManualWithdraw.tsx:111
|
||||
#, c-format
|
||||
msgid "Add exchange"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/ExchangeAddConfirm.tsx:131
|
||||
#, c-format
|
||||
msgid "Add exchange anyway"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/Settings.tsx:95
|
||||
#, c-format
|
||||
msgid "Known exchanges"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/Transaction.tsx:159
|
||||
#, c-format
|
||||
msgid "retry"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/Transaction.tsx:163
|
||||
#, c-format
|
||||
msgid "Forget"
|
||||
msgstr ""
|
||||
|
||||
#: src/wallet/Transaction.tsx:198
|
||||
#, c-format
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Pay.tsx:211
|
||||
#, c-format
|
||||
msgid "Pay with a mobile phone"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Pay.tsx:211
|
||||
#, c-format
|
||||
msgid "Hide QR"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Pay.tsx:241
|
||||
#, c-format
|
||||
msgid "Pay"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Pay.tsx:265
|
||||
#, c-format
|
||||
msgid "Withdraw digital cash"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Pay.tsx:295
|
||||
#, c-format
|
||||
msgid "Digital cash payment"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:101
|
||||
#, c-format
|
||||
msgid "Digital cash withdrawal"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:149
|
||||
#, c-format
|
||||
msgid "Cancel exchange selection"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:150
|
||||
#, c-format
|
||||
msgid "Confirm exchange selection"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:155
|
||||
#, c-format
|
||||
msgid "Switch exchange"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:174
|
||||
#, c-format
|
||||
msgid "Confirm withdrawal"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:183
|
||||
#, c-format
|
||||
msgid "Withdraw anyway"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Withdraw.tsx:310
|
||||
#, c-format
|
||||
msgid "missing withdraw uri"
|
||||
msgstr ""
|
||||
|
||||
#: src/cta/Deposit.tsx:186
|
||||
#, c-format
|
||||
msgid "Digital cash deposit"
|
||||
msgstr ""
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { Amounts, Balance } from "@gnu-taler/taler-util";
|
||||
import { Amounts, Balance, Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { BalanceTable } from "../components/BalanceTable";
|
||||
@ -47,7 +47,12 @@ export function BalancePage({
|
||||
}
|
||||
|
||||
if (state.hasError) {
|
||||
return <LoadingError title="Could not load balance page" error={state} />;
|
||||
return (
|
||||
<LoadingError
|
||||
title={<Translate>Could not load balance page</Translate>}
|
||||
error={state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (addingAction) {
|
||||
@ -99,17 +104,19 @@ export function BalanceView({
|
||||
</section>
|
||||
<footer style={{ justifyContent: "space-between" }}>
|
||||
<ButtonPrimary onClick={goToWalletManualWithdraw}>
|
||||
Withdraw
|
||||
<Translate>Withdraw</Translate>
|
||||
</ButtonPrimary>
|
||||
{currencyWithNonZeroAmount.length > 0 && (
|
||||
<MultiActionButton
|
||||
label={(s) => `Deposit ${s}`}
|
||||
label={(s) => <Translate>Deposit {s}</Translate>}
|
||||
actions={currencyWithNonZeroAmount}
|
||||
onClick={(c) => goToWalletDeposit(c)}
|
||||
/>
|
||||
)}
|
||||
<JustInDevMode>
|
||||
<ButtonBoxPrimary onClick={goToAddAction}>enter uri</ButtonBoxPrimary>
|
||||
<ButtonBoxPrimary onClick={goToAddAction}>
|
||||
<Translate>Enter URI</Translate>
|
||||
</ButtonBoxPrimary>
|
||||
</JustInDevMode>
|
||||
</footer>
|
||||
</Fragment>
|
||||
|
@ -20,6 +20,8 @@ import {
|
||||
CoinDumpJson,
|
||||
ExchangeListItem,
|
||||
NotificationType,
|
||||
Translate,
|
||||
i18n,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core";
|
||||
import { format } from "date-fns";
|
||||
@ -31,7 +33,6 @@ import { Time } from "../components/Time";
|
||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||
import { useDiagnostics } from "../hooks/useDiagnostics";
|
||||
import * as wxApi from "../wxApi";
|
||||
import BalanceStories from "./Balance.stories";
|
||||
|
||||
export function DeveloperPage(): VNode {
|
||||
const [status, timedOut] = useDiagnostics();
|
||||
@ -149,10 +150,16 @@ export function View({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Debug tools:</p>
|
||||
<button onClick={confirmReset}>reset</button>
|
||||
<p>
|
||||
<Translate>Debug tools</Translate>:
|
||||
</p>
|
||||
<button onClick={confirmReset}>
|
||||
<Translate>reset</Translate>
|
||||
</button>
|
||||
<br />
|
||||
<button onClick={() => fileRef?.current?.click()}>import database</button>
|
||||
<button onClick={() => fileRef?.current?.click()}>
|
||||
<Translate>import database</Translate>
|
||||
</button>
|
||||
<input
|
||||
ref={fileRef}
|
||||
style={{ display: "none" }}
|
||||
@ -171,31 +178,36 @@ export function View({
|
||||
}}
|
||||
/>
|
||||
<br />
|
||||
<button onClick={onExportDatabase}>export database</button>
|
||||
<button onClick={onExportDatabase}>
|
||||
<Translate>export database</Translate>
|
||||
</button>
|
||||
{downloadedDatabase && (
|
||||
<div>
|
||||
Database exported at
|
||||
<Time
|
||||
timestamp={{ t_ms: downloadedDatabase.time.getTime() }}
|
||||
format="yyyy/MM/dd HH:mm:ss"
|
||||
/>
|
||||
<a
|
||||
href={`data:text/plain;charset=utf-8;base64,${toBase64(
|
||||
downloadedDatabase.content,
|
||||
)}`}
|
||||
download={`taler-wallet-database-${format(
|
||||
downloadedDatabase.time,
|
||||
"yyyy/MM/dd_HH:mm",
|
||||
)}.json`}
|
||||
>
|
||||
{" "}
|
||||
click here{" "}
|
||||
</a>
|
||||
to download
|
||||
<Translate>
|
||||
Database exported at
|
||||
<Time
|
||||
timestamp={{ t_ms: downloadedDatabase.time.getTime() }}
|
||||
format="yyyy/MM/dd HH:mm:ss"
|
||||
/>
|
||||
<a
|
||||
href={`data:text/plain;charset=utf-8;base64,${toBase64(
|
||||
downloadedDatabase.content,
|
||||
)}`}
|
||||
download={`taler-wallet-database-${format(
|
||||
downloadedDatabase.time,
|
||||
"yyyy/MM/dd_HH:mm",
|
||||
)}.json`}
|
||||
>
|
||||
<Translate>click here</Translate>
|
||||
</a>
|
||||
to download
|
||||
</Translate>
|
||||
</div>
|
||||
)}
|
||||
<br />
|
||||
<p>Coins:</p>
|
||||
<p>
|
||||
<Translate>Coins</Translate>:
|
||||
</p>
|
||||
{Object.keys(money_by_exchange).map((ex) => {
|
||||
const allcoins = money_by_exchange[ex];
|
||||
allcoins.sort((a, b) => {
|
||||
@ -220,7 +232,9 @@ export function View({
|
||||
<Diagnostics diagnostics={status} timedOut={timedOut} />
|
||||
{operations && operations.length > 0 && (
|
||||
<Fragment>
|
||||
<p>Pending operations</p>
|
||||
<p>
|
||||
<Translate>Pending operations</Translate>
|
||||
</p>
|
||||
<dl>
|
||||
{operations.reverse().map((o) => {
|
||||
return (
|
||||
@ -257,18 +271,30 @@ function ShowAllCoins({
|
||||
<b>{ex}</b>: {total} {currencies[ex]}
|
||||
</p>
|
||||
<p>
|
||||
<b>usable coins</b>
|
||||
<b>
|
||||
<Translate>usable coins</Translate>
|
||||
</b>
|
||||
</p>
|
||||
{collapsedUnspent ? (
|
||||
<div onClick={() => setCollapsedUnspent(false)}>click to show</div>
|
||||
) : (
|
||||
<table onClick={() => setCollapsedUnspent(true)}>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>denom</td>
|
||||
<td>value</td>
|
||||
<td>status</td>
|
||||
<td>from refresh?</td>
|
||||
<td>
|
||||
<Translate>id</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>denom</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>value</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>status</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>from refresh?</Translate>
|
||||
</td>
|
||||
</tr>
|
||||
{coins.usable.map((c) => {
|
||||
return (
|
||||
@ -283,17 +309,31 @@ function ShowAllCoins({
|
||||
})}
|
||||
</table>
|
||||
)}
|
||||
<p>spent coins</p>
|
||||
<p>
|
||||
<Translate>spent coins</Translate>
|
||||
</p>
|
||||
{collapsedSpent ? (
|
||||
<div onClick={() => setCollapsedSpent(false)}>click to show</div>
|
||||
<div onClick={() => setCollapsedSpent(false)}>
|
||||
<Translate>click to show</Translate>
|
||||
</div>
|
||||
) : (
|
||||
<table onClick={() => setCollapsedSpent(true)}>
|
||||
<tr>
|
||||
<td>id</td>
|
||||
<td>denom</td>
|
||||
<td>value</td>
|
||||
<td>status</td>
|
||||
<td>refresh?</td>
|
||||
<td>
|
||||
<Translate>id</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>denom</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>value</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>status</Translate>
|
||||
</td>
|
||||
<td>
|
||||
<Translate>from refresh?</Translate>
|
||||
</td>
|
||||
</tr>
|
||||
{coins.spent.map((c) => {
|
||||
return (
|
||||
@ -335,8 +375,7 @@ function runIntegrationTest() {}
|
||||
export async function confirmReset(): Promise<void> {
|
||||
if (
|
||||
confirm(
|
||||
"Do you want to IRREVOCABLY DESTROY everything inside your" +
|
||||
" wallet and LOSE ALL YOUR COINS?",
|
||||
i18n.str`Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?`,
|
||||
)
|
||||
) {
|
||||
await wxApi.resetDb();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { i18n } from "@gnu-taler/taler-util";
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
import { ButtonBoxWarning, WarningBox } from "../components/styled";
|
||||
|
||||
@ -11,16 +11,16 @@ export function NoBalanceHelp({
|
||||
<WarningBox>
|
||||
<p>
|
||||
<b>
|
||||
<i18n.Translate>You have no balance to show.</i18n.Translate>
|
||||
<Translate>You have no balance to show.</Translate>
|
||||
</b>
|
||||
<br />
|
||||
<i18n.Translate>
|
||||
<Translate>
|
||||
To withdraw money you can start from your bank site or click the
|
||||
"withdraw" button to use a known exchange.
|
||||
</i18n.Translate>
|
||||
</Translate>
|
||||
</p>
|
||||
<ButtonBoxWarning onClick={() => goToWalletManualWithdraw()}>
|
||||
Withdraw
|
||||
<Translate>Withdraw</Translate>
|
||||
</ButtonBoxWarning>
|
||||
</WarningBox>
|
||||
);
|
||||
|
@ -19,7 +19,11 @@
|
||||
* @author Sebastian Javier Marchano (sebasjm)
|
||||
*/
|
||||
|
||||
import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
classifyTalerUri,
|
||||
TalerUriType,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Fragment, h } from "preact";
|
||||
import { ButtonPrimary, ButtonSuccess } from "../components/styled";
|
||||
import { actionForTalerUri } from "../utils/index";
|
||||
@ -52,46 +56,56 @@ export function TalerActionFound({ url, onDismiss }: Props) {
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<h1>Taler Action </h1>
|
||||
<h1>
|
||||
<Translate>Taler Action</Translate>
|
||||
</h1>
|
||||
{uriType === TalerUriType.TalerPay && (
|
||||
<div>
|
||||
<p>This page has pay action.</p>
|
||||
<p>
|
||||
<Translate>This page has pay action.</Translate>
|
||||
</p>
|
||||
<ButtonSuccess
|
||||
onClick={() => {
|
||||
navigateTo(actionForTalerUri(uriType, url));
|
||||
}}
|
||||
>
|
||||
Open pay page
|
||||
<Translate>Open pay page</Translate>
|
||||
</ButtonSuccess>
|
||||
</div>
|
||||
)}
|
||||
{uriType === TalerUriType.TalerWithdraw && (
|
||||
<div>
|
||||
<p>This page has a withdrawal action.</p>
|
||||
<p>
|
||||
<Translate>This page has a withdrawal action.</Translate>
|
||||
</p>
|
||||
<ButtonSuccess
|
||||
onClick={() => {
|
||||
navigateTo(actionForTalerUri(uriType, url));
|
||||
}}
|
||||
>
|
||||
Open withdraw page
|
||||
<Translate>Open withdraw page</Translate>
|
||||
</ButtonSuccess>
|
||||
</div>
|
||||
)}
|
||||
{uriType === TalerUriType.TalerTip && (
|
||||
<div>
|
||||
<p>This page has a tip action.</p>
|
||||
<p>
|
||||
<Translate>This page has a tip action.</Translate>
|
||||
</p>
|
||||
<ButtonSuccess
|
||||
onClick={() => {
|
||||
navigateTo(actionForTalerUri(uriType, url));
|
||||
}}
|
||||
>
|
||||
Open tip page
|
||||
<Translate>Open tip page</Translate>
|
||||
</ButtonSuccess>
|
||||
</div>
|
||||
)}
|
||||
{uriType === TalerUriType.TalerNotifyReserve && (
|
||||
<div>
|
||||
<p>This page has a notify reserve action.</p>
|
||||
<p>
|
||||
<Translate>This page has a notify reserve action.</Translate>
|
||||
</p>
|
||||
<ButtonSuccess
|
||||
onClick={() => {
|
||||
navigateTo(actionForTalerUri(uriType, url));
|
||||
@ -103,26 +117,33 @@ export function TalerActionFound({ url, onDismiss }: Props) {
|
||||
)}
|
||||
{uriType === TalerUriType.TalerRefund && (
|
||||
<div>
|
||||
<p>This page has a refund action.</p>
|
||||
<p>
|
||||
<Translate>This page has a refund action.</Translate>
|
||||
</p>
|
||||
<ButtonSuccess
|
||||
onClick={() => {
|
||||
navigateTo(actionForTalerUri(uriType, url));
|
||||
}}
|
||||
>
|
||||
Open refund page
|
||||
<Translate>Open refund page</Translate>
|
||||
</ButtonSuccess>
|
||||
</div>
|
||||
)}
|
||||
{uriType === TalerUriType.Unknown && (
|
||||
<div>
|
||||
<p>This page has a malformed taler uri.</p>
|
||||
<p>
|
||||
<Translate>This page has a malformed taler uri.</Translate>
|
||||
</p>
|
||||
<p>{url}</p>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
<footer>
|
||||
<div />
|
||||
<ButtonPrimary onClick={() => onDismiss()}> Dismiss </ButtonPrimary>
|
||||
<ButtonPrimary onClick={() => onDismiss()}>
|
||||
{" "}
|
||||
<Translate>Dismiss</Translate>{" "}
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</Fragment>
|
||||
);
|
||||
|
@ -17,10 +17,10 @@
|
||||
/**
|
||||
* Main entry point for extension pages.
|
||||
*
|
||||
* @author Florian Dold <dold@taler.net>
|
||||
* @author sebasjm <dold@taler.net>
|
||||
*/
|
||||
|
||||
import { setupI18n } from "@gnu-taler/taler-util";
|
||||
import { setupI18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { createHashHistory } from "history";
|
||||
import { Fragment, h, render, VNode } from "preact";
|
||||
import Router, { route, Route } from "preact-router";
|
||||
@ -87,27 +87,20 @@ function Application(): VNode {
|
||||
<CheckTalerActionComponent />
|
||||
<PopupBox devMode={devMode}>
|
||||
<Router history={hash_history}>
|
||||
<Route path={Pages.dev} component={DeveloperPage} />
|
||||
|
||||
<Route
|
||||
path={Pages.balance}
|
||||
component={BalancePage}
|
||||
goToWalletManualWithdraw={() =>
|
||||
goToWalletPage(
|
||||
Pages.balance_manual_withdraw.replace(":currency?", ""),
|
||||
)
|
||||
route(Pages.balance_manual_withdraw.replace(":currency?", ""))
|
||||
}
|
||||
goToWalletDeposit={(currency: string) =>
|
||||
goToWalletPage(
|
||||
Pages.balance_deposit.replace(":currency", currency),
|
||||
)
|
||||
route(Pages.balance_deposit.replace(":currency", currency))
|
||||
}
|
||||
goToWalletHistory={(currency: string) =>
|
||||
goToWalletPage(
|
||||
Pages.balance_history.replace(":currency", currency),
|
||||
)
|
||||
route(Pages.balance_history.replace(":currency", currency))
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path={Pages.cta}
|
||||
component={function Action({ action }: { action: string }) {
|
||||
@ -139,21 +132,29 @@ function Application(): VNode {
|
||||
route(Pages.backup);
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path={Pages.backup_provider_add}
|
||||
component={ProviderAddPage}
|
||||
onBack={() => {
|
||||
route(Pages.backup);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path={Pages.settings_exchange_add}
|
||||
component={ExchangeAddPage}
|
||||
onBack={() => {
|
||||
route(Pages.balance);
|
||||
}}
|
||||
path={Pages.balance_manual_withdraw}
|
||||
component={RedirectToWalletPage}
|
||||
/>
|
||||
<Route
|
||||
path={Pages.balance_deposit}
|
||||
component={RedirectToWalletPage}
|
||||
/>
|
||||
<Route
|
||||
path={Pages.balance_history}
|
||||
component={RedirectToWalletPage}
|
||||
/>
|
||||
<Route
|
||||
path={Pages.backup_provider_add}
|
||||
component={RedirectToWalletPage}
|
||||
/>
|
||||
<Route path={Pages.settings} component={RedirectToWalletPage} />
|
||||
<Route
|
||||
path={Pages.settings_exchange_add}
|
||||
component={RedirectToWalletPage}
|
||||
/>
|
||||
<Route path={Pages.dev} component={RedirectToWalletPage} />
|
||||
|
||||
<Route default component={Redirect} to={Pages.balance} />
|
||||
</Router>
|
||||
@ -165,15 +166,26 @@ function Application(): VNode {
|
||||
);
|
||||
}
|
||||
|
||||
async function goToWalletPage(page: Pages | string): Promise<void> {
|
||||
// eslint-disable-next-line no-undef
|
||||
await chrome.tabs.create({
|
||||
active: true,
|
||||
// eslint-disable-next-line no-undef
|
||||
url: chrome.runtime.getURL(`/static/wallet.html#${page}`),
|
||||
function RedirectToWalletPage(): VNode {
|
||||
const page = document.location.hash || "#/";
|
||||
useEffect(() => {
|
||||
chrome.tabs
|
||||
.create({
|
||||
active: true,
|
||||
// eslint-disable-next-line no-undef
|
||||
url: chrome.runtime.getURL(`/static/wallet.html${page}`),
|
||||
})
|
||||
.then(() => {
|
||||
window.close();
|
||||
});
|
||||
});
|
||||
window.close();
|
||||
// return null;
|
||||
return (
|
||||
<span>
|
||||
<Translate>
|
||||
this popup is being closed and you are being redirected to {page}
|
||||
</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function Redirect({ to }: { to: string }): null {
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
classifyTalerUri,
|
||||
TalerUriType,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { Button, ButtonSuccess, InputWithLabel } from "../components/styled";
|
||||
@ -8,20 +12,20 @@ export interface Props {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
function buttonLabelByTalerType(type: TalerUriType): string {
|
||||
function buttonLabelByTalerType(type: TalerUriType): VNode {
|
||||
switch (type) {
|
||||
case TalerUriType.TalerNotifyReserve:
|
||||
return "Open reserve page";
|
||||
return <Translate>Open reserve page</Translate>;
|
||||
case TalerUriType.TalerPay:
|
||||
return "Open pay page";
|
||||
return <Translate>Open pay page</Translate>;
|
||||
case TalerUriType.TalerRefund:
|
||||
return "Open refund page";
|
||||
return <Translate>Open refund page</Translate>;
|
||||
case TalerUriType.TalerTip:
|
||||
return "Open tip page";
|
||||
return <Translate>Open tip page</Translate>;
|
||||
case TalerUriType.TalerWithdraw:
|
||||
return "Open withdraw page";
|
||||
return <Translate>Open withdraw page</Translate>;
|
||||
}
|
||||
return "";
|
||||
return <Fragment />;
|
||||
}
|
||||
|
||||
export function AddNewActionView({ onCancel }: Props): VNode {
|
||||
@ -47,7 +51,9 @@ export function AddNewActionView({ onCancel }: Props): VNode {
|
||||
</InputWithLabel>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>Back</Button>
|
||||
<Button onClick={onCancel}>
|
||||
<Translate>Back</Translate>
|
||||
</Button>
|
||||
{uriType !== TalerUriType.Unknown && (
|
||||
<ButtonSuccess
|
||||
onClick={() => {
|
||||
|
@ -14,7 +14,7 @@
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { i18n, Timestamp } from "@gnu-taler/taler-util";
|
||||
import { i18n, Timestamp, Translate } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
ProviderInfo,
|
||||
ProviderPaymentPaid,
|
||||
@ -71,7 +71,10 @@ export function BackupPage({ onAddProvider }: Props): VNode {
|
||||
}
|
||||
if (status.hasError) {
|
||||
return (
|
||||
<LoadingError title="Could not load backup providers" error={status} />
|
||||
<LoadingError
|
||||
title={<Translate>Could not load backup providers</Translate>}
|
||||
error={status}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -122,9 +125,11 @@ export function BackupView({
|
||||
))}
|
||||
{!providers.length && (
|
||||
<Centered style={{ marginTop: 100 }}>
|
||||
<BoldLight>No backup providers configured</BoldLight>
|
||||
<BoldLight>
|
||||
<Translate>No backup providers configured</Translate>
|
||||
</BoldLight>
|
||||
<ButtonSuccess onClick={onAddProvider}>
|
||||
<i18n.Translate>Add provider</i18n.Translate>
|
||||
<Translate>Add provider</Translate>
|
||||
</ButtonSuccess>
|
||||
</Centered>
|
||||
)}
|
||||
@ -135,12 +140,14 @@ export function BackupView({
|
||||
<div>
|
||||
<ButtonPrimary onClick={onSyncAll}>
|
||||
{providers.length > 1 ? (
|
||||
<i18n.Translate>Sync all backups</i18n.Translate>
|
||||
<Translate>Sync all backups</Translate>
|
||||
) : (
|
||||
<i18n.Translate>Sync now</i18n.Translate>
|
||||
<Translate>Sync now</Translate>
|
||||
)}
|
||||
</ButtonPrimary>
|
||||
<ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess>
|
||||
<ButtonSuccess onClick={onAddProvider}>
|
||||
<Translate>Add provider</Translate>
|
||||
</ButtonSuccess>
|
||||
</div>
|
||||
</footer>
|
||||
)}
|
||||
@ -176,10 +183,14 @@ function BackupLayout(props: TransactionLayoutProps): VNode {
|
||||
</a>
|
||||
|
||||
{dateStr && (
|
||||
<SmallText style={{ marginTop: 5 }}>Last synced: {dateStr}</SmallText>
|
||||
<SmallText style={{ marginTop: 5 }}>
|
||||
<Translate>Last synced</Translate>: {dateStr}
|
||||
</SmallText>
|
||||
)}
|
||||
{!dateStr && (
|
||||
<SmallLightText style={{ marginTop: 5 }}>Not synced</SmallLightText>
|
||||
<SmallLightText style={{ marginTop: 5 }}>
|
||||
<Translate>Not synced</Translate>
|
||||
</SmallLightText>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
@ -196,7 +207,9 @@ function BackupLayout(props: TransactionLayoutProps): VNode {
|
||||
function ExpirationText({ until }: { until: Timestamp }): VNode {
|
||||
return (
|
||||
<Fragment>
|
||||
<CenteredText> Expires in </CenteredText>
|
||||
<CenteredText>
|
||||
<Translate>Expires in</Translate>
|
||||
</CenteredText>
|
||||
<CenteredBoldText {...{ color: colorByTimeToExpire(until) }}>
|
||||
{" "}
|
||||
{daysUntil(until)}{" "}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* @author Sebastian Javier Marchano (sebasjm)
|
||||
*/
|
||||
|
||||
import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util";
|
||||
import { AmountJson, Amounts, i18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { ErrorMessage } from "../components/ErrorMessage";
|
||||
@ -99,16 +99,22 @@ export function CreateManualWithdraw({
|
||||
if (!initialExchange) {
|
||||
return (
|
||||
<section>
|
||||
<h2>Manual Withdrawal</h2>
|
||||
<h2>
|
||||
<Translate>Manual Withdrawal</Translate>
|
||||
</h2>
|
||||
<LightText>
|
||||
Choose a exchange from where the coins will be withdrawn. The exchange
|
||||
will send the coins to this wallet after receiving a wire transfer
|
||||
with the correct subject.
|
||||
<Translate>
|
||||
Choose a exchange from where the coins will be withdrawn. The
|
||||
exchange will send the coins to this wallet after receiving a wire
|
||||
transfer with the correct subject.
|
||||
</Translate>
|
||||
</LightText>
|
||||
<Centered style={{ marginTop: 100 }}>
|
||||
<BoldLight>No exchange configured</BoldLight>
|
||||
<BoldLight>
|
||||
<Translate>No exchange configured</Translate>
|
||||
</BoldLight>
|
||||
<ButtonSuccess onClick={onAddExchange}>
|
||||
<i18n.Translate>Add exchange</i18n.Translate>
|
||||
<Translate>Add exchange</Translate>
|
||||
</ButtonSuccess>
|
||||
</Centered>
|
||||
</section>
|
||||
@ -118,20 +124,26 @@ export function CreateManualWithdraw({
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<ErrorMessage
|
||||
title={error && "Can't create the reserve"}
|
||||
description={error}
|
||||
/>
|
||||
<h2>Manual Withdrawal</h2>
|
||||
{error && (
|
||||
<ErrorMessage
|
||||
title={<Translate>Can't create the reserve</Translate>}
|
||||
description={error}
|
||||
/>
|
||||
)}
|
||||
<h2>
|
||||
<Translate>Manual Withdrawal</Translate>
|
||||
</h2>
|
||||
<LightText>
|
||||
Choose a exchange from where the coins will be withdrawn. The exchange
|
||||
will send the coins to this wallet after receiving a wire transfer
|
||||
with the correct subject.
|
||||
<Translate>
|
||||
Choose a exchange from where the coins will be withdrawn. The
|
||||
exchange will send the coins to this wallet after receiving a wire
|
||||
transfer with the correct subject.
|
||||
</Translate>
|
||||
</LightText>
|
||||
<p>
|
||||
<Input>
|
||||
<SelectList
|
||||
label="Currency"
|
||||
label={<Translate>Currency</Translate>}
|
||||
list={currencyMap}
|
||||
name="currency"
|
||||
value={currency}
|
||||
@ -140,7 +152,7 @@ export function CreateManualWithdraw({
|
||||
</Input>
|
||||
<Input>
|
||||
<SelectList
|
||||
label="Exchange"
|
||||
label={<Translate>Exchange</Translate>}
|
||||
list={exchangeMap}
|
||||
name="currency"
|
||||
value={exchange}
|
||||
@ -149,12 +161,14 @@ export function CreateManualWithdraw({
|
||||
</Input>
|
||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<LinkPrimary onClick={onAddExchange} style={{ marginLeft: "auto" }}>
|
||||
<i18n.Translate>Add exchange</i18n.Translate>
|
||||
<Translate>Add Exchange</Translate>
|
||||
</LinkPrimary>
|
||||
</div>
|
||||
{currency && (
|
||||
<InputWithLabel invalid={!!amount && !parsedAmount}>
|
||||
<label>Amount</label>
|
||||
<label>
|
||||
<Translate>Amount</Translate>
|
||||
</label>
|
||||
<div>
|
||||
<span>{currency}</span>
|
||||
<input
|
||||
@ -173,7 +187,7 @@ export function CreateManualWithdraw({
|
||||
disabled={!parsedAmount || !exchange}
|
||||
onClick={() => onCreate(exchange, parsedAmount!)}
|
||||
>
|
||||
Start withdrawal
|
||||
<Translate>Start withdrawal</Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</Fragment>
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
Amounts,
|
||||
AmountString,
|
||||
PaytoUri,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
@ -132,13 +133,21 @@ export function View({
|
||||
}, [amount]);
|
||||
|
||||
if (!balance) {
|
||||
return <div>no balance</div>;
|
||||
return (
|
||||
<div>
|
||||
<Translate>no balance</Translate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (!knownBankAccounts || !knownBankAccounts.length) {
|
||||
return (
|
||||
<WarningBox>
|
||||
<p>There is no known bank account to send money to</p>
|
||||
<ButtonBoxWarning>Withdraw</ButtonBoxWarning>
|
||||
<p>
|
||||
<Translate>There is no known bank account to send money to</Translate>
|
||||
</p>
|
||||
<ButtonBoxWarning>
|
||||
<Translate>Withdraw</Translate>
|
||||
</ButtonBoxWarning>
|
||||
</WarningBox>
|
||||
);
|
||||
}
|
||||
@ -162,11 +171,13 @@ export function View({
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<h2>Send {currency} to your account</h2>
|
||||
<h2>
|
||||
<Translate>Send {currency} to your account</Translate>
|
||||
</h2>
|
||||
<section>
|
||||
<Input>
|
||||
<SelectList
|
||||
label="Bank account IBAN number"
|
||||
label={<Translate>Bank account IBAN number</Translate>}
|
||||
list={accountMap}
|
||||
name="account"
|
||||
value={String(accountIdx)}
|
||||
@ -174,7 +185,9 @@ export function View({
|
||||
/>
|
||||
</Input>
|
||||
<InputWithLabel invalid={!!error}>
|
||||
<label>Amount</label>
|
||||
<label>
|
||||
<Translate>Amount</Translate>
|
||||
</label>
|
||||
<div>
|
||||
<span>{currency}</span>
|
||||
<input
|
||||
@ -196,7 +209,9 @@ export function View({
|
||||
{
|
||||
<Fragment>
|
||||
<InputWithLabel>
|
||||
<label>Deposit fee</label>
|
||||
<label>
|
||||
<Translate>Deposit fee</Translate>
|
||||
</label>
|
||||
<div>
|
||||
<span>{currency}</span>
|
||||
<input
|
||||
@ -208,7 +223,9 @@ export function View({
|
||||
</InputWithLabel>
|
||||
|
||||
<InputWithLabel>
|
||||
<label>Total deposit</label>
|
||||
<label>
|
||||
<Translate>Total deposit</Translate>
|
||||
</label>
|
||||
<div>
|
||||
<span>{currency}</span>
|
||||
<input
|
||||
@ -224,10 +241,14 @@ export function View({
|
||||
<footer>
|
||||
<div />
|
||||
{unableToDeposit ? (
|
||||
<ButtonPrimary disabled>Deposit</ButtonPrimary>
|
||||
<ButtonPrimary disabled>
|
||||
<Translate>Deposit</Translate>
|
||||
</ButtonPrimary>
|
||||
) : (
|
||||
<ButtonPrimary onClick={() => onSend(accountURI, amountStr)}>
|
||||
Deposit {Amounts.stringifyValue(totalToDeposit)} {currency}
|
||||
<Translate>
|
||||
Deposit {Amounts.stringifyValue(totalToDeposit)} {currency}
|
||||
</Translate>
|
||||
</ButtonPrimary>
|
||||
)}
|
||||
</footer>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { i18n } from "@gnu-taler/taler-util";
|
||||
import { i18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
import { Button, ButtonSuccess, ButtonWarning } from "../components/styled";
|
||||
@ -84,9 +84,11 @@ export function View({
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<h1>Review terms of service</h1>
|
||||
<h1>
|
||||
<Translate>Review terms of service</Translate>
|
||||
</h1>
|
||||
<div>
|
||||
Exchange URL:
|
||||
<Translate>Exchange URL</Translate>:
|
||||
<a href={url} target="_blank" rel="noreferrer">
|
||||
{url}
|
||||
</a>
|
||||
@ -107,28 +109,28 @@ export function View({
|
||||
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate>Cancel</i18n.Translate>
|
||||
<Translate>Cancel</Translate>
|
||||
</Button>
|
||||
{!terms && (
|
||||
<Button disabled>
|
||||
<i18n.Translate>Loading terms..</i18n.Translate>
|
||||
<Translate>Loading terms..</Translate>
|
||||
</Button>
|
||||
)}
|
||||
{terms && (
|
||||
<Fragment>
|
||||
{needsReview && !reviewed && (
|
||||
<ButtonSuccess disabled upperCased onClick={onConfirm}>
|
||||
{i18n.str`Add exchange`}
|
||||
<Translate>Add exchange</Translate>
|
||||
</ButtonSuccess>
|
||||
)}
|
||||
{(terms.status === "accepted" || (needsReview && reviewed)) && (
|
||||
<ButtonSuccess upperCased onClick={onConfirm}>
|
||||
{i18n.str`Add exchange`}
|
||||
<Translate>Add exchange</Translate>
|
||||
</ButtonSuccess>
|
||||
)}
|
||||
{terms.status === "notfound" && (
|
||||
<ButtonWarning upperCased onClick={onConfirm}>
|
||||
{i18n.str`Add exchange anyway`}
|
||||
<Translate>Add exchange anyway</Translate>
|
||||
</ButtonWarning>
|
||||
)}
|
||||
</Fragment>
|
||||
|
@ -2,6 +2,7 @@ import {
|
||||
canonicalizeBaseUrl,
|
||||
i18n,
|
||||
TalerConfigResponse,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Fragment, h } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
@ -91,32 +92,46 @@ export function ExchangeSetUrlPage({
|
||||
<Fragment>
|
||||
<section>
|
||||
{!expectedCurrency ? (
|
||||
<h1>Add new exchange</h1>
|
||||
<h1>
|
||||
<Translate>Add new exchange</Translate>
|
||||
</h1>
|
||||
) : (
|
||||
<h2>Add exchange for {expectedCurrency}</h2>
|
||||
<h2>
|
||||
<Translate>Add exchange for {expectedCurrency}</Translate>
|
||||
</h2>
|
||||
)}
|
||||
{!result && (
|
||||
<LightText>Enter the URL of an exchange you trust.</LightText>
|
||||
<LightText>
|
||||
<Translate>Enter the URL of an exchange you trust.</Translate>
|
||||
</LightText>
|
||||
)}
|
||||
{result && (
|
||||
<LightText>
|
||||
An exchange has been found! Review the information and click next
|
||||
<Translate>
|
||||
An exchange has been found! Review the information and click next
|
||||
</Translate>
|
||||
</LightText>
|
||||
)}
|
||||
{result && expectedCurrency && expectedCurrency !== result.currency && (
|
||||
<WarningBox>
|
||||
This exchange doesn't match the expected currency{" "}
|
||||
<b>{expectedCurrency}</b>
|
||||
<Translate>
|
||||
This exchange doesn't match the expected currency
|
||||
<b>{expectedCurrency}</b>
|
||||
</Translate>
|
||||
</WarningBox>
|
||||
)}
|
||||
<ErrorMessage
|
||||
title={error && "Unable to add this exchange"}
|
||||
description={error}
|
||||
/>
|
||||
<ErrorMessage
|
||||
title={confirmationError && "Unable to add this exchange"}
|
||||
description={confirmationError}
|
||||
/>
|
||||
{error && (
|
||||
<ErrorMessage
|
||||
title={<Translate>Unable to verify this exchange</Translate>}
|
||||
description={error}
|
||||
/>
|
||||
)}
|
||||
{confirmationError && (
|
||||
<ErrorMessage
|
||||
title={<Translate>Unable to add this exchange</Translate>}
|
||||
description={confirmationError}
|
||||
/>
|
||||
)}
|
||||
<p>
|
||||
<Input invalid={!!error}>
|
||||
<label>URL</label>
|
||||
@ -127,15 +142,23 @@ export function ExchangeSetUrlPage({
|
||||
onInput={(e) => updateEndpoint(e.currentTarget.value)}
|
||||
/>
|
||||
</Input>
|
||||
{loading && <div>loading... </div>}
|
||||
{loading && (
|
||||
<div>
|
||||
<Translate>loading</Translate>...
|
||||
</div>
|
||||
)}
|
||||
{result && !loading && (
|
||||
<Fragment>
|
||||
<Input>
|
||||
<label>Version</label>
|
||||
<label>
|
||||
<Translate>Version</Translate>
|
||||
</label>
|
||||
<input type="text" disabled value={result.version} />
|
||||
</Input>
|
||||
<Input>
|
||||
<label>Currency</label>
|
||||
<label>
|
||||
<Translate>Currency</Translate>
|
||||
</label>
|
||||
<input type="text" disabled value={result.currency} />
|
||||
</Input>
|
||||
</Fragment>
|
||||
@ -144,7 +167,7 @@ export function ExchangeSetUrlPage({
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate>Cancel</i18n.Translate>
|
||||
<Translate>Cancel</Translate>
|
||||
</Button>
|
||||
<ButtonPrimary
|
||||
disabled={
|
||||
@ -160,7 +183,7 @@ export function ExchangeSetUrlPage({
|
||||
);
|
||||
}}
|
||||
>
|
||||
<i18n.Translate>Next</i18n.Translate>
|
||||
<Translate>Next</Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</Fragment>
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
Balance,
|
||||
NotificationType,
|
||||
Transaction,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
@ -66,7 +67,7 @@ export function HistoryPage({
|
||||
if (transactionQuery.hasError) {
|
||||
return (
|
||||
<LoadingError
|
||||
title="Could not load the list of transactions"
|
||||
title={<Translate>Could not load the list of transactions</Translate>}
|
||||
error={transactionQuery}
|
||||
/>
|
||||
);
|
||||
@ -193,21 +194,23 @@ export function HistoryView({
|
||||
style={{ marginLeft: 0, marginTop: 8 }}
|
||||
onClick={() => goToWalletManualWithdraw(selectedCurrency)}
|
||||
>
|
||||
Withdraw
|
||||
<Translate>Withdraw</Translate>
|
||||
</ButtonPrimary>
|
||||
{currencyAmount && Amounts.isNonZero(currencyAmount) && (
|
||||
<ButtonBoxPrimary
|
||||
style={{ marginLeft: 0, marginTop: 8 }}
|
||||
onClick={() => goToWalletDeposit(selectedCurrency)}
|
||||
>
|
||||
Deposit
|
||||
<Translate>Deposit</Translate>
|
||||
</ButtonBoxPrimary>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{datesWithTransaction.length === 0 ? (
|
||||
<section>There is no history for this currency</section>
|
||||
<section>
|
||||
<Translate>There is no history for this currency</Translate>
|
||||
</section>
|
||||
) : (
|
||||
<section>
|
||||
{datesWithTransaction.map((d, i) => {
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
AmountJson,
|
||||
Amounts,
|
||||
NotificationType,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { h, VNode } from "preact";
|
||||
import { useState } from "preact/hooks";
|
||||
@ -95,7 +96,9 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
||||
if (state.hasError) {
|
||||
return (
|
||||
<LoadingError
|
||||
title="Could not load the list of known exchanges"
|
||||
title={
|
||||
<Translate>Could not load the list of known exchanges</Translate>
|
||||
}
|
||||
error={state}
|
||||
/>
|
||||
);
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
BackupBackupProviderTerms,
|
||||
canonicalizeBaseUrl,
|
||||
i18n,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
@ -113,15 +114,23 @@ export function SetUrlView({
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<h1> Add backup provider</h1>
|
||||
<ErrorMessage
|
||||
title={error && "Could not get provider information"}
|
||||
description={error}
|
||||
/>
|
||||
<LightText> Backup providers may charge for their service</LightText>
|
||||
<h1>
|
||||
<Translate>Add backup provider</Translate>
|
||||
</h1>
|
||||
{error && (
|
||||
<ErrorMessage
|
||||
title={<Translate>Could not get provider information</Translate>}
|
||||
description={error}
|
||||
/>
|
||||
)}
|
||||
<LightText>
|
||||
<Translate>Backup providers may charge for their service</Translate>
|
||||
</LightText>
|
||||
<p>
|
||||
<Input invalid={urlError}>
|
||||
<label>URL</label>
|
||||
<label>
|
||||
<Translate>URL</Translate>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="https://"
|
||||
@ -130,7 +139,9 @@ export function SetUrlView({
|
||||
/>
|
||||
</Input>
|
||||
<Input>
|
||||
<label>Name</label>
|
||||
<label>
|
||||
<Translate>Name</Translate>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
disabled={name === undefined}
|
||||
@ -142,7 +153,7 @@ export function SetUrlView({
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate> < Back</i18n.Translate>
|
||||
< <Translate>Back</Translate>
|
||||
</Button>
|
||||
<ButtonPrimary
|
||||
disabled={!value && !urlError}
|
||||
@ -153,7 +164,7 @@ export function SetUrlView({
|
||||
);
|
||||
}}
|
||||
>
|
||||
<i18n.Translate>Next</i18n.Translate>
|
||||
<Translate>Next</Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</Fragment>
|
||||
@ -177,29 +188,41 @@ export function ConfirmProviderView({
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<h1>Review terms of service</h1>
|
||||
<h1>
|
||||
<Translate>Review terms of service</Translate>
|
||||
</h1>
|
||||
<div>
|
||||
Provider URL:{" "}
|
||||
<Translate>Provider URL</Translate>:{" "}
|
||||
<a href={url} target="_blank">
|
||||
{url}
|
||||
</a>
|
||||
</div>
|
||||
<SmallLightText>
|
||||
Please review and accept this provider's terms of service
|
||||
<Translate>
|
||||
Please review and accept this provider's terms of service
|
||||
</Translate>
|
||||
</SmallLightText>
|
||||
<h2>1. Pricing</h2>
|
||||
<h2>
|
||||
1. <Translate>Pricing</Translate>
|
||||
</h2>
|
||||
<p>
|
||||
{Amounts.isZero(provider.annual_fee)
|
||||
? "free of charge"
|
||||
: `${provider.annual_fee} per year of service`}
|
||||
{Amounts.isZero(provider.annual_fee) ? (
|
||||
<Translate>free of charge</Translate>
|
||||
) : (
|
||||
<Translate>{provider.annual_fee} per year of service</Translate>
|
||||
)}
|
||||
</p>
|
||||
<h2>2. Storage</h2>
|
||||
<h2>
|
||||
2. <Translate>Storage</Translate>
|
||||
</h2>
|
||||
<p>
|
||||
{provider.storage_limit_in_megabytes} megabytes of storage per year of
|
||||
service
|
||||
<Translate>
|
||||
{provider.storage_limit_in_megabytes} megabytes of storage per year
|
||||
of service
|
||||
</Translate>
|
||||
</p>
|
||||
<Checkbox
|
||||
label="Accept terms of service"
|
||||
label={<Translate>Accept terms of service</Translate>}
|
||||
name="terms"
|
||||
onToggle={() => setAccepted((old) => !old)}
|
||||
enabled={accepted}
|
||||
@ -207,10 +230,10 @@ export function ConfirmProviderView({
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onCancel}>
|
||||
<i18n.Translate> < Back</i18n.Translate>
|
||||
< <Translate>Back</Translate>
|
||||
</Button>
|
||||
<ButtonPrimary disabled={!accepted} onClick={onConfirm}>
|
||||
<i18n.Translate>Add provider</i18n.Translate>
|
||||
<Translate>Add provider</Translate>
|
||||
</ButtonPrimary>
|
||||
</footer>
|
||||
</Fragment>
|
||||
|
@ -14,7 +14,7 @@
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { i18n } from "@gnu-taler/taler-util";
|
||||
import { Translate } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
ProviderInfo,
|
||||
ProviderPaymentStatus,
|
||||
@ -22,6 +22,8 @@ import {
|
||||
} from "@gnu-taler/taler-wallet-core";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { ErrorMessage } from "../components/ErrorMessage";
|
||||
import { Loading } from "../components/Loading";
|
||||
import { LoadingError } from "../components/LoadingError";
|
||||
import {
|
||||
Button,
|
||||
ButtonDestructive,
|
||||
@ -52,35 +54,24 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
|
||||
const state = useAsyncAsHook(getProviderInfo);
|
||||
|
||||
if (!state) {
|
||||
return (
|
||||
<div>
|
||||
<i18n.Translate>Loading...</i18n.Translate>
|
||||
</div>
|
||||
);
|
||||
return <Loading />;
|
||||
}
|
||||
if (state.hasError) {
|
||||
return (
|
||||
<div>
|
||||
<i18n.Translate>
|
||||
There was an error loading the provider detail for "{providerURL}"
|
||||
</i18n.Translate>
|
||||
</div>
|
||||
<LoadingError
|
||||
title={
|
||||
<Translate>
|
||||
There was an error loading the provider detail for "{providerURL}"
|
||||
</Translate>
|
||||
}
|
||||
error={state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (state.response === null) {
|
||||
onBack();
|
||||
return (
|
||||
<div>
|
||||
<i18n.Translate>
|
||||
There is not known provider with url "{providerURL}". Redirecting
|
||||
back...
|
||||
</i18n.Translate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ProviderView
|
||||
url={providerURL}
|
||||
info={state.response}
|
||||
onSync={async () => wxApi.syncOneProvider(providerURL)}
|
||||
onDelete={async () => wxApi.removeProvider(providerURL).then(onBack)}
|
||||
@ -93,7 +84,8 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
|
||||
}
|
||||
|
||||
export interface ViewProps {
|
||||
info: ProviderInfo;
|
||||
url: string;
|
||||
info: ProviderInfo | null;
|
||||
onDelete: () => void;
|
||||
onSync: () => void;
|
||||
onBack: () => void;
|
||||
@ -102,12 +94,30 @@ export interface ViewProps {
|
||||
|
||||
export function ProviderView({
|
||||
info,
|
||||
url,
|
||||
onDelete,
|
||||
onSync,
|
||||
onBack,
|
||||
onExtend,
|
||||
}: ViewProps): VNode {
|
||||
const lb = info?.lastSuccessfulBackupTimestamp;
|
||||
if (info === null) {
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<p>
|
||||
<Translate>There is not known provider with url "{url}".</Translate>
|
||||
</p>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onBack}>
|
||||
< <Translate>Back</Translate>
|
||||
</Button>
|
||||
<div />
|
||||
</footer>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
const lb = info.lastSuccessfulBackupTimestamp;
|
||||
const isPaid =
|
||||
info.paymentStatus.type === ProviderPaymentType.Paid ||
|
||||
info.paymentStatus.type === ProviderPaymentType.TermsChanged;
|
||||
@ -125,48 +135,55 @@ export function ProviderView({
|
||||
</header>
|
||||
<section>
|
||||
<p>
|
||||
<b>Last backup:</b> <Time timestamp={lb} format="dd MMMM yyyy" />
|
||||
<b>
|
||||
<Translate>Last backup</Translate>:
|
||||
</b>{" "}
|
||||
<Time timestamp={lb} format="dd MMMM yyyy" />
|
||||
</p>
|
||||
<ButtonPrimary onClick={onSync}>
|
||||
<i18n.Translate>Back up</i18n.Translate>
|
||||
<Translate>Back up</Translate>
|
||||
</ButtonPrimary>
|
||||
{info.terms && (
|
||||
<Fragment>
|
||||
<p>
|
||||
<b>Provider fee:</b> {info.terms && info.terms.annualFee} per year
|
||||
<b>
|
||||
<Translate>Provider fee</Translate>:
|
||||
</b>{" "}
|
||||
{info.terms && info.terms.annualFee}{" "}
|
||||
<Translate>per year</Translate>
|
||||
</p>
|
||||
</Fragment>
|
||||
)}
|
||||
<p>{descriptionByStatus(info.paymentStatus)}</p>
|
||||
<ButtonPrimary disabled onClick={onExtend}>
|
||||
<i18n.Translate>Extend</i18n.Translate>
|
||||
<Translate>Extend</Translate>
|
||||
</ButtonPrimary>
|
||||
|
||||
{info.paymentStatus.type === ProviderPaymentType.TermsChanged && (
|
||||
<div>
|
||||
<p>
|
||||
<i18n.Translate>
|
||||
<Translate>
|
||||
terms has changed, extending the service will imply accepting
|
||||
the new terms of service
|
||||
</i18n.Translate>
|
||||
</Translate>
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<i18n.Translate>old</i18n.Translate>
|
||||
<Translate>old</Translate>
|
||||
</td>
|
||||
<td> -></td>
|
||||
<td>
|
||||
<i18n.Translate>new</i18n.Translate>
|
||||
<Translate>new</Translate>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<i18n.Translate>fee</i18n.Translate>
|
||||
<Translate>fee</Translate>
|
||||
</td>
|
||||
<td>{info.paymentStatus.oldTerms.annualFee}</td>
|
||||
<td>-></td>
|
||||
@ -174,7 +191,7 @@ export function ProviderView({
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i18n.Translate>storage</i18n.Translate>
|
||||
<Translate>storage</Translate>
|
||||
</td>
|
||||
<td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
|
||||
<td>-></td>
|
||||
@ -187,11 +204,11 @@ export function ProviderView({
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onBack}>
|
||||
<i18n.Translate> < back</i18n.Translate>
|
||||
< <Translate>back</Translate>
|
||||
</Button>
|
||||
<div>
|
||||
<ButtonDestructive onClick={onDelete}>
|
||||
<i18n.Translate>remove provider</i18n.Translate>
|
||||
<Translate>Remove provider</Translate>
|
||||
</ButtonDestructive>
|
||||
</div>
|
||||
</footer>
|
||||
@ -201,7 +218,12 @@ export function ProviderView({
|
||||
|
||||
function Error({ info }: { info: ProviderInfo }): VNode {
|
||||
if (info.lastError) {
|
||||
return <ErrorMessage title={info.lastError.hint} />;
|
||||
return (
|
||||
<ErrorMessage
|
||||
title={<Translate>This provider has reported an error</Translate>}
|
||||
description={info.lastError.hint}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (info.backupProblem) {
|
||||
switch (info.backupProblem.type) {
|
||||
@ -210,24 +232,26 @@ function Error({ info }: { info: ProviderInfo }): VNode {
|
||||
<ErrorMessage
|
||||
title={
|
||||
<Fragment>
|
||||
<i18n.Translate>
|
||||
<Translate>
|
||||
There is conflict with another backup from{" "}
|
||||
<b>{info.backupProblem.otherDeviceId}</b>
|
||||
</i18n.Translate>
|
||||
</Translate>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
case "backup-unreadable":
|
||||
return <ErrorMessage title="Backup is not readable" />;
|
||||
return (
|
||||
<ErrorMessage title={<Translate>Backup is not readable</Translate>} />
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<ErrorMessage
|
||||
title={
|
||||
<Fragment>
|
||||
<i18n.Translate>
|
||||
<Translate>
|
||||
Unknown backup problem: {JSON.stringify(info.backupProblem)}
|
||||
</i18n.Translate>
|
||||
</Translate>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
@ -239,16 +263,20 @@ function Error({ info }: { info: ProviderInfo }): VNode {
|
||||
|
||||
function descriptionByStatus(status: ProviderPaymentStatus): VNode {
|
||||
switch (status.type) {
|
||||
// return i18n.str`no enough balance to make the payment`
|
||||
// return i18n.str`not paid yet`
|
||||
case ProviderPaymentType.Paid:
|
||||
case ProviderPaymentType.TermsChanged:
|
||||
if (status.paidUntil.t_ms === "never") {
|
||||
return <span>{i18n.str`service paid`}</span>;
|
||||
return (
|
||||
<span>
|
||||
<Translate>service paid</Translate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Fragment>
|
||||
<b>Backup valid until:</b>{" "}
|
||||
<b>
|
||||
<Translate>Backup valid until</Translate>:
|
||||
</b>{" "}
|
||||
<Time timestamp={status.paidUntil} format="dd MMM yyyy" />
|
||||
</Fragment>
|
||||
);
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { AmountJson, Amounts, parsePaytoUri } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
AmountJson,
|
||||
Amounts,
|
||||
parsePaytoUri,
|
||||
Translate,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType";
|
||||
import { QR } from "../components/QR";
|
||||
@ -22,15 +27,23 @@ export function ReserveCreated({
|
||||
const paytoURI = parsePaytoUri(payto);
|
||||
// const url = new URL(paytoURI?.targetPath);
|
||||
if (!paytoURI) {
|
||||
return <div>could not parse payto uri from exchange {payto}</div>;
|
||||
return (
|
||||
<div>
|
||||
<Translate>could not parse payto uri from exchange {payto}</Translate>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
<h1>Exchange is ready for withdrawal!</h1>
|
||||
<h1>
|
||||
<Translate>Exchange is ready for withdrawal</Translate>
|
||||
</h1>
|
||||
<p>
|
||||
To complete the process you need to wire{" "}
|
||||
<b>{amountToString(amount)}</b> to the exchange bank account
|
||||
<Translate>
|
||||
To complete the process you need to wire
|
||||
<b>{amountToString(amount)}</b> to the exchange bank account
|
||||
</Translate>
|
||||
</p>
|
||||
<BankDetailsByPaytoType
|
||||
amount={amountToString(amount)}
|
||||
@ -40,23 +53,27 @@ export function ReserveCreated({
|
||||
/>
|
||||
<p>
|
||||
<WarningBox>
|
||||
Make sure to use the correct subject, otherwise the money will not
|
||||
arrive in this wallet.
|
||||
<Translate>
|
||||
Make sure to use the correct subject, otherwise the money will not
|
||||
arrive in this wallet.
|
||||
</Translate>
|
||||
</WarningBox>
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<p>
|
||||
Alternative, you can also scan this QR code or open{" "}
|
||||
<a href={payto}>this link</a> if you have a banking app installed that
|
||||
supports RFC 8905
|
||||
<Translate>
|
||||
Alternative, you can also scan this QR code or open
|
||||
<a href={payto}>this link</a> if you have a banking app installed
|
||||
that supports RFC 8905
|
||||
</Translate>
|
||||
</p>
|
||||
<QR text={payto} />
|
||||
</section>
|
||||
<footer>
|
||||
<div />
|
||||
<ButtonDestructive onClick={onCancel}>
|
||||
Cancel withdrawal
|
||||
<Translate>Cancel withdrawal</Translate>
|
||||
</ButtonDestructive>
|
||||
</footer>
|
||||
</Fragment>
|
||||
|
@ -14,7 +14,7 @@
|
||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
||||
import { ExchangeListItem, i18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { Checkbox } from "../components/Checkbox";
|
||||
import {
|
||||
@ -81,29 +81,46 @@ export function SettingsView({
|
||||
<Fragment>
|
||||
<section>
|
||||
<h2>
|
||||
<i18n.Translate>Permissions</i18n.Translate>
|
||||
<Translate>Permissions</Translate>
|
||||
</h2>
|
||||
<Checkbox
|
||||
label="Automatically open wallet based on page content"
|
||||
label={
|
||||
<Translate>
|
||||
Automatically open wallet based on page content
|
||||
</Translate>
|
||||
}
|
||||
name="perm"
|
||||
description="(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)"
|
||||
description={
|
||||
<Translate>
|
||||
Enabling this option below will make using the wallet faster, but
|
||||
requires more permissions from your browser.
|
||||
</Translate>
|
||||
}
|
||||
enabled={permissionsEnabled}
|
||||
onToggle={togglePermissions}
|
||||
/>
|
||||
|
||||
<h2>
|
||||
<i18n.Translate>Known exchanges</i18n.Translate>
|
||||
<Translate>Known exchanges</Translate>
|
||||
</h2>
|
||||
{!knownExchanges || !knownExchanges.length ? (
|
||||
<div>No exchange yet!</div>
|
||||
<div>
|
||||
<Translate>No exchange yet</Translate>
|
||||
</div>
|
||||
) : (
|
||||
<Fragment>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>currency</th>
|
||||
<th>url</th>
|
||||
<th>term of service</th>
|
||||
<th>
|
||||
<Translate>Currency</Translate>
|
||||
</th>
|
||||
<th>
|
||||
<Translate>URL</Translate>
|
||||
</th>
|
||||
<th>
|
||||
<Translate>Term of Service</Translate>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -116,12 +133,24 @@ export function SettingsView({
|
||||
);
|
||||
switch (status) {
|
||||
case "accepted":
|
||||
return <SuccessText>ok</SuccessText>;
|
||||
return (
|
||||
<SuccessText>
|
||||
<Translate>ok</Translate>
|
||||
</SuccessText>
|
||||
);
|
||||
case "changed":
|
||||
return <WarningText>changed!</WarningText>;
|
||||
return (
|
||||
<WarningText>
|
||||
<Translate>changed</Translate>
|
||||
</WarningText>
|
||||
);
|
||||
case "new":
|
||||
case "notfound":
|
||||
return <DestructiveText>not accepted</DestructiveText>;
|
||||
return (
|
||||
<DestructiveText>
|
||||
<Translate>not accepted</Translate>
|
||||
</DestructiveText>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
@ -143,15 +172,19 @@ export function SettingsView({
|
||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||
<div />
|
||||
<LinkPrimary href={Pages.settings_exchange_add}>
|
||||
Add an exchange
|
||||
<Translate>Add an exchange</Translate>
|
||||
</LinkPrimary>
|
||||
</div>
|
||||
|
||||
<h2>Config</h2>
|
||||
<Checkbox
|
||||
label="Developer mode"
|
||||
label={<Translate>Developer mode</Translate>}
|
||||
name="devMode"
|
||||
description="(More options and information useful for debugging)"
|
||||
description={
|
||||
<Translate>
|
||||
(More options and information useful for debugging)
|
||||
</Translate>
|
||||
}
|
||||
enabled={developerMode}
|
||||
onToggle={toggleDeveloperMode}
|
||||
/>
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
parsePaytoUri,
|
||||
Transaction,
|
||||
TransactionType,
|
||||
Translate,
|
||||
WithdrawalType,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { differenceInSeconds } from "date-fns";
|
||||
@ -47,7 +48,6 @@ import {
|
||||
} from "../components/styled";
|
||||
import { Time } from "../components/Time";
|
||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||
import { Pages } from "../NavigationBar";
|
||||
import * as wxApi from "../wxApi";
|
||||
|
||||
interface Props {
|
||||
@ -76,7 +76,9 @@ export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
|
||||
if (state.hasError) {
|
||||
return (
|
||||
<LoadingError
|
||||
title="Could not load the transaction information"
|
||||
title={
|
||||
<Translate>Could not load the transaction information</Translate>
|
||||
}
|
||||
error={state}
|
||||
/>
|
||||
);
|
||||
@ -139,11 +141,17 @@ export function TransactionView({
|
||||
<Fragment>
|
||||
<section style={{ padding: 8, textAlign: "center" }}>
|
||||
<ErrorTalerOperation
|
||||
title="There was an error trying to complete the transaction"
|
||||
title={
|
||||
<Translate>
|
||||
There was an error trying to complete the transaction
|
||||
</Translate>
|
||||
}
|
||||
error={transaction?.error}
|
||||
/>
|
||||
{transaction.pending && (
|
||||
<WarningBox>This transaction is not completed</WarningBox>
|
||||
<WarningBox>
|
||||
<Translate>This transaction is not completed</Translate>
|
||||
</WarningBox>
|
||||
)}
|
||||
</section>
|
||||
<section>
|
||||
@ -151,16 +159,16 @@ export function TransactionView({
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={onBack}>
|
||||
<i18n.Translate> < Back </i18n.Translate>
|
||||
< <Translate> Back </Translate>
|
||||
</Button>
|
||||
<div>
|
||||
{showRetry ? (
|
||||
<ButtonPrimary onClick={onRetry}>
|
||||
<i18n.Translate>retry</i18n.Translate>
|
||||
<Translate>Retry</Translate>
|
||||
</ButtonPrimary>
|
||||
) : null}
|
||||
<ButtonDestructive onClick={doCheckBeforeForget}>
|
||||
<i18n.Translate> Forget </i18n.Translate>
|
||||
<Translate>Forget</Translate>
|
||||
</ButtonDestructive>
|
||||
</div>
|
||||
</footer>
|
||||
@ -184,24 +192,30 @@ export function TransactionView({
|
||||
{confirmBeforeForget ? (
|
||||
<Overlay>
|
||||
<CenteredDialog>
|
||||
<header>Caution!</header>
|
||||
<header>
|
||||
<Translate>Caution!</Translate>
|
||||
</header>
|
||||
<section>
|
||||
If you have already wired money to the exchange you will loose
|
||||
the chance to get the coins form it.
|
||||
<Translate>
|
||||
If you have already wired money to the exchange you will loose
|
||||
the chance to get the coins form it.
|
||||
</Translate>
|
||||
</section>
|
||||
<footer>
|
||||
<Button onClick={() => setConfirmBeforeForget(false)}>
|
||||
<i18n.Translate> Cancel </i18n.Translate>
|
||||
<Translate>Cancel</Translate>
|
||||
</Button>
|
||||
|
||||
<ButtonDestructive onClick={onDelete}>
|
||||
<i18n.Translate> Confirm </i18n.Translate>
|
||||
<Translate>Confirm</Translate>
|
||||
</ButtonDestructive>
|
||||
</footer>
|
||||
</CenteredDialog>
|
||||
</Overlay>
|
||||
) : undefined}
|
||||
<h2>Withdrawal</h2>
|
||||
<h2>
|
||||
<Translate>Withdrawal</Translate>
|
||||
</h2>
|
||||
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
|
||||
{transaction.pending ? (
|
||||
transaction.withdrawalDetails.type ===
|
||||
@ -217,19 +231,21 @@ export function TransactionView({
|
||||
/>
|
||||
<p>
|
||||
<WarningBox>
|
||||
Make sure to use the correct subject, otherwise the money will
|
||||
not arrive in this wallet.
|
||||
<Translate>
|
||||
Make sure to use the correct subject, otherwise the money
|
||||
will not arrive in this wallet.
|
||||
</Translate>
|
||||
</WarningBox>
|
||||
</p>
|
||||
<Part
|
||||
big
|
||||
title="Total withdrawn"
|
||||
title={<Translate>Total withdrawn</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="positive"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Exchange fee"
|
||||
title={<Translate>Exchange fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
@ -239,34 +255,38 @@ export function TransactionView({
|
||||
{!transaction.withdrawalDetails.confirmed &&
|
||||
transaction.withdrawalDetails.bankConfirmationUrl ? (
|
||||
<InfoBox>
|
||||
The bank is waiting for confirmation. Go to the
|
||||
<a
|
||||
href={transaction.withdrawalDetails.bankConfirmationUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
bank site
|
||||
</a>
|
||||
<Translate>
|
||||
The bank is waiting for confirmation. Go to the
|
||||
<a
|
||||
href={transaction.withdrawalDetails.bankConfirmationUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Translate>bank site</Translate>
|
||||
</a>
|
||||
</Translate>
|
||||
</InfoBox>
|
||||
) : undefined}
|
||||
{transaction.withdrawalDetails.confirmed && (
|
||||
<InfoBox>Waiting for the coins to arrive</InfoBox>
|
||||
<InfoBox>
|
||||
<Translate>Waiting for the coins to arrive</Translate>
|
||||
</InfoBox>
|
||||
)}
|
||||
<Part
|
||||
big
|
||||
title="Total withdrawn"
|
||||
title={<Translate>Total withdrawn</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="positive"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Chosen amount"
|
||||
title={<Translate>Chosen amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Exchange fee"
|
||||
title={<Translate>Exchange fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
@ -276,26 +296,26 @@ export function TransactionView({
|
||||
<Fragment>
|
||||
<Part
|
||||
big
|
||||
title="Total withdrawn"
|
||||
title={<Translate>Total withdrawn</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="positive"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Chosen amount"
|
||||
title={<Translate>Chosen amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Exchange fee"
|
||||
title={<Translate>Exchange fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
<Part
|
||||
title="Exchange"
|
||||
title={<Translate>Exchange</Translate>}
|
||||
text={new URL(transaction.exchangeBaseUrl).hostname}
|
||||
kind="neutral"
|
||||
/>
|
||||
@ -315,30 +335,41 @@ export function TransactionView({
|
||||
|
||||
return (
|
||||
<TransactionTemplate>
|
||||
<h2>Payment </h2>
|
||||
<h2>
|
||||
<Translate>Payment</Translate>
|
||||
</h2>
|
||||
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
|
||||
<br />
|
||||
<Part
|
||||
big
|
||||
title="Total paid"
|
||||
title={<Translate>Total paid</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="negative"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Purchase amount"
|
||||
title={<Translate>Purchase amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part big title="Fee" text={amountToString(fee)} kind="negative" />
|
||||
<Part
|
||||
title="Merchant"
|
||||
big
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
<Part
|
||||
title={<Translate>Merchant</Translate>}
|
||||
text={transaction.info.merchant.name}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part title="Purchase" text={transaction.info.summary} kind="neutral" />
|
||||
<Part
|
||||
title="Receipt"
|
||||
title={<Translate>Purchase</Translate>}
|
||||
text={transaction.info.summary}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part
|
||||
title={<Translate>Receipt</Translate>}
|
||||
text={`#${transaction.info.orderId}`}
|
||||
kind="neutral"
|
||||
/>
|
||||
@ -375,22 +406,29 @@ export function TransactionView({
|
||||
).amount;
|
||||
return (
|
||||
<TransactionTemplate>
|
||||
<h2>Deposit </h2>
|
||||
<h2>
|
||||
<Translate>Deposit</Translate>
|
||||
</h2>
|
||||
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
|
||||
<br />
|
||||
<Part
|
||||
big
|
||||
title="Total send"
|
||||
title={<Translate>Total send</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Deposit amount"
|
||||
title={<Translate>Deposit amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="positive"
|
||||
/>
|
||||
<Part big title="Fee" text={amountToString(fee)} kind="negative" />
|
||||
<Part
|
||||
big
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
</TransactionTemplate>
|
||||
);
|
||||
}
|
||||
@ -402,22 +440,29 @@ export function TransactionView({
|
||||
).amount;
|
||||
return (
|
||||
<TransactionTemplate>
|
||||
<h2>Refresh</h2>
|
||||
<h2>
|
||||
<Translate>Refresh</Translate>
|
||||
</h2>
|
||||
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
|
||||
<br />
|
||||
<Part
|
||||
big
|
||||
title="Total refresh"
|
||||
title={<Translate>Total refresh</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="negative"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Refresh amount"
|
||||
title={<Translate>Refresh amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part big title="Fee" text={amountToString(fee)} kind="negative" />
|
||||
<Part
|
||||
big
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
</TransactionTemplate>
|
||||
);
|
||||
}
|
||||
@ -429,22 +474,29 @@ export function TransactionView({
|
||||
).amount;
|
||||
return (
|
||||
<TransactionTemplate>
|
||||
<h2>Tip</h2>
|
||||
<h2>
|
||||
<Translate>Tip</Translate>
|
||||
</h2>
|
||||
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
|
||||
<br />
|
||||
<Part
|
||||
big
|
||||
title="Total tip"
|
||||
title={<Translate>Total tip</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="positive"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Received amount"
|
||||
title={<Translate>Received amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part big title="Fee" text={amountToString(fee)} kind="negative" />
|
||||
<Part
|
||||
big
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
</TransactionTemplate>
|
||||
);
|
||||
}
|
||||
@ -456,30 +508,41 @@ export function TransactionView({
|
||||
).amount;
|
||||
return (
|
||||
<TransactionTemplate>
|
||||
<h2>Refund</h2>
|
||||
<h2>
|
||||
<Translate>Refund</Translate>
|
||||
</h2>
|
||||
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
|
||||
<br />
|
||||
<Part
|
||||
big
|
||||
title="Total refund"
|
||||
title={<Translate>Total refund</Translate>}
|
||||
text={amountToString(transaction.amountEffective)}
|
||||
kind="positive"
|
||||
/>
|
||||
<Part
|
||||
big
|
||||
title="Refund amount"
|
||||
title={<Translate>Refund amount</Translate>}
|
||||
text={amountToString(transaction.amountRaw)}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part big title="Fee" text={amountToString(fee)} kind="negative" />
|
||||
<Part
|
||||
title="Merchant"
|
||||
big
|
||||
title={<Translate>Fee</Translate>}
|
||||
text={amountToString(fee)}
|
||||
kind="negative"
|
||||
/>
|
||||
<Part
|
||||
title={<Translate>Merchant</Translate>}
|
||||
text={transaction.info.merchant.name}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part title="Purchase" text={transaction.info.summary} kind="neutral" />
|
||||
<Part
|
||||
title="Receipt"
|
||||
title={<Translate>Purchase</Translate>}
|
||||
text={transaction.info.summary}
|
||||
kind="neutral"
|
||||
/>
|
||||
<Part
|
||||
title={<Translate>Receipt</Translate>}
|
||||
text={`#${transaction.info.orderId}`}
|
||||
kind="neutral"
|
||||
/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
/**
|
||||
* Welcome page, shown on first installs.
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
import { WalletDiagnostics } from "@gnu-taler/taler-util";
|
||||
import { Translate, WalletDiagnostics } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { Checkbox } from "../components/Checkbox";
|
||||
import { Diagnostics } from "../components/Diagnostics";
|
||||
@ -54,24 +54,41 @@ export function View({
|
||||
}: ViewProps): VNode {
|
||||
return (
|
||||
<Fragment>
|
||||
<h1>Browser Extension Installed!</h1>
|
||||
<h1>
|
||||
<Translate>Browser Extension Installed!</Translate>
|
||||
</h1>
|
||||
<div>
|
||||
<p>Thank you for installing the wallet.</p>
|
||||
<p>
|
||||
<Translate>Thank you for installing the wallet.</Translate>
|
||||
</p>
|
||||
<Diagnostics diagnostics={diagnostics} timedOut={timedOut} />
|
||||
<h2>Permissions</h2>
|
||||
<h2>
|
||||
<Translate>Permissions</Translate>
|
||||
</h2>
|
||||
<Checkbox
|
||||
label="Automatically open wallet based on page content"
|
||||
label={
|
||||
<Translate>
|
||||
Automatically open wallet based on page content
|
||||
</Translate>
|
||||
}
|
||||
name="perm"
|
||||
description="(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)"
|
||||
description={
|
||||
<Translate>
|
||||
(Enabling this option below will make using the wallet faster, but
|
||||
requires more permissions from your browser.)
|
||||
</Translate>
|
||||
}
|
||||
enabled={permissionsEnabled}
|
||||
onToggle={togglePermissions}
|
||||
/>
|
||||
<h2>Next Steps</h2>
|
||||
<h2>
|
||||
<Translate>Next Steps</Translate>
|
||||
</h2>
|
||||
<a href="https://demo.taler.net/" style={{ display: "block" }}>
|
||||
Try the demo »
|
||||
<Translate>Try the demo</Translate> »
|
||||
</a>
|
||||
<a href="https://demo.taler.net/" style={{ display: "block" }}>
|
||||
Learn how to top up your wallet balance »
|
||||
<Translate>Learn how to top up your wallet balance</Translate> »
|
||||
</a>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
@ -17,10 +17,10 @@
|
||||
/**
|
||||
* Main entry point for extension pages.
|
||||
*
|
||||
* @author Florian Dold <dold@taler.net>
|
||||
* @author sebasjm <dold@taler.net>
|
||||
*/
|
||||
|
||||
import { i18n, setupI18n } from "@gnu-taler/taler-util";
|
||||
import { i18n, setupI18n, Translate } from "@gnu-taler/taler-util";
|
||||
import { createHashHistory } from "history";
|
||||
import { Fragment, h, render, VNode } from "preact";
|
||||
import Router, { route, Route } from "preact-router";
|
||||
@ -78,7 +78,7 @@ if (document.readyState === "loading") {
|
||||
|
||||
function Application(): VNode {
|
||||
const [globalNotification, setGlobalNotification] = useState<
|
||||
string | undefined
|
||||
VNode | undefined
|
||||
>(undefined);
|
||||
const hash_history = createHashHistory();
|
||||
function clearNotification(): void {
|
||||
@ -169,7 +169,9 @@ function Application(): VNode {
|
||||
onSuccess={(currency: string) => {
|
||||
route(Pages.balance_history.replace(":currency", currency));
|
||||
setGlobalNotification(
|
||||
"All done, your transaction is in progress",
|
||||
<Translate>
|
||||
All done, your transaction is in progress
|
||||
</Translate>,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
@ -41,6 +41,12 @@ import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits
|
||||
import { ExchangeWithdrawDetails } from "@gnu-taler/taler-wallet-core/src/operations/withdraw";
|
||||
import { MessageFromBackend } from "./wxBackend";
|
||||
|
||||
/**
|
||||
*
|
||||
* @autor Florian Dold
|
||||
* @autor sebasjm
|
||||
*/
|
||||
|
||||
export interface ExtendedPermissionsResponse {
|
||||
newValue: boolean;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user