'use client' import { useState, useEffect } from 'react' // import { useTranslations } from 'next-intl' import { Box, Card, CardContent, Typography, Button, LinearProgress, List, ListItem, ListItemText, ListItemSecondaryAction, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Chip, Alert, Tooltip } from '@mui/material' import { Download, Delete, CloudDownload, Storage, Wifi, WifiOff, CheckCircle, Error, Info } from '@mui/icons-material' import { bibleDownloadManager, type BibleVersion, type DownloadProgress } from '@/lib/offline-storage' interface OfflineDownloadManagerProps { availableVersions: BibleVersion[] onVersionDownloaded?: (versionId: string) => void } export function OfflineDownloadManager({ availableVersions, onVersionDownloaded }: OfflineDownloadManagerProps) { // const t = useTranslations('bible') const [downloadedVersions, setDownloadedVersions] = useState([]) const [downloads, setDownloads] = useState>({}) const [storageInfo, setStorageInfo] = useState({ used: 0, quota: 0, percentage: 0 }) const [isOnline, setIsOnline] = useState(true) const [confirmDelete, setConfirmDelete] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { loadDownloadedVersions() loadStorageInfo() checkOnlineStatus() // Listen for online/offline events const handleOnline = () => setIsOnline(true) const handleOffline = () => setIsOnline(false) window.addEventListener('online', handleOnline) window.addEventListener('offline', handleOffline) return () => { window.removeEventListener('online', handleOnline) window.removeEventListener('offline', handleOffline) } }, []) const loadDownloadedVersions = async () => { try { const versions = await bibleDownloadManager.getDownloadedVersions() setDownloadedVersions(versions) } catch (error: unknown) { console.error('Failed to load downloaded versions:', error) } finally { setLoading(false) } } const loadStorageInfo = async () => { try { const info = await bibleDownloadManager.getStorageInfo() setStorageInfo(info) } catch (error: unknown) { console.error('Failed to load storage info:', error) } } const checkOnlineStatus = () => { setIsOnline(navigator.onLine) } const handleDownload = async (version: BibleVersion) => { if (!isOnline) { alert('You need an internet connection to download Bible versions') return } try { await bibleDownloadManager.downloadVersion( version.id, (progress: DownloadProgress) => { setDownloads(prev => ({ ...prev, [version.id]: progress })) if (progress.status === 'completed') { loadDownloadedVersions() loadStorageInfo() onVersionDownloaded?.(version.id) // Remove from downloads state after completion setTimeout(() => { setDownloads(prev => { const { [version.id]: _, ...rest } = prev return rest }) }, 3000) } } ) } catch (error: unknown) { console.error('Download failed:', error) const errorMessage = 'Download failed' alert(errorMessage) } } const handleDelete = async (versionId: string) => { try { await bibleDownloadManager.deleteVersion(versionId) setDownloadedVersions(prev => prev.filter(v => v.id !== versionId)) loadStorageInfo() setConfirmDelete(null) } catch (error: unknown) { console.error('Delete failed:', error) alert('Failed to delete version') } } const formatBytes = (bytes: number): string => { if (bytes === 0) return '0 Bytes' const k = 1024 const sizes = ['Bytes', 'KB', 'MB', 'GB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] } const getStatusIcon = (status: string) => { switch (status) { case 'completed': return case 'failed': return case 'downloading': return default: return } } const isVersionDownloaded = (versionId: string) => { return downloadedVersions.some(v => v.id === versionId) } const isVersionDownloading = (versionId: string) => { return downloads[versionId]?.status === 'downloading' } if (loading) { return ( Loading offline storage... ) } return ( {/* Header */} Offline Bible Storage : } label={isOnline ? 'Online' : 'Offline'} color={isOnline ? 'success' : 'error'} size="small" /> {/* Storage Info */} Storage Usage {storageInfo.percentage.toFixed(1)}% {formatBytes(storageInfo.used)} of {formatBytes(storageInfo.quota)} used {downloadedVersions.length} Bible versions downloaded {/* Available Versions for Download */} {isOnline && ( Available for Download {availableVersions .filter(version => !isVersionDownloaded(version.id)) .map((version) => ( ))} {availableVersions.filter(v => !isVersionDownloaded(v.id)).length === 0 && ( All available versions are already downloaded )} )} {/* Active Downloads */} {Object.keys(downloads).length > 0 && ( Downloads in Progress {Object.entries(downloads).map(([versionId, progress]) => { const version = availableVersions.find(v => v.id === versionId) return ( {getStatusIcon(progress.status)} {version?.name || versionId} } secondary={ {progress.downloadedChapters} / {progress.totalChapters} chapters ({progress.progress}%) } /> ) })} )} {/* Downloaded Versions */} Downloaded Versions {downloadedVersions.length === 0 ? ( No Bible versions downloaded yet. Download versions above to read offline. ) : ( {downloadedVersions.map((version) => ( {version.abbreviation} - {version.language} {version.downloadedAt && ( Downloaded: {new Date(version.downloadedAt).toLocaleDateString()} )} } /> setConfirmDelete(version.id)} color="error" size="small" > ))} )} {/* Delete Confirmation Dialog */} setConfirmDelete(null)} > Delete Bible Version Are you sure you want to delete this Bible version from offline storage? You'll need to download it again to read offline. ) }