From 550905f0e7eed38fa1ef598b4015faf10648cf1b Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 1 Jul 2021 15:42:32 -0300 Subject: add provider examples --- .../src/popup/BackupPage.tsx | 2 +- .../src/popup/Provider.stories.tsx | 215 -------------------- .../popup/ProviderAddConfirmProvider.stories.tsx | 60 ++++++ .../src/popup/ProviderAddPage.tsx | 107 ++++++++++ .../src/popup/ProviderAddSetUrl.stories.tsx | 46 +++++ .../src/popup/ProviderDetail.stories.tsx | 218 +++++++++++++++++++++ .../src/popup/ProviderDetailPage.tsx | 163 +++++++++++++++ .../src/popup/ProviderPage.tsx | 174 ---------------- .../src/popup/Transaction.tsx | 14 +- .../taler-wallet-webextension/src/popup/popup.tsx | 5 +- 10 files changed, 605 insertions(+), 399 deletions(-) delete mode 100644 packages/taler-wallet-webextension/src/popup/Provider.stories.tsx create mode 100644 packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx create mode 100644 packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx create mode 100644 packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx create mode 100644 packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx create mode 100644 packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx delete mode 100644 packages/taler-wallet-webextension/src/popup/ProviderPage.tsx (limited to 'packages/taler-wallet-webextension/src/popup') diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx index 968898a63..e0e41427b 100644 --- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx @@ -99,7 +99,7 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element { {dateStr &&
{dateStr}
} {!dateStr &&
never synced
}
- {props.title} + {props.title}
{props.subtitle}
diff --git a/packages/taler-wallet-webextension/src/popup/Provider.stories.tsx b/packages/taler-wallet-webextension/src/popup/Provider.stories.tsx deleted file mode 100644 index 7b059103b..000000000 --- a/packages/taler-wallet-webextension/src/popup/Provider.stories.tsx +++ /dev/null @@ -1,215 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 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 - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core'; -import { FunctionalComponent } from 'preact'; -import { ProviderView as TestedComponent } from './ProviderPage'; - -export default { - title: 'popup/backup/details', - component: TestedComponent, - argTypes: { - onRetry: { action: 'onRetry' }, - onDelete: { action: 'onDelete' }, - onBack: { action: 'onBack' }, - } -}; - - -function createExample(Component: FunctionalComponent, props: Partial) { - const r = (args: any) => - r.args = props - return r -} - -export const NotDefined = createExample(TestedComponent, { - currency: 'ARS', -}); - -export const Active = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": true, - "syncProviderBaseUrl": "http://sync.taler:9967/", - "lastSuccessfulBackupTimestamp": { - "t_ms": 1625063925078 - }, - "paymentProposalIds": [ - "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" - ], - "paymentStatus": { - "type": ProviderPaymentType.Paid, - "paidUntil": { - "t_ms": 1656599921000 - } - }, - "terms": { - "annualFee": "ARS:1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - -export const ActiveErrorSync = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": true, - "syncProviderBaseUrl": "http://sync.taler:9967/", - "lastSuccessfulBackupTimestamp": { - "t_ms": 1625063925078 - }, - "paymentProposalIds": [ - "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" - ], - "paymentStatus": { - "type": ProviderPaymentType.Paid, - "paidUntil": { - "t_ms": 1656599921000 - } - }, - lastError: { - code: 2002, - details: 'details', - hint: 'error hint from the server', - message: 'message' - }, - "terms": { - "annualFee": "ARS:1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - -export const ActiveBackupProblemUnreadable = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": true, - "syncProviderBaseUrl": "http://sync.taler:9967/", - "lastSuccessfulBackupTimestamp": { - "t_ms": 1625063925078 - }, - "paymentProposalIds": [ - "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" - ], - "paymentStatus": { - "type": ProviderPaymentType.Paid, - "paidUntil": { - "t_ms": 1656599921000 - } - }, - backupProblem: { - type: 'backup-unreadable' - }, - "terms": { - "annualFee": "ARS:1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - -export const ActiveBackupProblemDevice = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": true, - "syncProviderBaseUrl": "http://sync.taler:9967/", - "lastSuccessfulBackupTimestamp": { - "t_ms": 1625063925078 - }, - "paymentProposalIds": [ - "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" - ], - "paymentStatus": { - "type": ProviderPaymentType.Paid, - "paidUntil": { - "t_ms": 1656599921000 - } - }, - backupProblem: { - type: 'backup-conflicting-device', - myDeviceId: 'my-device-id', - otherDeviceId: 'other-device-id', - backupTimestamp: { - "t_ms": 1656599921000 - } - }, - "terms": { - "annualFee": "ARS:1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - -export const InactiveUnpaid = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": false, - "syncProviderBaseUrl": "http://sync.demo.taler.net/", - "paymentProposalIds": [], - "paymentStatus": { - "type": ProviderPaymentType.Unpaid, - }, - "terms": { - "annualFee": "ARS:0.1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - -export const InactiveInsufficientBalance = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": false, - "syncProviderBaseUrl": "http://sync.demo.taler.net/", - "paymentProposalIds": [], - "paymentStatus": { - "type": ProviderPaymentType.InsufficientBalance, - }, - "terms": { - "annualFee": "ARS:0.1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - -export const InactivePending = createExample(TestedComponent, { - currency: 'ARS', - info: { - "active": false, - "syncProviderBaseUrl": "http://sync.demo.taler.net/", - "paymentProposalIds": [], - "paymentStatus": { - "type": ProviderPaymentType.Pending, - }, - "terms": { - "annualFee": "ARS:0.1", - "storageLimitInMegabytes": 16, - "supportedProtocolVersion": "0.0" - } - } -}); - - diff --git a/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx b/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx new file mode 100644 index 000000000..679a7ce43 --- /dev/null +++ b/packages/taler-wallet-webextension/src/popup/ProviderAddConfirmProvider.stories.tsx @@ -0,0 +1,60 @@ +/* + This file is part of GNU Taler + (C) 2021 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { FunctionalComponent } from 'preact'; +import { ConfirmProviderView as TestedComponent } from './ProviderAddPage'; + +export default { + title: 'popup/backup/confirm', + component: TestedComponent, + argTypes: { + onRetry: { action: 'onRetry' }, + onDelete: { action: 'onDelete' }, + onBack: { action: 'onBack' }, + } +}; + + +function createExample(Component: FunctionalComponent, props: Partial) { + const r = (args: any) => + r.args = props + return r +} + +export const DemoService = createExample(TestedComponent, { + currency: 'KUDOS', + url: 'https://sync.demo.taler.net/', + provider: { + annual_fee: 'KUDOS:0.1', + storage_limit_in_megabytes: 20, + supported_protocol_version: '1' + } +}); + +export const FreeService = createExample(TestedComponent, { + currency: 'ARS', + url: 'https://sync.taler:9667/', + provider: { + annual_fee: 'ARS:0', + storage_limit_in_megabytes: 20, + supported_protocol_version: '1' + } +}); diff --git a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx new file mode 100644 index 000000000..7b8712eca --- /dev/null +++ b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx @@ -0,0 +1,107 @@ +import { Amounts, BackupBackupProviderTerms, i18n } from "@gnu-taler/taler-util"; +import { privateDecrypt } from "crypto"; +import { add, addYears } from "date-fns"; +import { VNode } from "preact"; +import { useState } from "preact/hooks"; +import * as wxApi from "../wxApi"; +import ProviderAddConfirmProviderStories from "./ProviderAddConfirmProvider.stories"; + +interface Props { + currency: string; +} + +export function ProviderAddPage({ currency }: Props): VNode { + const [verifying, setVerifying] = useState<{ url: string, provider: BackupBackupProviderTerms } | undefined>(undefined) + if (!verifying) { + return { + setVerifying(undefined); + }} + onVerify={(url) => { + return fetch(url).then(r => r.json()) + .then((provider) => setVerifying({ url, provider })) + .catch((e) => e.message) + }} + /> + } + return { + setVerifying(undefined); + }} + onConfirm={() => { + wxApi.addBackupProvider(verifying.url).then(_ => history.go(-1)) + }} + + /> +} + +export interface SetUrlViewProps { + currency: string, + onCancel: () => void; + onVerify: (s: string) => Promise; +} + +export function SetUrlView({ currency, onCancel, onVerify }: SetUrlViewProps) { + const [value, setValue] = useState("") + const [error, setError] = useState(undefined) + return
+
+
+ Add backup provider for storing {currency} +
+ {error &&
+

{error}

+
} +

Backup provider URL

+ setValue(e.currentTarget.value)} /> +

