aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wallet
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-11-24 23:16:01 -0300
committerSebastian <sebasjm@gmail.com>2022-11-24 23:16:01 -0300
commite05ba843a061c8050648ce922f36ed3d8e1cf24a (patch)
tree4daf3eccc5f2976b980e884499a756cc6f864c6e /packages/taler-wallet-webextension/src/wallet
parent88618df7b870732f4f29a80686dd4f4cf20887f8 (diff)
downloadwallet-core-e05ba843a061c8050648ce922f36ed3d8e1cf24a.tar.xz
fix 7465
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
-rw-r--r--packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts6
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Application.tsx12
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Notifications/index.ts61
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Notifications/state.ts48
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx58
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Notifications/test.ts28
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx220
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx81
-rw-r--r--packages/taler-wallet-webextension/src/wallet/index.stories.tsx2
11 files changed, 492 insertions, 28 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts
index 0b3c17902..504ee4678 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts
@@ -171,7 +171,11 @@ export function useComponentState(
switch (resp.status) {
case "payment-required":
- return onPaymentRequired(resp.talerUri);
+ if (resp.talerUri) {
+ return onPaymentRequired(resp.talerUri);
+ } else {
+ return onComplete(url);
+ }
case "error":
return setOperationError(resp.error);
case "ok":
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx
index 6b265c1ba..6362f1924 100644
--- a/packages/taler-wallet-webextension/src/wallet/Application.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx
@@ -66,6 +66,7 @@ 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<
@@ -206,6 +207,7 @@ export function Application(): VNode {
/>
<Route path={Pages.settings} component={SettingsPage} />
+ <Route path={Pages.notifications} component={NotificationsPage} />
{/**
* BACKUP
@@ -218,6 +220,12 @@ export function Application(): VNode {
<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
@@ -254,7 +262,7 @@ export function Application(): VNode {
path={Pages.ctaPay}
component={PaymentPage}
goToWalletManualWithdraw={(amount?: string) =>
- redirectTo(Pages.ctaWithdrawManual({ amount }))
+ redirectTo(Pages.receiveCash({ amount }))
}
cancel={() => redirectTo(Pages.balance)}
onSuccess={(tid: string) =>
@@ -321,7 +329,7 @@ export function Application(): VNode {
path={Pages.ctaInvoicePay}
component={InvoicePayPage}
goToWalletManualWithdraw={(amount?: string) =>
- redirectTo(Pages.ctaWithdrawManual({ amount }))
+ redirectTo(Pages.receiveCash({ amount }))
}
onClose={() => redirectTo(Pages.balance)}
onSuccess={(tid: string) =>
diff --git a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
index b12f5e5f6..2e19d3944 100644
--- a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx
@@ -89,6 +89,7 @@ export const LotOfProviders = createExample(TestedComponent, {
paymentProposalIds: [],
paymentStatus: {
type: ProviderPaymentType.Pending,
+ talerUri: "taler://",
},
terms: {
annualFee: "KUDOS:0.1",
@@ -103,6 +104,7 @@ export const LotOfProviders = createExample(TestedComponent, {
paymentProposalIds: [],
paymentStatus: {
type: ProviderPaymentType.InsufficientBalance,
+ amount: "KUDOS:10",
},
terms: {
annualFee: "KUDOS:0.1",
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts
new file mode 100644
index 000000000..253a0e629
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts
@@ -0,0 +1,61 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { UserAttentionUnreadList } from "@gnu-taler/taler-util";
+import { Loading } from "../../components/Loading.js";
+import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { compose, StateViewMap } from "../../utils/index.js";
+import { wxApi } from "../../wxApi.js";
+import { useComponentState } from "./state.js";
+import { LoadingUriView, ReadyView } from "./views.js";
+
+export interface Props {}
+
+export type State = State.Loading | State.LoadingUriError | State.Ready;
+
+export namespace State {
+ export interface Loading {
+ status: "loading";
+ error: undefined;
+ }
+
+ export interface LoadingUriError {
+ status: "loading-error";
+ error: HookError;
+ }
+
+ export interface BaseInfo {
+ error: undefined;
+ }
+
+ export interface Ready extends BaseInfo {
+ status: "ready";
+ error: undefined;
+ list: UserAttentionUnreadList;
+ }
+}
+
+const viewMapping: StateViewMap<State> = {
+ loading: Loading,
+ "loading-error": LoadingUriView,
+ ready: ReadyView,
+};
+
+export const NotificationsPage = compose(
+ "NotificationsPage",
+ (p: Props) => useComponentState(p, wxApi),
+ viewMapping,
+);
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts
new file mode 100644
index 000000000..093722cf0
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts
@@ -0,0 +1,48 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
+import { wxApi } from "../../wxApi.js";
+import { Props, State } from "./index.js";
+
+export function useComponentState({}: Props, api: typeof wxApi): State {
+ const hook = useAsyncAsHook(async () => {
+ return await api.wallet.call(
+ WalletApiOperation.GetUserAttentionRequests,
+ {},
+ );
+ });
+
+ if (!hook) {
+ return {
+ status: "loading",
+ error: undefined,
+ };
+ }
+ if (hook.hasError) {
+ return {
+ status: "loading-error",
+ error: hook,
+ };
+ }
+
+ return {
+ status: "ready",
+ error: undefined,
+ list: hook.response.pending,
+ };
+}
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx b/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx
new file mode 100644
index 000000000..e4c7105e9
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx
@@ -0,0 +1,58 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { AbsoluteTime, AttentionType } from "@gnu-taler/taler-util";
+import { createExample } from "../../test-utils.js";
+import { ReadyView } from "./views.js";
+
+export default {
+ title: "wallet/notifications",
+};
+
+export const Ready = createExample(ReadyView, {
+ list: [
+ {
+ when: AbsoluteTime.now(),
+ read: false,
+ info: {
+ type: AttentionType.KycWithdrawal,
+ transactionId: "123",
+ },
+ },
+ {
+ when: AbsoluteTime.now(),
+ read: false,
+ info: {
+ type: AttentionType.MerchantRefund,
+ transactionId: "123",
+ },
+ },
+ {
+ when: AbsoluteTime.now(),
+ read: false,
+ info: {
+ type: AttentionType.BackupUnpaid,
+ provider_base_url: "http://sync.taler.net",
+ talerUri: "taler://payment/asdasdasd",
+ },
+ },
+ ],
+});
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/test.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/test.ts
new file mode 100644
index 000000000..eae4d4ca2
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/test.ts
@@ -0,0 +1,28 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { expect } from "chai";
+
+describe("test description", () => {
+ it("should assert", () => {
+ expect([]).deep.equals([]);
+ });
+});
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx b/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx
new file mode 100644
index 000000000..9146d8837
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx
@@ -0,0 +1,220 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU 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.
+
+ GNU 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import {
+ AbsoluteTime,
+ AttentionInfo,
+ AttentionType,
+} from "@gnu-taler/taler-util";
+import { Fragment, h, VNode } from "preact";
+import { LoadingError } from "../../components/LoadingError.js";
+import {
+ Column,
+ DateSeparator,
+ HistoryRow,
+ LargeText,
+ SmallLightText,
+} from "../../components/styled/index.js";
+import { Time } from "../../components/Time.js";
+import { useTranslationContext } from "../../context/translation.js";
+import { Avatar } from "../../mui/Avatar.js";
+import { Button } from "../../mui/Button.js";
+import { Grid } from "../../mui/Grid.js";
+import { Pages } from "../../NavigationBar.js";
+import { assertUnreachable } from "../../utils/index.js";
+import { State } from "./index.js";
+
+export function LoadingUriView({ error }: State.LoadingUriError): VNode {
+ const { i18n } = useTranslationContext();
+
+ return (
+ <LoadingError
+ title={<i18n.Translate>Could not load notifications</i18n.Translate>}
+ error={error}
+ />
+ );
+}
+
+const term = 1000 * 60 * 60 * 24;
+function normalizeToDay(x: number): number {
+ return Math.round(x / term) * term;
+}
+
+export function ReadyView({ list }: State.Ready): VNode {
+ const { i18n } = useTranslationContext();
+ if (list.length < 1) {
+ return (
+ <section>
+ <i18n.Translate>No notification left</i18n.Translate>
+ </section>
+ );
+ }
+
+ const byDate = list.reduce((rv, x) => {
+ const theDate = x.when.t_ms === "never" ? 0 : normalizeToDay(x.when.t_ms);
+ if (theDate) {
+ (rv[theDate] = rv[theDate] || []).push(x);
+ }
+
+ return rv;
+ }, {} as { [x: string]: typeof list });
+ const datesWithNotifications = Object.keys(byDate);
+
+ return (
+ <section>
+ {datesWithNotifications.map((d, i) => {
+ return (
+ <Fragment key={i}>
+ <DateSeparator>
+ <Time
+ timestamp={{ t_ms: Number.parseInt(d, 10) }}
+ format="dd MMMM yyyy"
+ />
+ </DateSeparator>
+ {byDate[d].map((n, i) => (
+ <NotificationItem
+ key={i}
+ info={n.info}
+ isRead={n.read}
+ timestamp={n.when}
+ />
+ ))}
+ </Fragment>
+ );
+ })}
+ </section>
+ );
+}
+
+function NotificationItem({
+ info,
+ isRead,
+ timestamp,
+}: {
+ info: AttentionInfo;
+ timestamp: AbsoluteTime;
+ isRead: boolean;
+}): VNode {
+ switch (info.type) {
+ case AttentionType.KycWithdrawal:
+ return (
+ <NotificationLayout
+ timestamp={timestamp}
+ href={Pages.balanceTransaction({ tid: info.transactionId })}
+ title="Withdrawal on hold"
+ subtitle="Know-your-customer validation is required"
+ iconPath={"K"}
+ isRead={isRead}
+ />
+ );
+ case AttentionType.MerchantRefund:
+ return (
+ <NotificationLayout
+ timestamp={timestamp}
+ href={Pages.balanceTransaction({ tid: info.transactionId })}
+ title="Merchant has refund your payment"
+ subtitle="Accept or deny refund"
+ iconPath={"K"}
+ isRead={isRead}
+ />
+ );
+ case AttentionType.BackupUnpaid:
+ return (
+ <NotificationLayout
+ timestamp={timestamp}
+ href={`${Pages.ctaPay}?talerPayUri=${info.talerUri}`}
+ title="Backup provider is unpaid"
+ subtitle="Complete the payment or remove the service provider"
+ iconPath={"K"}
+ isRead={isRead}
+ />
+ );
+ case AttentionType.AuditorDenominationsExpires:
+ return <div>not implemented</div>;
+ case AttentionType.AuditorKeyExpires:
+ return <div>not implemented</div>;
+ case AttentionType.AuditorTosChanged:
+ return <div>not implemented</div>;
+ case AttentionType.ExchangeDenominationsExpired:
+ return <div>not implemented</div>;
+ // case AttentionType.ExchangeDenominationsExpiresSoon:
+ // return <div>not implemented</div>;
+ case AttentionType.ExchangeKeyExpired:
+ return <div>not implemented</div>;
+ // case AttentionType.ExchangeKeyExpiresSoon:
+ // return <div>not implemented</div>;
+ case AttentionType.ExchangeTosChanged:
+ return <div>not implemented</div>;
+ case AttentionType.BackupExpiresSoon:
+ return <div>not implemented</div>;
+ case AttentionType.PushPaymentReceived:
+ return <div>not implemented</div>;
+ case AttentionType.PullPaymentPaid:
+ return <div>not implemented</div>;
+ default:
+ assertUnreachable(info);
+ }
+}
+
+function NotificationLayout(props: {
+ title: string;
+ href: string;
+ subtitle?: string;
+ timestamp: AbsoluteTime;
+ iconPath: string;
+ isRead: boolean;
+}): VNode {
+ const { i18n } = useTranslationContext();
+ return (
+ <HistoryRow
+ href={props.href}
+ style={{
+ backgroundColor: props.isRead ? "lightcyan" : "inherit",
+ alignItems: "center",
+ }}
+ >
+ <Avatar
+ style={{
+ border: "solid gray 1px",
+ color: "gray",
+ boxSizing: "border-box",
+ }}
+ >
+ {props.iconPath}
+ </Avatar>
+ <Column>
+ <LargeText>
+ <div>{props.title}</div>
+ {props.subtitle && (
+ <div style={{ color: "gray", fontSize: "medium", marginTop: 5 }}>
+ {props.subtitle}
+ </div>
+ )}
+ </LargeText>
+ <SmallLightText style={{ marginTop: 5 }}>
+ <Time timestamp={props.timestamp} format="HH:mm" />
+ </SmallLightText>
+ </Column>
+ <Column>
+ <Grid>
+ <Button variant="outlined">
+ <i18n.Translate>Ignore</i18n.Translate>
+ </Button>
+ </Grid>
+ </Column>
+ </HistoryRow>
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
index d55a25e78..854c14ac1 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx
@@ -174,6 +174,7 @@ export const InactiveInsufficientBalance = createExample(TestedComponent, {
paymentProposalIds: [],
paymentStatus: {
type: ProviderPaymentType.InsufficientBalance,
+ amount: "EUR:123",
},
terms: {
annualFee: "EUR:0.1",
@@ -191,6 +192,7 @@ export const InactivePending = createExample(TestedComponent, {
paymentProposalIds: [],
paymentStatus: {
type: ProviderPaymentType.Pending,
+ talerUri: "taler://pay/sad",
},
terms: {
annualFee: "EUR:0.1",
diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
index d9dd1d746..6dde30b39 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
@@ -36,9 +36,16 @@ import { wxApi } from "../wxApi.js";
interface Props {
pid: string;
onBack: () => Promise<void>;
+ onPayProvider: (uri: string) => Promise<void>;
+ onWithdraw: (amount: string) => Promise<void>;
}
-export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
+export function ProviderDetailPage({
+ pid: providerURL,
+ onBack,
+ onPayProvider,
+ onWithdraw,
+}: Props): VNode {
const { i18n } = useTranslationContext();
async function getProviderInfo(): Promise<ProviderInfo | null> {
//create a first list of backup info by currency
@@ -71,11 +78,30 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
/>
);
}
+ const info = state.response;
+ if (info === null) {
+ return (
+ <Fragment>
+ <section>
+ <p>
+ <i18n.Translate>
+ There is not known provider with url &quot;{providerURL}&quot;.
+ </i18n.Translate>
+ </p>
+ </section>
+ <footer>
+ <Button variant="contained" color="secondary" onClick={onBack}>
+ <i18n.Translate>See providers</i18n.Translate>
+ </Button>
+ <div />
+ </footer>
+ </Fragment>
+ );
+ }
return (
<ProviderView
- url={providerURL}
- info={state.response}
+ info={info}
onSync={async () =>
wxApi.wallet
.call(WalletApiOperation.RunBackupCycle, {
@@ -83,6 +109,16 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
})
.then()
}
+ onPayProvider={async () => {
+ if (info.paymentStatus.type !== ProviderPaymentType.Pending) return;
+ if (!info.paymentStatus.talerUri) return;
+ onPayProvider(info.paymentStatus.talerUri);
+ }}
+ onWithdraw={async () => {
+ if (info.paymentStatus.type !== ProviderPaymentType.InsufficientBalance)
+ return;
+ onWithdraw(info.paymentStatus.amount);
+ }}
onDelete={() =>
wxApi.wallet
.call(WalletApiOperation.RemoveBackupProvider, {
@@ -99,42 +135,25 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
}
export interface ViewProps {
- url: string;
- info: ProviderInfo | null;
+ info: ProviderInfo;
onDelete: () => Promise<void>;
onSync: () => Promise<void>;
onBack: () => Promise<void>;
onExtend: () => Promise<void>;
+ onPayProvider: () => Promise<void>;
+ onWithdraw: () => Promise<void>;
}
export function ProviderView({
info,
- url,
onDelete,
+ onPayProvider,
+ onWithdraw,
onSync,
onBack,
onExtend,
}: ViewProps): VNode {
const { i18n } = useTranslationContext();
- if (info === null) {
- return (
- <Fragment>
- <section>
- <p>
- <i18n.Translate>
- There is not known provider with url &quot;{url}&quot;.
- </i18n.Translate>
- </p>
- </section>
- <footer>
- <Button variant="contained" color="secondary" onClick={onBack}>
- <i18n.Translate>See providers</i18n.Translate>
- </Button>
- <div />
- </footer>
- </Fragment>
- );
- }
const lb = info.lastSuccessfulBackupTimestamp
? AbsoluteTime.fromTimestamp(info.lastSuccessfulBackupTimestamp)
: undefined;
@@ -230,6 +249,18 @@ export function ProviderView({
<Button variant="contained" color="error" onClick={onDelete}>
<i18n.Translate>Remove provider</i18n.Translate>
</Button>
+ {info.paymentStatus.type === ProviderPaymentType.Pending &&
+ info.paymentStatus.talerUri ? (
+ <Button variant="contained" color="primary" onClick={onPayProvider}>
+ <i18n.Translate>Pay</i18n.Translate>
+ </Button>
+ ) : undefined}
+ {info.paymentStatus.type ===
+ ProviderPaymentType.InsufficientBalance ? (
+ <Button variant="contained" color="primary" onClick={onWithdraw}>
+ <i18n.Translate>Withdraw</i18n.Translate>
+ </Button>
+ ) : undefined}
</div>
</footer>
</Fragment>
diff --git a/packages/taler-wallet-webextension/src/wallet/index.stories.tsx b/packages/taler-wallet-webextension/src/wallet/index.stories.tsx
index ef1295846..20de1a3c3 100644
--- a/packages/taler-wallet-webextension/src/wallet/index.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/index.stories.tsx
@@ -36,6 +36,7 @@ import * as a17 from "./QrReader.stories.js";
import * as a18 from "./DestinationSelection.stories.js";
import * as a19 from "./ExchangeSelection/stories.js";
import * as a20 from "./ManageAccount/stories.js";
+import * as a21 from "./Notifications/stories.js";
export default [
a1,
@@ -55,4 +56,5 @@ export default [
a18,
a19,
a20,
+ a21,
];