import React from 'react'; import { HardDrive, Database, FileArchive, Image, Clock, CheckCircle, AlertCircle, TrendingUp, Shield, Server, Cloud, Calendar, Play, Loader2, AlertTriangle, Info } from 'lucide-react'; import { format, formatDistanceToNow } from 'date-fns'; import { Card, Button } from '../common'; const StatCard = ({ icon: Icon, label, value, color = 'blue', subtext }) => (

{label}

{value}

{subtext && (

{subtext}

)}
); const formatBytes = (bytes) => { if (!bytes) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`; }; export const BackupDashboard = ({ status, config, onRunBackup, isBackupRunning }) => { const lastBackup = status?.lastBackup; const statistics = lastBackup?.statistics || {}; const isConfigured = config && config.backup_destination_type; const isEnabled = config?.backup_enabled; // Calculate backup health score const getHealthScore = () => { if (!lastBackup) return { score: 0, status: 'critical', message: 'No backups found' }; const hoursSinceBackup = (Date.now() - new Date(lastBackup.created_at)) / (1000 * 60 * 60); if (lastBackup.status === 'failed') { return { score: 0, status: 'critical', message: 'Last backup failed' }; } if (hoursSinceBackup < 24) { return { score: 100, status: 'excellent', message: 'Backup is up to date' }; } else if (hoursSinceBackup < 48) { return { score: 75, status: 'good', message: 'Backup is recent' }; } else if (hoursSinceBackup < 168) { // 1 week return { score: 50, status: 'warning', message: 'Backup is getting old' }; } else { return { score: 25, status: 'critical', message: 'Backup is outdated' }; } }; const health = getHealthScore(); const healthColors = { excellent: 'green', good: 'blue', warning: 'amber', critical: 'red' }; return (
{/* Configuration Alert */} {!isConfigured && (

Backup Not Configured

Please configure backup settings in the Configuration tab before running backups.

)} {/* Health Score Card */}

Backup Health

{health.status.charAt(0).toUpperCase() + health.status.slice(1)}
{health.score}%

{health.message}

{lastBackup && (

Last successful backup: {formatDistanceToNow(new Date(lastBackup.created_at), { addSuffix: true })}

)}
{/* Statistics Grid */}
{/* Recent Activity */} {status?.recentBackups && status.recentBackups.length > 0 && (

Recent Backup Activity

{status.recentBackups.slice(0, 5).map((backup) => (
{backup.status === 'completed' ? ( ) : backup.status === 'failed' ? ( ) : ( )}

{backup.backup_type} backup

{format(new Date(backup.created_at), 'PPp')}

{formatBytes(backup.statistics?.total_size || 0)}

{backup.statistics?.files_processed || 0} files

))}
)} {/* Storage Status */}

Backup Coverage

Database
{statistics.database_backed_up ? 'Backed up' : 'Not backed up'}
Photos
{statistics.photos_backed_up || 0} of {statistics.total_photos || 0}
Archives
{statistics.archives_backed_up || 0} files

Destination Info

{config?.backup_destination_type === 's3' ? ( ) : config?.backup_destination_type === 'rsync' ? ( ) : ( )}

{config?.backup_destination_type ? config.backup_destination_type.toUpperCase() : 'Not Configured'}

{config?.backup_destination_type === 's3' && config?.backup_s3_bucket ? `Bucket: ${config.backup_s3_bucket}` : config?.backup_destination_type === 'local' && config?.backup_destination_path ? `Path: ${config.backup_destination_path}` : config?.backup_destination_type === 'rsync' && config?.backup_rsync_host ? `Host: ${config.backup_rsync_host}` : 'No destination set'}

{config?.backup_retention_days && (
Backups retained for {config.backup_retention_days} days
)}
); };