aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wallet
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-01-04 11:24:58 -0300
committerSebastian <sebasjm@gmail.com>2023-01-04 11:38:00 -0300
commit24cac493dded00ef40e0e30a0d2263e4f35c3e29 (patch)
tree1bbd1fb4f9149af349358491c3720750d031d255 /packages/taler-wallet-webextension/src/wallet
parent7d02e4212346b7b7b88197259a7e74554e1b10a3 (diff)
downloadwallet-core-24cac493dded00ef40e0e30a0d2263e4f35c3e29.tar.xz
fix #7522
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
-rw-r--r--packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts1
-rw-r--r--packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts1
-rw-r--r--packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts1
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Application.tsx741
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx33
5 files changed, 468 insertions, 309 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts
index 94020069b..10fcd84ce 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts
@@ -32,7 +32,6 @@ import {
} from "./views.js";
export interface Props {
- currency: string;
onBack: () => Promise<void>;
onComplete: (pid: string) => Promise<void>;
onPaymentRequired: (uri: string) => Promise<void>;
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts
index 32c48be91..1b30ed0cd 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts
@@ -144,7 +144,6 @@ function useUrlState<T>(
}
export function useComponentState({
- currency,
onBack,
onComplete,
onPaymentRequired,
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts
index 9abb672fa..3241a3ab0 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts
@@ -26,7 +26,6 @@ import { Props } from "./index.js";
import { useComponentState } from "./state.js";
const props: Props = {
- currency: "KUDOS",
onBack: nullFunction,
onComplete: nullFunction,
onPaymentRequired: nullFunction,
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx
index d150ebfaf..8b77e152c 100644
--- a/packages/taler-wallet-webextension/src/wallet/Application.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx
@@ -20,352 +20,452 @@
* @author sebasjm
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { createHashHistory } from "history";
-import { Fragment, h, VNode } from "preact";
+import { ComponentChildren, Fragment, h, VNode } from "preact";
import Router, { route, Route } from "preact-router";
-import Match from "preact-router/match";
-import { useEffect, useState } from "preact/hooks";
+import { useEffect } from "preact/hooks";
import { LogoHeader } from "../components/LogoHeader.js";
import PendingTransactions from "../components/PendingTransactions.js";
-import { SuccessBox, WalletBox } from "../components/styled/index.js";
+import {
+ SubTitle,
+ WalletAction,
+ WalletBox,
+} from "../components/styled/index.js";
import { DevContextProvider } from "../context/devContext.js";
import { IoCProviderForRuntime } from "../context/iocContext.js";
import {
TranslationProvider,
useTranslationContext,
} from "../context/translation.js";
+import { DepositPage as DepositPageCTA } from "../cta/Deposit/index.js";
+import { InvoiceCreatePage } from "../cta/InvoiceCreate/index.js";
+import { InvoicePayPage } from "../cta/InvoicePay/index.js";
import { PaymentPage } from "../cta/Payment/index.js";
+import { RecoveryPage } from "../cta/Recovery/index.js";
import { RefundPage } from "../cta/Refund/index.js";
import { TipPage } from "../cta/Tip/index.js";
+import { TransferCreatePage } from "../cta/TransferCreate/index.js";
+import { TransferPickupPage } from "../cta/TransferPickup/index.js";
import {
WithdrawPageFromParams,
WithdrawPageFromURI,
} from "../cta/Withdraw/index.js";
-import { DepositPage as DepositPageCTA } from "../cta/Deposit/index.js";
-import { Pages, WalletNavBar } from "../NavigationBar.js";
-import { DeveloperPage } from "./DeveloperPage.js";
+import { WalletNavBarOptions, Pages, WalletNavBar } from "../NavigationBar.js";
+import { platform } from "../platform/api.js";
+import { AddBackupProviderPage } from "./AddBackupProvider/index.js";
import { BackupPage } from "./BackupPage.js";
import { DepositPage } from "./DepositPage/index.js";
+import { DestinationSelectionPage } from "./DestinationSelection/index.js";
+import { DeveloperPage } from "./DeveloperPage.js";
import { ExchangeAddPage } from "./ExchangeAddPage.js";
import { HistoryPage } from "./History.js";
+import { NotificationsPage } from "./Notifications/index.js";
import { ProviderDetailPage } from "./ProviderDetailPage.js";
+import { QrReaderPage } from "./QrReader.js";
import { SettingsPage } from "./Settings.js";
import { TransactionPage } from "./Transaction.js";
import { WelcomePage } from "./Welcome.js";
-import { QrReaderPage } from "./QrReader.js";
-import { platform } from "../platform/api.js";
-import { DestinationSelectionPage } from "./DestinationSelection/index.js";
-import { ExchangeSelectionPage } from "./ExchangeSelection/index.js";
-import { TransferCreatePage } from "../cta/TransferCreate/index.js";
-import { InvoiceCreatePage } from "../cta/InvoiceCreate/index.js";
-import { TransferPickupPage } from "../cta/TransferPickup/index.js";
-import { InvoicePayPage } from "../cta/InvoicePay/index.js";
-import { RecoveryPage } from "../cta/Recovery/index.js";
-import { AddBackupProviderPage } from "./AddBackupProvider/index.js";
-import { NotificationsPage } from "./Notifications/index.js";
export function Application(): VNode {
- const [globalNotification, setGlobalNotification] = useState<
- VNode | undefined
- >(undefined);
- const hash_history = createHashHistory();
- function clearNotification(): void {
- setGlobalNotification(undefined);
- }
- function clearNotificationWhenMovingOut(): void {
- // const movingOutFromNotification =
- // globalNotification && e.url !== globalNotification.to;
- if (globalNotification) {
- //&& movingOutFromNotification) {
- setGlobalNotification(undefined);
- }
- }
const { i18n } = useTranslationContext();
+ const hash_history = createHashHistory();
+ async function redirectToTxInfo(tid: string): Promise<void> {
+ redirectTo(Pages.balanceTransaction({ tid }));
+ }
return (
<TranslationProvider>
<DevContextProvider>
<IoCProviderForRuntime>
- {/* <Match/> won't work in the first render if <Router /> is not called first */}
- {/* https://github.com/preactjs/preact-router/issues/415 */}
<Router history={hash_history}>
- <Match default>
- {({ path }: { path: string }) => {
- if (path && path.startsWith("/cta")) return;
- return (
- <Fragment>
- <LogoHeader />
- <WalletNavBar path={path} />
- {shouldShowPendingOperations(path) && (
- <div
- style={{
- backgroundColor: "lightcyan",
- display: "flex",
- justifyContent: "center",
- }}
- >
- <PendingTransactions
- goToTransaction={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- </div>
- )}
- </Fragment>
- );
- }}
- </Match>
- </Router>
- <WalletBox>
- {globalNotification && (
- <SuccessBox onClick={clearNotification}>
- <div>{globalNotification}</div>
- </SuccessBox>
- )}
- <Router
- history={hash_history}
- onChange={clearNotificationWhenMovingOut}
- >
- <Route path={Pages.welcome} component={WelcomePage} />
-
- {/**
- * BALANCE
- */}
+ <Route
+ path={Pages.welcome}
+ component={() => (
+ <WalletTemplate>
+ <WelcomePage />
+ </WalletTemplate>
+ )}
+ />
- <Route
- path={Pages.balanceHistory.pattern}
- component={HistoryPage}
- goToWalletDeposit={(currency: string) =>
- redirectTo(Pages.sendCash({ amount: `${currency}:0` }))
- }
- goToWalletManualWithdraw={(currency?: string) =>
- redirectTo(
- Pages.receiveCash({
- amount: !currency ? undefined : `${currency}:0`,
- }),
- )
- }
- />
- <Route path={Pages.exchanges} component={ExchangeSelectionPage} />
- <Route
- path={Pages.sendCash.pattern}
- type="send"
- component={DestinationSelectionPage}
- goToWalletBankDeposit={(amount: string) =>
- redirectTo(Pages.balanceDeposit({ amount }))
- }
- goToWalletWalletSend={(amount: string) =>
- redirectTo(Pages.ctaTransferCreate({ amount }))
- }
- />
- <Route
- path={Pages.receiveCash.pattern}
- type="get"
- component={DestinationSelectionPage}
- goToWalletManualWithdraw={(amount?: string) =>
- redirectTo(Pages.ctaWithdrawManual({ amount }))
- }
- goToWalletWalletInvoice={(amount?: string) =>
- redirectTo(Pages.ctaInvoiceCreate({ amount }))
- }
- />
+ <Route
+ path={Pages.qr}
+ component={() => (
+ <WalletTemplate goToTransaction={redirectToTxInfo}>
+ <QrReaderPage
+ onDetected={(talerActionUrl: string) => {
+ platform.openWalletURIFromPopup(talerActionUrl);
+ }}
+ />
+ </WalletTemplate>
+ )}
+ />
- <Route
- path={Pages.balanceTransaction.pattern}
- component={TransactionPage}
- goToWalletHistory={(currency?: string) =>
- redirectTo(Pages.balanceHistory({ currency }))
- }
- />
+ <Route
+ path={Pages.settings}
+ component={() => (
+ <WalletTemplate goToTransaction={redirectToTxInfo}>
+ <SettingsPage />
+ </WalletTemplate>
+ )}
+ />
+ <Route
+ path={Pages.notifications}
+ component={() => (
+ <WalletTemplate>
+ <NotificationsPage />
+ </WalletTemplate>
+ )}
+ />
+ {/**
+ * SETTINGS
+ */}
+ <Route
+ path={Pages.settingsExchangeAdd.pattern}
+ component={() => (
+ <WalletTemplate>
+ <ExchangeAddPage onBack={() => redirectTo(Pages.balance)} />
+ </WalletTemplate>
+ )}
+ />
- <Route
- path={Pages.balanceDeposit.pattern}
- component={DepositPage}
- onCancel={(currency: string) => {
- redirectTo(Pages.balanceHistory({ currency }));
- }}
- onSuccess={(currency: string) => {
- redirectTo(Pages.balanceHistory({ currency }));
- setGlobalNotification(
- <i18n.Translate>
- All done, your transaction is in progress
- </i18n.Translate>,
- );
- }}
- />
- {/**
- * PENDING
- */}
- <Route
- path={Pages.qr}
- component={QrReaderPage}
- onDetected={(talerActionUrl: string) => {
- platform.openWalletURIFromPopup(talerActionUrl);
- }}
- />
+ <Route
+ path={Pages.balanceHistory.pattern}
+ component={() => (
+ <WalletTemplate
+ path="balance"
+ goToTransaction={redirectToTxInfo}
+ >
+ <HistoryPage
+ goToWalletDeposit={(currency: string) =>
+ redirectTo(Pages.sendCash({ amount: `${currency}:0` }))
+ }
+ goToWalletManualWithdraw={(currency?: string) =>
+ redirectTo(
+ Pages.receiveCash({
+ amount: !currency ? undefined : `${currency}:0`,
+ }),
+ )
+ }
+ />
+ </WalletTemplate>
+ )}
+ />
+ <Route
+ path={Pages.sendCash.pattern}
+ component={({ amount }: { amount?: string }) => (
+ <WalletTemplate path="balance">
+ <DestinationSelectionPage
+ type="send"
+ amount={amount}
+ goToWalletBankDeposit={(amount: string) =>
+ redirectTo(Pages.balanceDeposit({ amount }))
+ }
+ goToWalletWalletSend={(amount: string) =>
+ redirectTo(Pages.ctaTransferCreate({ amount }))
+ }
+ />
+ </WalletTemplate>
+ )}
+ />
+ <Route
+ path={Pages.receiveCash.pattern}
+ component={({ amount }: { amount?: string }) => (
+ <WalletTemplate path="balance">
+ <DestinationSelectionPage
+ type="get"
+ amount={amount}
+ goToWalletManualWithdraw={(amount?: string) =>
+ redirectTo(Pages.ctaWithdrawManual({ amount }))
+ }
+ goToWalletWalletInvoice={(amount?: string) =>
+ redirectTo(Pages.ctaInvoiceCreate({ amount }))
+ }
+ />
+ </WalletTemplate>
+ )}
+ />
- <Route path={Pages.settings} component={SettingsPage} />
- <Route path={Pages.notifications} component={NotificationsPage} />
+ <Route
+ path={Pages.balanceTransaction.pattern}
+ component={({ tid }: { tid: string }) => (
+ <WalletTemplate path="balance">
+ <TransactionPage
+ tid={tid}
+ goToWalletHistory={(currency?: string) =>
+ redirectTo(Pages.balanceHistory({ currency }))
+ }
+ />
+ </WalletTemplate>
+ )}
+ />
- {/**
- * BACKUP
- */}
- <Route
- path={Pages.backup}
- component={BackupPage}
- onAddProvider={() => redirectTo(Pages.backupProviderAdd)}
- />
- <Route
- path={Pages.backupProviderDetail.pattern}
- component={ProviderDetailPage}
- onPayProvider={(uri: string) =>
- redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`)
- }
- onWithdraw={(amount: string) =>
- redirectTo(Pages.receiveCash({ amount }))
- }
- onBack={() => redirectTo(Pages.backup)}
- />
- <Route
- path={Pages.backupProviderAdd}
- component={AddBackupProviderPage}
- onPaymentRequired={(uri: string) =>
- redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`)
- }
- onComplete={(pid: string) =>
- redirectTo(Pages.backupProviderDetail({ pid }))
- }
- onBack={() => redirectTo(Pages.backup)}
- />
+ <Route
+ path={Pages.balanceDeposit.pattern}
+ component={() => (
+ <WalletTemplate path="balance">
+ <DepositPage
+ onCancel={(currency: string) => {
+ redirectTo(Pages.balanceHistory({ currency }));
+ }}
+ onSuccess={(currency: string) => {
+ redirectTo(Pages.balanceHistory({ currency }));
+ }}
+ />
+ </WalletTemplate>
+ )}
+ />
- {/**
- * SETTINGS
- */}
- <Route
- path={Pages.settingsExchangeAdd.pattern}
- component={ExchangeAddPage}
- onBack={() => redirectTo(Pages.balance)}
- />
+ <Route
+ path={Pages.backup}
+ component={() => (
+ <WalletTemplate
+ path="backup"
+ goToTransaction={redirectToTxInfo}
+ >
+ <BackupPage
+ onAddProvider={() => redirectTo(Pages.backupProviderAdd)}
+ />
+ </WalletTemplate>
+ )}
+ />
+ <Route
+ path={Pages.backupProviderDetail.pattern}
+ component={({ pid }: { pid: string }) => (
+ <WalletTemplate>
+ <ProviderDetailPage
+ pid={pid}
+ onPayProvider={(uri: string) =>
+ redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`)
+ }
+ onWithdraw={(amount: string) =>
+ redirectTo(Pages.receiveCash({ amount }))
+ }
+ onBack={() => redirectTo(Pages.backup)}
+ />
+ </WalletTemplate>
+ )}
+ />
+ <Route
+ path={Pages.backupProviderAdd}
+ component={() => (
+ <WalletTemplate>
+ <AddBackupProviderPage
+ onPaymentRequired={(uri: string) =>
+ redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`)
+ }
+ onComplete={(pid: string) =>
+ redirectTo(Pages.backupProviderDetail({ pid }))
+ }
+ onBack={() => redirectTo(Pages.backup)}
+ />
+ </WalletTemplate>
+ )}
+ />
- {/**
- * DEV
- */}
+ {/**
+ * DEV
+ */}
+ <Route
+ path={Pages.dev}
+ component={() => (
+ <WalletTemplate path="dev" goToTransaction={redirectToTxInfo}>
+ <DeveloperPage />
+ </WalletTemplate>
+ )}
+ />
- <Route path={Pages.dev} component={DeveloperPage} />
+ {/**
+ * CALL TO ACTION
+ */}
+ <Route
+ path={Pages.ctaPay}
+ component={({ talerPayUri }: { talerPayUri: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash payment`}>
+ <PaymentPage
+ talerPayUri={talerPayUri}
+ goToWalletManualWithdraw={(amount?: string) =>
+ redirectTo(Pages.receiveCash({ amount }))
+ }
+ cancel={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaRefund}
+ component={({ talerRefundUri }: { talerRefundUri: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash refund`}>
+ <RefundPage
+ talerRefundUri={talerRefundUri}
+ cancel={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaTips}
+ component={({ talerTipUri }: { talerTipUri: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash tip`}>
+ <TipPage
+ talerTipUri={talerTipUri}
+ onCancel={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaWithdraw}
+ component={({
+ talerWithdrawUri,
+ }: {
+ talerWithdrawUri: string;
+ }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}>
+ <WithdrawPageFromURI
+ talerWithdrawUri={talerWithdrawUri}
+ cancel={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaWithdrawManual.pattern}
+ component={({ amount }: { amount: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}>
+ <WithdrawPageFromParams
+ amount={amount}
+ cancel={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaDeposit}
+ component={({
+ amountStr,
+ talerDepositUri,
+ }: {
+ amountStr: string;
+ talerDepositUri: string;
+ }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash deposit`}>
+ <DepositPageCTA
+ amountStr={amountStr}
+ talerDepositUri={talerDepositUri}
+ cancel={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaInvoiceCreate.pattern}
+ component={({ amount }: { amount: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash invoice`}>
+ <InvoiceCreatePage
+ amount={amount}
+ onClose={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaTransferCreate.pattern}
+ component={({ amount }: { amount: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash transfer`}>
+ <TransferCreatePage
+ amount={amount}
+ onClose={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaInvoicePay}
+ component={({ talerPayPullUri }: { talerPayPullUri: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash invoice`}>
+ <InvoicePayPage
+ talerPayPullUri={talerPayPullUri}
+ goToWalletManualWithdraw={(amount?: string) =>
+ redirectTo(Pages.receiveCash({ amount }))
+ }
+ onClose={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaTransferPickup}
+ component={({ talerPayPushUri }: { talerPayPushUri: string }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash transfer`}>
+ <TransferPickupPage
+ talerPayPushUri={talerPayPushUri}
+ onClose={() => redirectTo(Pages.balance)}
+ onSuccess={(tid: string) =>
+ redirectTo(Pages.balanceTransaction({ tid }))
+ }
+ />
+ </CallToActionTemplate>
+ )}
+ />
+ <Route
+ path={Pages.ctaRecovery}
+ component={({
+ talerRecoveryUri,
+ }: {
+ talerRecoveryUri: string;
+ }) => (
+ <CallToActionTemplate title={i18n.str`Digital cash recovery`}>
+ <RecoveryPage
+ talerRecoveryUri={talerRecoveryUri}
+ onCancel={() => redirectTo(Pages.balance)}
+ onSuccess={() => redirectTo(Pages.backup)}
+ />
+ </CallToActionTemplate>
+ )}
+ />
- {/**
- * CALL TO ACTION
- */}
- <Route
- path={Pages.ctaPay}
- component={PaymentPage}
- goToWalletManualWithdraw={(amount?: string) =>
- redirectTo(Pages.receiveCash({ amount }))
- }
- cancel={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaRefund}
- component={RefundPage}
- cancel={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaTips}
- component={TipPage}
- onCancel={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaWithdraw}
- component={WithdrawPageFromURI}
- cancel={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaWithdrawManual.pattern}
- component={WithdrawPageFromParams}
- cancel={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaDeposit}
- component={DepositPageCTA}
- cancel={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaInvoiceCreate.pattern}
- component={InvoiceCreatePage}
- onClose={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaTransferCreate.pattern}
- component={TransferCreatePage}
- onClose={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaInvoicePay}
- component={InvoicePayPage}
- goToWalletManualWithdraw={(amount?: string) =>
- redirectTo(Pages.receiveCash({ amount }))
- }
- onClose={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaTransferPickup}
- component={TransferPickupPage}
- onClose={() => redirectTo(Pages.balance)}
- onSuccess={(tid: string) =>
- redirectTo(Pages.balanceTransaction({ tid }))
- }
- />
- <Route
- path={Pages.ctaRecovery}
- component={RecoveryPage}
- onCancel={() => redirectTo(Pages.balance)}
- onSuccess={() => redirectTo(Pages.backup)}
- />
+ {/**
+ * NOT FOUND
+ * all redirects should be at the end
+ */}
+ <Route
+ path={Pages.balance}
+ component={() => <Redirect to={Pages.balanceHistory({})} />}
+ />
- {/**
- * NOT FOUND
- * all redirects should be at the end
- */}
- <Route
- path={Pages.balance}
- component={Redirect}
- to={Pages.balanceHistory({})}
- />
-
- <Route
- default
- component={Redirect}
- to={Pages.balanceHistory({})}
- />
- </Router>
- </WalletBox>
+ <Route
+ default
+ component={() => <Redirect to={Pages.balanceHistory({})} />}
+ />
+ </Router>
</IoCProviderForRuntime>
</DevContextProvider>
</TranslationProvider>
@@ -403,3 +503,40 @@ function shouldShowPendingOperations(url: string): boolean {
Pages.backup,
].some((p) => matchesRoute(url, p));
}
+
+function CallToActionTemplate({
+ title,
+ children,
+}: {
+ title: TranslatedString;
+ children: ComponentChildren;
+}): VNode {
+ return (
+ <WalletAction>
+ <LogoHeader />
+ <SubTitle>{title}</SubTitle>
+ {children}
+ </WalletAction>
+ );
+}
+
+function WalletTemplate({
+ path,
+ children,
+ goToTransaction,
+}: {
+ path?: WalletNavBarOptions;
+ children: ComponentChildren;
+ goToTransaction?: (id: string) => Promise<void>;
+}): VNode {
+ return (
+ <Fragment>
+ <LogoHeader />
+ <WalletNavBar path={path} />
+ {goToTransaction ? (
+ <PendingTransactions goToTransaction={goToTransaction} />
+ ) : undefined}
+ <WalletBox>{children}</WalletBox>
+ </Fragment>
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
index 4805c03ca..74e7ce611 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
@@ -92,6 +92,7 @@ type CoinsInfo = CoinDumpJson["coins"];
type CalculatedCoinfInfo = {
ageKeysCount: number | undefined;
denom_value: number;
+ denom_fraction: number;
//remain_value: number;
status: string;
from_refresh: boolean;
@@ -151,7 +152,8 @@ export function View({
}
prev[cur.exchange_base_url].push({
ageKeysCount: cur.ageCommitmentProof?.proof.privateKeys.length,
- denom_value: parseFloat(Amounts.stringifyValue(denom)),
+ denom_value: denom.value,
+ denom_fraction: denom.fraction,
// remain_value: parseFloat(
// Amounts.stringifyValue(Amounts.parseOrThrow(cur.remaining_value)),
// ),
@@ -340,7 +342,10 @@ export function View({
{Object.keys(money_by_exchange).map((ex, idx) => {
const allcoins = money_by_exchange[ex];
allcoins.sort((a, b) => {
- return b.denom_value - a.denom_value;
+ if (b.denom_value !== a.denom_value) {
+ return b.denom_value - a.denom_value;
+ }
+ return b.denom_fraction - a.denom_fraction;
});
const coins = allcoins.reduce(
@@ -407,11 +412,31 @@ function ShowAllCoins({
const { i18n } = useTranslationContext();
const [collapsedSpent, setCollapsedSpent] = useState(true);
const [collapsedUnspent, setCollapsedUnspent] = useState(false);
- const total = coins.usable.reduce((prev, cur) => prev + cur.denom_value, 0);
+ const totalUsable = coins.usable.reduce(
+ (prev, cur) =>
+ Amounts.add(prev, {
+ currency: "NONE",
+ fraction: cur.denom_fraction,
+ value: cur.denom_value,
+ }).amount,
+ Amounts.zeroOfCurrency("NONE"),
+ );
+ const totalSpent = coins.spent.reduce(
+ (prev, cur) =>
+ Amounts.add(prev, {
+ currency: "NONE",
+ fraction: cur.denom_fraction,
+ value: cur.denom_value,
+ }).amount,
+ Amounts.zeroOfCurrency("NONE"),
+ );
return (
<Fragment>
<p>
- <b>{ex}</b>: {total} {currencies[ex]}
+ <b>{ex}</b>: {Amounts.stringifyValue(totalUsable)} {currencies[ex]}
+ </p>
+ <p>
+ spent: {Amounts.stringifyValue(totalSpent)} {currencies[ex]}
</p>
<p onClick={() => setCollapsedUnspent(true)}>
<b>