156 lines
8.3 KiB
TypeScript
156 lines
8.3 KiB
TypeScript
|
|
import React, { useState } from 'react';
|
|
import { Card } from '../../ui/card';
|
|
import { Button } from '../../ui/button';
|
|
import { Backup } from '../../../types';
|
|
import { Database, Clock, Download, RefreshCcw, CheckCircle, AlertTriangle, HardDrive } from 'lucide-react';
|
|
import { useToast } from '../../../context/ToastContext';
|
|
|
|
const MOCK_BACKUPS: Backup[] = [
|
|
{ id: 'b1', date: '2023-10-25 04:00 AM', type: 'Full', size: '4.2 GB', status: 'Success', location: 'Cloud' },
|
|
{ id: 'b2', date: '2023-10-24 04:00 AM', type: 'Incremental', size: '120 MB', status: 'Success', location: 'Cloud' },
|
|
{ id: 'b3', date: '2023-10-23 04:00 AM', type: 'Incremental', size: '450 MB', status: 'Failed', location: 'Cloud' },
|
|
];
|
|
|
|
export const BackupsView: React.FC = () => {
|
|
const { addToast } = useToast();
|
|
const [backups, setBackups] = useState<Backup[]>(MOCK_BACKUPS);
|
|
const [autoBackup, setAutoBackup] = useState(true);
|
|
|
|
const handleCreateBackup = () => {
|
|
addToast("Backup process started...", "info");
|
|
setTimeout(() => {
|
|
const newBackup: Backup = {
|
|
id: `b-${Date.now()}`,
|
|
date: 'Just now',
|
|
type: 'Full',
|
|
size: '1.5 GB',
|
|
status: 'Success',
|
|
location: 'Cloud'
|
|
};
|
|
setBackups([newBackup, ...backups]);
|
|
addToast("Backup completed successfully", "success");
|
|
}, 2000);
|
|
};
|
|
|
|
const handleRestore = (id: string) => {
|
|
addToast(`Restoring from backup ${id}...`, "info");
|
|
};
|
|
|
|
return (
|
|
<div className="max-w-5xl mx-auto space-y-8 animate-fadeIn">
|
|
|
|
{/* Header Actions */}
|
|
<div className="flex flex-col md:flex-row justify-between items-end gap-4">
|
|
<div>
|
|
<h2 className="text-2xl font-bold text-white flex items-center gap-2">
|
|
<Database className="w-6 h-6 text-kodo-gold" /> System Backups
|
|
</h2>
|
|
<p className="text-gray-400 text-sm">Manage restore points and redundancy.</p>
|
|
</div>
|
|
<Button variant="primary" icon={<HardDrive className="w-4 h-4" />} onClick={handleCreateBackup}>
|
|
CREATE BACKUP NOW
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
|
|
{/* List */}
|
|
<div className="lg:col-span-2 space-y-4">
|
|
<Card variant="default">
|
|
<h3 className="font-bold text-white mb-4">Recent Backups</h3>
|
|
<div className="space-y-2">
|
|
{backups.map(backup => (
|
|
<div key={backup.id} className="flex flex-col md:flex-row items-center justify-between p-4 bg-kodo-ink rounded-lg border border-kodo-steel hover:border-kodo-cyan/30 transition-all">
|
|
<div className="flex items-center gap-4 mb-2 md:mb-0 w-full md:w-auto">
|
|
<div className={`p-2 rounded-full ${backup.status === 'Success' ? 'bg-kodo-lime/10 text-kodo-lime' : 'bg-kodo-red/10 text-kodo-red'}`}>
|
|
{backup.status === 'Success' ? <CheckCircle className="w-5 h-5" /> : <AlertTriangle className="w-5 h-5" />}
|
|
</div>
|
|
<div>
|
|
<div className="font-bold text-white text-sm">{backup.date}</div>
|
|
<div className="text-xs text-gray-400 flex gap-2">
|
|
<span>{backup.type}</span>
|
|
<span>•</span>
|
|
<span>{backup.size}</span>
|
|
<span>•</span>
|
|
<span>{backup.location}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex gap-2 w-full md:w-auto">
|
|
<Button variant="ghost" size="sm" className="flex-1 md:flex-none border border-kodo-steel" onClick={() => handleRestore(backup.id)}>
|
|
<RefreshCcw className="w-4 h-4 mr-2" /> Restore
|
|
</Button>
|
|
<Button variant="ghost" size="sm" className="flex-1 md:flex-none border border-kodo-steel">
|
|
<Download className="w-4 h-4" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* Scheduling Sidebar */}
|
|
<div className="space-y-6">
|
|
<Card variant="gaming">
|
|
<h3 className="font-bold text-white mb-4 flex items-center gap-2 text-sm uppercase tracking-wider">
|
|
<Clock className="w-4 h-4 text-kodo-cyan" /> Schedule
|
|
</h3>
|
|
|
|
<div className="space-y-4">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<div className="text-sm text-white font-bold">Auto-Backup</div>
|
|
<div className="text-xs text-gray-400">Daily incremental backups</div>
|
|
</div>
|
|
<div
|
|
onClick={() => setAutoBackup(!autoBackup)}
|
|
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${autoBackup ? 'bg-kodo-cyan' : 'bg-gray-600'}`}
|
|
>
|
|
<div className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${autoBackup ? 'left-6' : 'left-1'}`}></div>
|
|
</div>
|
|
</div>
|
|
|
|
{autoBackup && (
|
|
<div className="animate-fadeIn space-y-3 pt-2 border-t border-gray-700">
|
|
<div>
|
|
<label className="block text-xs font-bold text-gray-400 uppercase mb-1">Frequency</label>
|
|
<select className="w-full bg-kodo-void border border-kodo-steel rounded p-2 text-white text-sm">
|
|
<option>Daily</option>
|
|
<option>Weekly</option>
|
|
<option>Monthly</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="block text-xs font-bold text-gray-400 uppercase mb-1">Time</label>
|
|
<input type="time" className="w-full bg-kodo-void border border-kodo-steel rounded p-2 text-white text-sm" defaultValue="04:00" />
|
|
</div>
|
|
<div>
|
|
<label className="block text-xs font-bold text-gray-400 uppercase mb-1">Retention</label>
|
|
<select className="w-full bg-kodo-void border border-kodo-steel rounded p-2 text-white text-sm">
|
|
<option>Keep last 7 days</option>
|
|
<option>Keep last 30 days</option>
|
|
<option>Keep forever</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
|
|
<div className="bg-kodo-orange/10 border border-kodo-orange/30 p-4 rounded-xl flex gap-3">
|
|
<AlertTriangle className="w-6 h-6 text-kodo-orange flex-shrink-0" />
|
|
<div>
|
|
<h4 className="font-bold text-kodo-orange text-sm mb-1">Disaster Recovery</h4>
|
|
<p className="text-xs text-gray-300">
|
|
Off-site cold storage is available for Enterprise plans. <a href="#" className="underline">Learn more</a>.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|