import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import logger from '../../utils/logger'; import { apiClient } from '../../services/api'; import { Database, Server, Activity, HardDrive, Users, FileText, Trash2, RefreshCw, Download, Upload, AlertTriangle, CheckCircle, XCircle, Info } from 'lucide-react'; import { Card, CardContent, Typography, Button, Box, CircularProgress } from '@mui/material'; interface DatabaseStats { collections: Array<{ name: string; documentCount: number; avgObjSize: number; totalSize: number; indexes: number; }>; totalSize: string; totalDocuments: number; totalCollections: number; totalIndexes: number; connectionInfo: { host: string; port: number; database: string; status: 'connected' | 'disconnected' | 'error'; }; } interface DatabaseOperation { id: string; type: 'backup' | 'restore' | 'cleanup' | 'reindex'; status: 'running' | 'completed' | 'failed'; startTime: string; endTime?: string; message?: string; progress?: number; } const DatabaseManagementPage: React.FC = () => { const { t } = useTranslation(); const [stats, setStats] = useState(null); const [operations, setOperations] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedCollection, setSelectedCollection] = useState(null); const [showBackupDialog, setShowBackupDialog] = useState(false); const [showCleanupDialog, setShowCleanupDialog] = useState(false); const [showReindexDialog, setShowReindexDialog] = useState(false); const [operationLoading, setOperationLoading] = useState(null); useEffect(() => { fetchDatabaseStats(); fetchOperations(); // Refresh every 30 seconds const interval = setInterval(() => { fetchDatabaseStats(); fetchOperations(); }, 30000); return () => clearInterval(interval); }, []); const fetchDatabaseStats = async () => { try { setLoading(true); const response = await apiClient.get('/admin/database/stats'); setStats(response.data); setError(null); } catch (err: any) { setError(err.response?.data?.message || t('databaseManagement.errors.loadStats')); } finally { setLoading(false); } }; const fetchOperations = async () => { try { const response = await apiClient.get('/admin/database/operations'); setOperations(response.data); } catch (err: any) { logger.error(t('databaseManagement.errors.loadOperations'), err); } }; const handleBackup = async () => { try { await apiClient.post('/admin/database/backup'); setShowBackupDialog(false); fetchOperations(); } catch (err: any) { setError(err.response?.data?.message || t('databaseManagement.errors.backup')); } }; const handleCleanup = async (collection?: string) => { try { await apiClient.post('/admin/database/cleanup', { collection }); setShowCleanupDialog(false); fetchDatabaseStats(); fetchOperations(); } catch (err: any) { setError(err.response?.data?.message || t('databaseManagement.errors.cleanup')); } }; const handleReindex = async (collection?: string) => { try { await apiClient.post('/admin/database/reindex', { collection }); fetchOperations(); } catch (err: any) { setError(err.response?.data?.message || t('databaseManagement.errors.reindex')); } }; const formatBytes = (bytes: number) => { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', '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]; }; const getStatusIcon = (status: string) => { switch (status) { case 'connected': case 'completed': return ; case 'running': return ; case 'failed': case 'error': case 'disconnected': return ; default: return ; } }; if (loading) { return (
); } if (error) { return (
{error}
); } return (

{t('databaseManagement.header.title')}

{/* Connection Status */} {stats && (

{t('databaseManagement.connection.title')}

{stats.connectionInfo.host}:{stats.connectionInfo.port}/{stats.connectionInfo.database}

{getStatusIcon(stats.connectionInfo.status)} {stats.connectionInfo.status === 'connected' ? t('databaseManagement.connection.status.connected') : stats.connectionInfo.status === 'disconnected' ? t('databaseManagement.connection.status.disconnected') : t('databaseManagement.connection.status.error')}
)} {/* Database Statistics */}
{t('databaseManagement.stats.totalCollections')}
{stats?.totalCollections || 0}
{t('databaseManagement.stats.totalDocuments')}
{stats?.totalDocuments.toLocaleString() || 0}
{t('databaseManagement.stats.dbSize')}
{stats?.totalSize || '0 MB'}
{t('databaseManagement.stats.totalIndexes')}
{stats?.totalIndexes || 0}
{/* Database Operations */} {t('databaseManagement.operations.title')} {t('databaseManagement.operations.subtitle')}
{/* Collections Table */} {stats && (

{t('databaseManagement.collections.title')}

{stats.collections.map((collection) => ( ))}
{t('databaseManagement.collections.columns.name')} {t('databaseManagement.collections.columns.documents')} {t('databaseManagement.collections.columns.avgSize')} {t('databaseManagement.collections.columns.totalSize')} {t('databaseManagement.collections.columns.indexes')} {t('databaseManagement.collections.columns.actions')}
{collection.name} {collection.documentCount.toLocaleString()} {formatBytes(collection.avgObjSize)} {formatBytes(collection.totalSize)} {collection.indexes}
)} {/* Recent Operations */}

{t('databaseManagement.recent.title')}

{operations.map((operation) => ( ))}
{t('databaseManagement.recent.columns.type')} {t('databaseManagement.recent.columns.status')} {t('databaseManagement.recent.columns.start')} {t('databaseManagement.recent.columns.end')} {t('databaseManagement.recent.columns.message')}
{operation.type}
{getStatusIcon(operation.status)} {t(`databaseManagement.connection.status.${operation.status}`)}
{new Date(operation.startTime).toLocaleString()} {operation.endTime ? new Date(operation.endTime).toLocaleString() : '-'} {operation.message || '-'}
{/* Backup Dialog */} {showBackupDialog && (

{t('databaseManagement.dialogs.backup.title')}

{t('databaseManagement.dialogs.backup.message')}

)} {/* Cleanup Dialog */} {showCleanupDialog && (

{t('databaseManagement.dialogs.cleanup.title')}

{t('databaseManagement.dialogs.cleanup.message', { target: selectedCollection ? t('databaseManagement.dialogs.cleanup.collection', { name: selectedCollection }) : t('databaseManagement.dialogs.cleanup.allDatabase') })}

)}
); }; export default DatabaseManagementPage;