diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/popup/BackupPage.tsx')
-rw-r--r-- | packages/taler-wallet-webextension/src/popup/BackupPage.tsx | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx index 91f1782cc..d7a2d863c 100644 --- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx @@ -17,9 +17,9 @@ import { i18n, Timestamp } from "@gnu-taler/taler-util"; import { ProviderInfo } from "@gnu-taler/taler-wallet-core"; -import { formatDuration, intervalToDuration } from "date-fns"; -import { JSX, VNode } from "preact"; -import { useBackupStatus } from "../hooks/useProvidersByCurrency"; +import { differenceInMonths, formatDuration, intervalToDuration } from "date-fns"; +import { Fragment, JSX, VNode } from "preact"; +import { useBackupStatus } from "../hooks/useBackupStatus"; import { Pages } from "./popup"; interface Props { @@ -31,59 +31,59 @@ export function BackupPage({ onAddProvider }: Props): VNode { if (!status) { return <div>Loading...</div> } - return <BackupView providers={status.providers} onAddProvider={onAddProvider} />; + return <BackupView providers={status.providers} onAddProvider={onAddProvider} onSyncAll={status.sync}/>; } export interface ViewProps { providers: ProviderInfo[], onAddProvider: () => void; + onSyncAll: () => Promise<void>; } -export function BackupView({ providers, onAddProvider }: ViewProps): VNode { +export function BackupView({ providers, onAddProvider, onSyncAll }: ViewProps): VNode { return ( <div style={{ height: 'calc(320px - 34px - 16px)', overflow: 'auto' }}> <div style={{ display: 'flex', flexDirection: 'column' }}> <section style={{ flex: '1 0 auto', height: 'calc(320px - 34px - 34px - 16px)', overflow: 'auto' }}> {!!providers.length && <div> - {providers.map((provider, idx) => { + {providers.map((provider) => { return <BackupLayout status={provider.paymentStatus} timestamp={provider.lastSuccessfulBackupTimestamp} - id={idx} + id={provider.syncProviderBaseUrl} active={provider.active} - subtitle={provider.syncProviderBaseUrl} title={provider.syncProviderBaseUrl} /> })} </div>} - {!providers.length && <div> - There is not backup providers configured, add one with the button below + {!providers.length && <div style={{ color: 'gray', fontWeight: 'bold', marginTop: 80, textAlign: 'center' }}> + <div>No backup providers configured</div> + <button class="pure-button button-success" style={{ marginTop: 15 }} onClick={onAddProvider}><i18n.Translate>Add provider</i18n.Translate></button> </div>} </section> - <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 }}> + {!!providers.length && <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 }}> <div style={{ width: '100%', flexDirection: 'row', justifyContent: 'flex-end', display: 'flex' }}> - <button class="pure-button button-secondary" disabled={!providers.length} style={{ marginLeft: 5 }} onClick={onAddProvider}>{ + <button class="pure-button button-secondary" style={{ marginLeft: 5 }} onClick={onSyncAll}>{ providers.length > 1 ? - <i18n.Translate>sync all now</i18n.Translate>: - <i18n.Translate>sync now</i18n.Translate> + <i18n.Translate>Sync all backups</i18n.Translate> : + <i18n.Translate>Sync now</i18n.Translate> }</button> - <button class="pure-button button-success" style={{ marginLeft: 5 }} onClick={onAddProvider}><i18n.Translate>add provider</i18n.Translate></button> + <button class="pure-button button-success" style={{ marginLeft: 5 }} onClick={onAddProvider}><i18n.Translate>Add provider</i18n.Translate></button> </div> - </footer> + </footer>} </div> </div> ) } interface TransactionLayoutProps { - status?: any; + status: any; timestamp?: Timestamp; title: string; - id: number; - subtitle?: string; - active?: boolean; + id: string; + active: boolean; } function BackupLayout(props: TransactionLayoutProps): JSX.Element { @@ -107,13 +107,12 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element { <div style={{ display: "flex", flexDirection: "column", color: !props.active ? "gray" : undefined }} > - - <div style={{ fontVariant: "small-caps", fontSize: "x-large" }}> - <a href={Pages.provider_detail.replace(':pid', String(props.id))}><span>{props.title}</span></a> + <div style={{ }}> + <a href={Pages.provider_detail.replace(':pid', encodeURIComponent(props.id))}><span>{props.title}</span></a> </div> - {dateStr && <div style={{ fontSize: "small" }}>Last time synced: {dateStr}</div>} - {!dateStr && <div style={{ fontSize: "small", color: "red" }}>never synced</div>} + {dateStr && <div style={{ fontSize: "small", marginTop: '0.5em' }}>Last synced: {dateStr}</div>} + {!dateStr && <div style={{ fontSize: "small", color: 'gray' }}>Not synced</div>} </div> <div style={{ marginLeft: "auto", @@ -122,16 +121,32 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element { alignItems: "center", alignSelf: "center" }}> - <div style={{ whiteSpace: 'nowrap' }}> - {!props.status ? "missing" : ( - props.status?.type === 'paid' ? daysUntil(props.status.paidUntil) : 'unpaid' - )} + <div style={{ display: 'flex', flexDirection: 'column' }}> + { + props.status?.type === 'paid' ? + <Fragment> + <div style={{ whiteSpace: 'nowrap', textAlign: 'center' }}> + Expires in + </div> + <div style={{ whiteSpace: 'nowrap', textAlign: 'center', fontWeight: 'bold', color: colorByTimeToExpire(props.status.paidUntil) }}> + {daysUntil(props.status.paidUntil)} + </div> + </Fragment> + : + 'unpaid' + } </div> </div> </div> ); } +function colorByTimeToExpire(d: Timestamp) { + if (d.t_ms === 'never') return 'rgb(28, 184, 65)' + const months = differenceInMonths(d.t_ms, new Date()) + return months > 1 ? 'rgb(28, 184, 65)' : 'rgb(223, 117, 20)'; +} + function daysUntil(d: Timestamp) { if (d.t_ms === 'never') return undefined const duration = intervalToDuration({ @@ -150,5 +165,5 @@ function daysUntil(d: Timestamp) { ) ] }) - return `${str} left` + return `${str}` }
\ No newline at end of file |