/* 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, ProviderPaymentStatus, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; import { format, formatDuration, intervalToDuration } from "date-fns"; import { Fragment, VNode } from "preact"; import { ErrorMessage } from "../components/ErrorMessage"; import { Button, ButtonDestructive, ButtonPrimary, PaymentStatus, PopupBox, SmallTextLight } from "../components/styled"; import { useProviderStatus } from "../hooks/useProviderStatus"; 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 status.remove().then(onBack) } 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 { return (
{info.paymentStatus.type} {info.terms &&
{info.terms.annualFee} / year
}

{info.name} {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}
}
remove extend sync now
) } 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` } function Error({ info }: { info: ProviderInfo }) { if (info.lastError) { return } 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 default: return Unknown backup problem: {JSON.stringify(info.backupProblem)} } /> } } return null } function colorByStatus(status: ProviderPaymentType) { 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)' } } function descriptionByStatus(status: ProviderPaymentStatus) { switch (status.type) { case ProviderPaymentType.InsufficientBalance: return 'no enough balance to make the payment' case ProviderPaymentType.Unpaid: return 'not paid 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 '' } }