// Copyright 2025 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; import type { BackupsSubscriptionType, BackupStatusType, } from '../types/backups'; import type { LocalizerType } from '../types/I18N'; import { formatTimestamp } from '../util/formatTimestamp'; import { formatFileSize } from '../util/formatFileSize'; import { SettingsRow } from './PreferencesUtil'; import { missingCaseError } from '../util/missingCaseError'; export function PreferencesBackups({ cloudBackupStatus, backupSubscriptionStatus, i18n, locale, }: { cloudBackupStatus?: BackupStatusType; backupSubscriptionStatus?: BackupsSubscriptionType; i18n: LocalizerType; locale: string; }): JSX.Element { return ( <>
{getBackupsSubscriptionSummary({ subscriptionStatus: backupSubscriptionStatus, i18n, locale, })}
{cloudBackupStatus ? ( {cloudBackupStatus.createdAt ? (
{/* TODO (DESKTOP-8509) */} {i18n('icu:Preferences--backup-created-by-phone')} {formatTimestamp(cloudBackupStatus.createdAt, { dateStyle: 'medium', timeStyle: 'short', })}
) : null} {cloudBackupStatus.mediaSize != null || cloudBackupStatus.protoSize != null}
) : null} ); } function getSubscriptionDetails({ i18n, subscriptionStatus, locale, }: { i18n: LocalizerType; locale: string; subscriptionStatus: BackupsSubscriptionType; }): JSX.Element | null { if (subscriptionStatus.status === 'active') { return ( <> {subscriptionStatus.cost ? (
{new Intl.NumberFormat(locale, { style: 'currency', currency: subscriptionStatus.cost.currencyCode, currencyDisplay: 'narrowSymbol', }).format(subscriptionStatus.cost.amount)}{' '} / month
) : null} {subscriptionStatus.renewalDate ? (
{i18n('icu:Preferences--backup-plan__renewal-date', { date: formatTimestamp(subscriptionStatus.renewalDate.getTime(), { dateStyle: 'medium', }), })}
) : null} ); } if (subscriptionStatus.status === 'pending-cancellation') { return ( <>
{i18n('icu:Preferences--backup-plan__canceled')}
{subscriptionStatus.expiryDate ? (
{i18n('icu:Preferences--backup-plan__expiry-date', { date: formatTimestamp(subscriptionStatus.expiryDate.getTime(), { dateStyle: 'medium', }), })}
) : null} ); } return null; } export function getBackupsSubscriptionSummary({ subscriptionStatus, i18n, locale, }: { locale: string; subscriptionStatus?: BackupsSubscriptionType; i18n: LocalizerType; }): JSX.Element | null { if (!subscriptionStatus) { return null; } const { status } = subscriptionStatus; switch (status) { case 'active': case 'pending-cancellation': return ( <>
{i18n('icu:Preferences--backup-media-plan__description')}
{getSubscriptionDetails({ i18n, locale, subscriptionStatus })}
{subscriptionStatus.status === 'active' ? (
) : (
)}
{i18n('icu:Preferences--backup-media-plan__note')}
); case 'free': return ( <>
{i18n('icu:Preferences--backup-messages-plan__description', { mediaDayCount: subscriptionStatus.mediaIncludedInBackupDurationDays, })}
{i18n( 'icu:Preferences--backup-messages-plan__cost-description' )}
{i18n('icu:Preferences--backup-messages-plan__note')}
); case 'not-found': case 'expired': return ( <>
{i18n('icu:Preferences--backup-plan-not-found__description')}
{i18n('icu:Preferences--backup-plan__not-found__note')}
); default: throw missingCaseError(status); } }