summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/NavigationBar.tsx
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-06-02 12:20:36 -0300
committerSebastian <sebasjm@gmail.com>2022-06-02 12:20:36 -0300
commit5d9390bb3437171353db99e7afd8cbcca432ba5c (patch)
treea71d71d26f32d8d4334c8d49f8766d8a287340de /packages/taler-wallet-webextension/src/NavigationBar.tsx
parentaf7b107f455b01e136db2211c357cc59a506139a (diff)
downloadwallet-core-5d9390bb3437171353db99e7afd8cbcca432ba5c.tar.gz
wallet-core-5d9390bb3437171353db99e7afd8cbcca432ba5c.tar.bz2
wallet-core-5d9390bb3437171353db99e7afd8cbcca432ba5c.zip
typechecked dynamic path
Diffstat (limited to 'packages/taler-wallet-webextension/src/NavigationBar.tsx')
-rw-r--r--packages/taler-wallet-webextension/src/NavigationBar.tsx119
1 files changed, 88 insertions, 31 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index 58783a087..9c8e1ea29 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -40,43 +40,94 @@ import settingsIcon from "./svg/settings_black_24dp.svg";
* @author sebasjm
*/
-export enum Pages {
- welcome = "/welcome",
-
- balance = "/balance",
- balance_history = "/balance/history/:currency?",
- balance_manual_withdraw = "/balance/manual-withdraw/:currency?",
- balance_deposit = "/balance/deposit/:currency",
- balance_transaction = "/balance/transaction/:tid",
-
- dev = "/dev",
-
- backup = "/backup",
- backup_provider_detail = "/backup/provider/:pid",
- backup_provider_add = "/backup/provider/add",
-
- settings = "/settings",
- settings_exchange_add = "/settings/exchange/add/:currency?",
-
- cta = "/cta/:action",
- cta_pay = "/cta/pay",
- cta_refund = "/cta/refund",
- cta_tips = "/cta/tip",
- cta_withdraw = "/cta/withdraw",
- cta_deposit = "/cta/deposit",
+type PageLocation<DynamicPart extends object> = {
+ pattern: string;
+ (params: DynamicPart): string;
+};
+
+function replaceAll(
+ pattern: string,
+ vars: Record<string, string>,
+ values: Record<string, any>,
+): string {
+ let result = pattern;
+ for (const v in vars) {
+ result = result.replace(vars[v], values[v]);
+ }
+ return result;
}
+function pageDefinition<T extends object>(pattern: string): PageLocation<T> {
+ const patternParams = pattern.match(/(:[\w?]*)/g);
+ if (!patternParams)
+ throw Error(
+ `page definition pattern ${pattern} doesn't have any parameter`,
+ );
+
+ const vars = patternParams.reduce((prev, cur) => {
+ const pName = cur.match(/(\w+)/g);
+
+ //skip things like :? in the path pattern
+ if (!pName || !pName[0]) return prev;
+ const name = pName[0];
+ return { ...prev, [name]: cur };
+ }, {} as Record<string, string>);
+
+ const f = (values: T): string => replaceAll(pattern, vars, values);
+ f.pattern = pattern;
+ return f;
+}
+
+export const Pages = {
+ welcome: "/welcome",
+ balance: "/balance",
+ balanceHistory: pageDefinition<{ currency?: string }>(
+ "/balance/history/:currency?",
+ ),
+ balanceManualWithdraw: pageDefinition<{ currency?: string }>(
+ "/balance/manual-withdraw/:currency?",
+ ),
+ balanceDeposit: pageDefinition<{ currency: string }>(
+ "/balance/deposit/:currency",
+ ),
+ balanceTransaction: pageDefinition<{ tid: string }>(
+ "/balance/transaction/:tid",
+ ),
+ dev: "/dev",
+
+ backup: "/backup",
+ backupProviderDetail: pageDefinition<{ pid: string }>(
+ "/backup/provider/:pid",
+ ),
+ backupProviderAdd: "/backup/provider/add",
+
+ settings: "/settings",
+ settingsExchangeAdd: pageDefinition<{ currency?: string }>(
+ "/settings/exchange/add/:currency?",
+ ),
+
+ cta: pageDefinition<{ action: string }>("/cta/:action"),
+ ctaPay: "/cta/pay",
+ ctaRefund: "/cta/refund",
+ ctaTips: "/cta/tip",
+ ctaWithdraw: "/cta/withdraw",
+ ctaDeposit: "/cta/deposit",
+};
+
export function PopupNavBar({ path = "" }: { path?: string }): VNode {
const { i18n } = useTranslationContext();
return (
<NavigationHeader>
- <a href="/balance" class={path.startsWith("/balance") ? "active" : ""}>
+ <a
+ href={Pages.balance}
+ class={path.startsWith("/balance") ? "active" : ""}
+ >
<i18n.Translate>Balance</i18n.Translate>
</a>
- <a href="/backup" class={path.startsWith("/backup") ? "active" : ""}>
+ <a href={Pages.backup} class={path.startsWith("/backup") ? "active" : ""}>
<i18n.Translate>Backup</i18n.Translate>
</a>
- <a href="/settings">
+ <a href={Pages.settings}>
<SvgIcon
title={i18n.str`Settings`}
dangerouslySetInnerHTML={{ __html: settingsIcon }}
@@ -92,21 +143,27 @@ export function WalletNavBar({ path = "" }: { path?: string }): VNode {
return (
<NavigationHeaderHolder>
<NavigationHeader>
- <a href="/balance" class={path.startsWith("/balance") ? "active" : ""}>
+ <a
+ href={Pages.balance}
+ class={path.startsWith("/balance") ? "active" : ""}
+ >
<i18n.Translate>Balance</i18n.Translate>
</a>
- <a href="/backup" class={path.startsWith("/backup") ? "active" : ""}>
+ <a
+ href={Pages.backup}
+ class={path.startsWith("/backup") ? "active" : ""}
+ >
<i18n.Translate>Backup</i18n.Translate>
</a>
<JustInDevMode>
- <a href="/dev" class={path.startsWith("/dev") ? "active" : ""}>
+ <a href={Pages.dev} class={path.startsWith("/dev") ? "active" : ""}>
<i18n.Translate>Dev</i18n.Translate>
</a>
</JustInDevMode>
<a
- href="/settings"
+ href={Pages.settings}
class={path.startsWith("/settings") ? "active" : ""}
>
<i18n.Translate>Settings</i18n.Translate>