From 24cac493dded00ef40e0e30a0d2263e4f35c3e29 Mon Sep 17 00:00:00 2001
From: Sebastian <sebasjm@gmail.com>
Date: Wed, 4 Jan 2023 11:24:58 -0300
Subject: fix #7522

---
 .../src/wallet/Application.tsx                     | 741 ++++++++++++---------
 1 file changed, 439 insertions(+), 302 deletions(-)

(limited to 'packages/taler-wallet-webextension/src/wallet/Application.tsx')

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>
+  );
+}
-- 
cgit v1.2.3

