feat: add restore functionality to backup manager

This commit is contained in:
Erik
2025-11-29 12:37:34 -03:00
parent bf95f067bc
commit ae8639bb2f
4 changed files with 209 additions and 48 deletions

View File

@@ -21,6 +21,7 @@ interface BackupsListResponse {
export function BackupManager() {
const [loading, setLoading] = useState(false);
const [restoreLoading, setRestoreLoading] = useState<string | null>(null);
const [backups, setBackups] = useState<BackupInfo[]>([]);
const [listLoading, setListLoading] = useState(true);
const { success, error: showError } = useToast();
@@ -33,12 +34,9 @@ export function BackupManager() {
const fetchBackups = async () => {
try {
setListLoading(true);
const token = localStorage.getItem('auth_token') || '';
const response = await fetch('/api/backup', {
headers: {
'Authorization': `Bearer ${token}`
}
method: 'GET'
});
if (response.ok) {
@@ -57,12 +55,10 @@ export function BackupManager() {
const createBackup = async () => {
try {
setLoading(true);
const token = localStorage.getItem('auth_token') || '';
const response = await fetch('/api/backup', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
@@ -90,13 +86,8 @@ export function BackupManager() {
}
try {
const token = localStorage.getItem('auth_token') || '';
const response = await fetch(`/api/backup?id=${backupId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
method: 'DELETE'
});
const data = await response.json();
@@ -114,13 +105,7 @@ export function BackupManager() {
const downloadBackup = async (filename: string) => {
try {
const token = localStorage.getItem('auth_token') || '';
const response = await fetch(`/api/backup/download?file=${filename}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
const response = await fetch(`/api/backup/download?file=${filename}`);
if (response.ok) {
const blob = await response.blob();
@@ -140,6 +125,32 @@ export function BackupManager() {
}
};
const restoreBackup = async (filename: string) => {
if (!window.confirm('⚠️ AVISO: A restauração substituirá todo o banco de dados!\n\nTem certeza que deseja restaurar este backup?')) {
return;
}
try {
setRestoreLoading(filename);
const response = await fetch(`/api/backup/restore?file=${filename}`, {
method: 'POST'
});
const data = await response.json();
if (response.ok) {
success('Backup restaurado com sucesso! Por favor, recarregue a página.');
} else {
showError(data.error || 'Erro ao restaurar backup');
}
} catch (err) {
showError('Erro ao restaurar backup: ' + (err as Error).message);
} finally {
setRestoreLoading(null);
}
};
const formatSize = (bytes: number) => {
if (bytes === 0) return '0 B';
const k = 1024;
@@ -236,6 +247,18 @@ export function BackupManager() {
</div>
<div className="flex items-center gap-2 shrink-0">
<button
onClick={() => restoreBackup(backup.filename)}
disabled={restoreLoading === backup.filename}
title="Restaurar backup"
className="p-2 hover:bg-amber-100 dark:hover:bg-amber-900/20 rounded-lg transition-colors text-amber-600 dark:text-amber-400 disabled:opacity-50 disabled:cursor-not-allowed"
>
{restoreLoading === backup.filename ? (
<i className="ri-loader-4-line animate-spin text-xl"></i>
) : (
<i className="ri-restart-line text-xl"></i>
)}
</button>
<button
onClick={() => downloadBackup(backup.filename)}
title="Baixar backup"