/* 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, ProviderPaymentStatus, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; import { ContractTermsUtil } from "@gnu-taler/taler-wallet-core/src/util/contractTerms"; import { formatDuration, intervalToDuration, format } from "date-fns"; import { Fragment, VNode } from "preact"; import { useRef, useState } from "preact/hooks"; import { useBackupStatus } from "../hooks/useBackupStatus"; import { useProviderStatus } from "../hooks/useProviderStatus.js"; import * as wxApi from "../wxApi"; interface Props { pid: string; onBack: () => void; } export function ProviderDetailPage({ pid, onBack }: Props): VNode { const status = useProviderStatus(pid) if (!status) { return
Loading...
} if (!status.info) { onBack() return
} return { null }} onBack={onBack} onExtend={() => { null }} />; } export interface ViewProps { info: ProviderInfo; onDelete: () => void; onSync: () => void; onBack: () => void; onExtend: () => void; } export function ProviderView({ info, onDelete, onSync, onBack, onExtend }: ViewProps): VNode { function Footer() { return
{info && } {info && } {info && }
} function Error() { if (info?.lastError) { return
last time tried {!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 conflict with another backup from {info.backupProblem.otherDeviceId}

case "backup-unreadable": return

Backup is not readable

default: return

Unknown 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 } function descriptionByStatus(status: ProviderPaymentStatus | undefined) { if (!status) return '' switch (status.type) { case ProviderPaymentType.InsufficientBalance: return 'no enough balance to make the payment' case ProviderPaymentType.Unpaid: return 'not pay yet' case ProviderPaymentType.Paid: case ProviderPaymentType.TermsChanged: if (status.paidUntil.t_ms === 'never') { return 'service paid.' } else { return `service paid until ${format(status.paidUntil.t_ms, 'yyyy/MM/dd HH:mm:ss')}` } case ProviderPaymentType.Pending: return '' default: break; } return undefined } return (
{info?.paymentStatus.type} {/* {info && From {info.syncProviderBaseUrl} } */} {info &&
{info.terms?.annualFee} / year
}

{info?.syncProviderBaseUrl}

{daysSince(info?.lastSuccessfulBackupTimestamp)}

{descriptionByStatus(info?.paymentStatus)}

{info?.paymentStatus.type === ProviderPaymentType.TermsChanged &&

terms has changed, extending the service will imply accepting the new terms of service

old -> new
fee {info.paymentStatus.oldTerms.annualFee} -> {info.paymentStatus.newTerms.annualFee}
storage {info.paymentStatus.oldTerms.storageLimitInMegabytes} -> {info.paymentStatus.newTerms.storageLimitInMegabytes}
}
) } 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` }