+ Backup providers may charge for their service +

+
+
+ +
+ +
+
+
+} + +export interface ConfirmProviderViewProps { + provider: BackupBackupProviderTerms, + currency: string, + url: string, + onCancel: () => void; + onConfirm: () => void +} +export function ConfirmProviderView({ url, provider, currency, onCancel, onConfirm }: ConfirmProviderViewProps) { + return
+ +
+
+ Verify provider service terms for storing {currency} +
+

{url}

+

+ {Amounts.isZero(provider.annual_fee) ? 'free of charge' : provider.annual_fee} for a year of backup service +

+

+ {provider.storage_limit_in_megabytes} megabytes of storage +

+
+
+ +
+ +
+
+
+} diff --git a/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx b/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx new file mode 100644 index 000000000..8b9075165 --- /dev/null +++ b/packages/taler-wallet-webextension/src/popup/ProviderAddSetUrl.stories.tsx @@ -0,0 +1,46 @@ +/* + This file is part of GNU Taler + (C) 2021 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core'; +import { FunctionalComponent } from 'preact'; +import { SetUrlView as TestedComponent } from './ProviderAddPage'; + +export default { + title: 'popup/backup/add', + component: TestedComponent, + argTypes: { + onRetry: { action: 'onRetry' }, + onDelete: { action: 'onDelete' }, + onBack: { action: 'onBack' }, + } +}; + + +function createExample(Component: FunctionalComponent, props: Partial) { + const r = (args: any) => + r.args = props + return r +} + +export const SetUrl = createExample(TestedComponent, { + currency: 'ARS', +}); + diff --git a/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx b/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx new file mode 100644 index 000000000..01c0a5f05 --- /dev/null +++ b/packages/taler-wallet-webextension/src/popup/ProviderDetail.stories.tsx @@ -0,0 +1,218 @@ +/* + This file is part of GNU Taler + (C) 2021 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ProviderPaymentType } from '@gnu-taler/taler-wallet-core'; +import { FunctionalComponent } from 'preact'; +import { ProviderView as TestedComponent } from './ProviderDetailPage'; + +export default { + title: 'popup/backup/details', + component: TestedComponent, + argTypes: { + onRetry: { action: 'onRetry' }, + onDelete: { action: 'onDelete' }, + onBack: { action: 'onBack' }, + } +}; + + +function createExample(Component: FunctionalComponent, props: Partial) { + const r = (args: any) => + r.args = props + return r +} + +export const NotDefined = createExample(TestedComponent, { + currency: 'ARS', +}); + +export const Active = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": true, + "syncProviderBaseUrl": "http://sync.taler:9967/", + "lastSuccessfulBackupTimestamp": { + "t_ms": 1625063925078 + }, + "paymentProposalIds": [ + "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" + ], + "paymentStatus": { + "type": ProviderPaymentType.Paid, + "paidUntil": { + "t_ms": 1656599921000 + } + }, + "terms": { + "annualFee": "ARS:1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + +export const ActiveErrorSync = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": true, + "syncProviderBaseUrl": "http://sync.taler:9967/", + "lastSuccessfulBackupTimestamp": { + "t_ms": 1625063925078 + }, + lastAttemptedBackupTimestamp: { + "t_ms": 1625063925078 + }, + "paymentProposalIds": [ + "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" + ], + "paymentStatus": { + "type": ProviderPaymentType.Paid, + "paidUntil": { + "t_ms": 1656599921000 + } + }, + lastError: { + code: 2002, + details: 'details', + hint: 'error hint from the server', + message: 'message' + }, + "terms": { + "annualFee": "ARS:1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + +export const ActiveBackupProblemUnreadable = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": true, + "syncProviderBaseUrl": "http://sync.taler:9967/", + "lastSuccessfulBackupTimestamp": { + "t_ms": 1625063925078 + }, + "paymentProposalIds": [ + "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" + ], + "paymentStatus": { + "type": ProviderPaymentType.Paid, + "paidUntil": { + "t_ms": 1656599921000 + } + }, + backupProblem: { + type: 'backup-unreadable' + }, + "terms": { + "annualFee": "ARS:1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + +export const ActiveBackupProblemDevice = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": true, + "syncProviderBaseUrl": "http://sync.taler:9967/", + "lastSuccessfulBackupTimestamp": { + "t_ms": 1625063925078 + }, + "paymentProposalIds": [ + "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG" + ], + "paymentStatus": { + "type": ProviderPaymentType.Paid, + "paidUntil": { + "t_ms": 1656599921000 + } + }, + backupProblem: { + type: 'backup-conflicting-device', + myDeviceId: 'my-device-id', + otherDeviceId: 'other-device-id', + backupTimestamp: { + "t_ms": 1656599921000 + } + }, + "terms": { + "annualFee": "ARS:1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + +export const InactiveUnpaid = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": false, + "syncProviderBaseUrl": "http://sync.demo.taler.net/", + "paymentProposalIds": [], + "paymentStatus": { + "type": ProviderPaymentType.Unpaid, + }, + "terms": { + "annualFee": "ARS:0.1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + +export const InactiveInsufficientBalance = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": false, + "syncProviderBaseUrl": "http://sync.demo.taler.net/", + "paymentProposalIds": [], + "paymentStatus": { + "type": ProviderPaymentType.InsufficientBalance, + }, + "terms": { + "annualFee": "ARS:0.1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + +export const InactivePending = createExample(TestedComponent, { + currency: 'ARS', + info: { + "active": false, + "syncProviderBaseUrl": "http://sync.demo.taler.net/", + "paymentProposalIds": [], + "paymentStatus": { + "type": ProviderPaymentType.Pending, + }, + "terms": { + "annualFee": "ARS:0.1", + "storageLimitInMegabytes": 16, + "supportedProtocolVersion": "0.0" + } + } +}); + + diff --git a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx new file mode 100644 index 000000000..59e6cda1b --- /dev/null +++ b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx @@ -0,0 +1,163 @@ +/* + 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 +*/ + + +import { BackupBackupProviderTerms, i18n, Timestamp } from "@gnu-taler/taler-util"; +import { ProviderInfo, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; +import { formatDuration, intervalToDuration, format } from "date-fns"; +import { Fragment, VNode } from "preact"; +import { useRef, useState } from "preact/hooks"; +import { useBackupStatus } from "../hooks/useProvidersByCurrency"; +import * as wxApi from "../wxApi"; + +interface Props { + currency: string; + onAddProvider: (c: string) => void; + onBack: () => void; +} + +export function ProviderDetailPage({ currency, onAddProvider, onBack }: Props): VNode { + const status = useBackupStatus() + if (!status) { + return
Loading...
+ } + const info = status.providers[currency]; + return { null }} + onDelete={() => { null }} + onBack={onBack} + onAddProvider={() => onAddProvider(currency)} + />; +} + +export interface ViewProps { + currency: string; + info?: ProviderInfo; + onDelete: () => void; + onSync: () => void; + onBack: () => void; + onAddProvider: () => void; +} + +export function ProviderView({ currency, info, onDelete, onSync, onBack, onAddProvider }: ViewProps): VNode { + function Footer() { + return
+ +
+ {info && } + {info && } + {!info && } +
+
+ } + function Error() { + if (info?.lastError) { + return +
+
{!info.lastAttemptedBackupTimestamp || info.lastAttemptedBackupTimestamp.t_ms === 'never' ? 'never' : format(new Date(info.lastAttemptedBackupTimestamp.t_ms), 'dd/MM/yyyy HH:mm:ss')}
+

{info.lastError.hint}

+
+
+ } + if (info?.backupProblem) { + switch (info.backupProblem.type) { + case "backup-conflicting-device": + return
+

There is another backup from {info.backupProblem.otherDeviceId}

+
+ case "backup-unreadable": + return
+

Backup is not readable

+
+ default: + return
+

Unkown backup problem: {JSON.stringify(info.backupProblem)}

+
+ } + } + return null + } + function colorByStatus(status: ProviderPaymentType | undefined) { + switch (status) { + case ProviderPaymentType.InsufficientBalance: + return 'rgb(223, 117, 20)' + case ProviderPaymentType.Unpaid: + return 'rgb(202, 60, 60)' + case ProviderPaymentType.Paid: + return 'rgb(28, 184, 65)' + case ProviderPaymentType.Pending: + return 'gray' + case ProviderPaymentType.InsufficientBalance: + return 'rgb(202, 60, 60)' + case ProviderPaymentType.TermsChanged: + return 'rgb(202, 60, 60)' + default: + break; + } + return undefined + } + + return ( +
+ +
+
+ {info?.paymentStatus.type} + {info && + From {info.syncProviderBaseUrl} + } + + + +
+

{currency}

+ {info &&
{info.terms?.annualFee} / year
} +
+ +
{daysSince(info?.lastSuccessfulBackupTimestamp)}
+
+
+
+
+ ) +} + +function daysSince(d?: Timestamp) { + if (!d || d.t_ms === 'never') return 'never synced' + const duration = intervalToDuration({ + start: d.t_ms, + end: new Date(), + }) + const str = formatDuration(duration, { + delimiter: ', ', + format: [ + duration?.years ? 'years' : ( + duration?.months ? 'months' : ( + duration?.days ? 'days' : ( + duration?.hours ? 'hours' : ( + duration?.minutes ? 'minutes' : 'seconds' + ) + ) + ) + ) + ] + }) + return `synced ${str} ago` +} diff --git a/packages/taler-wallet-webextension/src/popup/ProviderPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderPage.tsx deleted file mode 100644 index 1112017fc..000000000 --- a/packages/taler-wallet-webextension/src/popup/ProviderPage.tsx +++ /dev/null @@ -1,174 +0,0 @@ -/* - 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 -*/ - - -import { i18n, Timestamp } from "@gnu-taler/taler-util"; -import { ProviderInfo, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; -import { formatDuration, intervalToDuration } from "date-fns"; -import { VNode } from "preact"; -import { useRef, useState } from "preact/hooks"; -import { useBackupStatus } from "../hooks/useProvidersByCurrency"; -import * as wxApi from "../wxApi"; - -interface Props { - currency: string; -} - -export function ProviderPage({ currency }: Props): VNode { - const status = useBackupStatus() - const [adding, setAdding] = useState(false) - if (!status) { - return
Loading...
- } - if (adding) { - return { - console.log(value) - wxApi.addBackupProvider(value).then(_ => history.go(-1)) - setAdding(false) - }} /> - } - const info = status.providers[currency]; - return { null }} - onDelete={() => { null }} - onBack={() => { history.go(-1); }} - onAddProvider={() => { setAdding(true) }} - />; -} - -function AddProviderView({ onConfirm }: { onConfirm: (s: string) => void }) { - const textInput = useRef(null) - return
- - -
-} - -export interface ViewProps { - currency: string; - info?: ProviderInfo; - onDelete: () => void; - onSync: () => void; - onBack: () => void; - onAddProvider: () => void; -} - -export function ProviderView({ currency, info, onDelete, onSync, onBack, onAddProvider }: ViewProps): VNode { - function Footer() { - return
- -
- {info && } - {info && } - {!info && } -
-
- } - function Error() { - if (info?.lastError) { - return
-

{info.lastError.hint}

-
- } - if (info?.backupProblem) { - switch (info.backupProblem.type) { - case "backup-conflicting-device": - return
-

There is another backup from {info.backupProblem.otherDeviceId}

-
- case "backup-unreadable": - return
-

Backup is not readable

-
- default: - return
-

Unkown backup problem: {JSON.stringify(info.backupProblem)}

-
- } - } - return null - } - function colorByStatus(status: ProviderPaymentType | undefined) { - switch (status) { - case ProviderPaymentType.InsufficientBalance: - return 'rgb(223, 117, 20)' - case ProviderPaymentType.Unpaid: - return 'rgb(202, 60, 60)' - case ProviderPaymentType.Paid: - return 'rgb(28, 184, 65)' - case ProviderPaymentType.Pending: - return 'gray' - case ProviderPaymentType.InsufficientBalance: - return 'rgb(202, 60, 60)' - case ProviderPaymentType.TermsChanged: - return 'rgb(202, 60, 60)' - default: - break; - } - return undefined - } - - return ( -
- -
-
- {info?.paymentStatus.type} - {info && - From {info.syncProviderBaseUrl} - } - - - -
-

{currency}

- {info &&
{info.terms?.annualFee} / year
} -
- -
{daysSince(info?.lastSuccessfulBackupTimestamp)}
-
-
-
-
- ) -} - -function daysSince(d?: Timestamp) { - if (!d || d.t_ms === 'never') return 'never synced' - const duration = intervalToDuration({ - start: d.t_ms, - end: new Date(), - }) - const str = formatDuration(duration, { - delimiter: ', ', - format: [ - duration?.years ? 'years' : ( - duration?.months ? 'months' : ( - duration?.days ? 'days' : ( - duration?.hours ? 'hours' : ( - duration?.minutes ? 'minutes' : 'seconds' - ) - ) - ) - ) - ] - }) - return `synced ${str} ago` -} diff --git a/packages/taler-wallet-webextension/src/popup/Transaction.tsx b/packages/taler-wallet-webextension/src/popup/Transaction.tsx index d6a85d64d..c5274da58 100644 --- a/packages/taler-wallet-webextension/src/popup/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/popup/Transaction.tsx @@ -62,7 +62,7 @@ export function TransactionView({ transaction, onDelete, onRetry, onBack }: Wall function Footer() { return