File: /home/u756937133/domains/swingersnest.com/public_html/resources/views/admin/backup/index.blade.php
@extends('layouts.admin')
@section('title', 'Backup - Admin Panel')
@section('content')
<div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<h1 class="text-3xl font-extrabold text-secondary">Backup Management</h1>
<div class="flex gap-3">
<button onclick="createFilesBackup()" class="inline-flex items-center gap-2 rounded-md bg-[#9810FA] px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-[#E60076]">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
Create Files Backup
</button>
<a href="{{ route('admin.backup.download.complete') }}" class="inline-flex items-center gap-2 rounded-md bg-green-600 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-green-700">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/>
</svg>
Download Complete Project
</a>
</div>
</div>
<div class="mb-6 rounded-lg border border-blue-200 bg-blue-50 p-4">
<h3 class="mb-2 text-sm font-semibold text-blue-800">Backup Options:</h3>
<ul class="list-inside list-disc space-y-1 text-sm text-blue-700">
<li><strong>Files Backup:</strong> Backs up storage files, media, and configuration</li>
<li><strong>Complete Project:</strong> Downloads entire project code + database + all files</li>
</ul>
@if(!extension_loaded('zip'))
<div class="mt-3 rounded-lg border border-red-300 bg-red-50 p-3">
<p class="text-sm font-semibold text-red-800">⚠️ ZipArchive Extension Required</p>
<p class="mt-1 text-xs text-red-700">
The PHP Zip extension is not enabled. Please enable it in your php.ini file by adding or uncommenting: <code class="bg-red-100 px-1 py-0.5 rounded">extension=zip</code>
</p>
</div>
@endif
</div>
@if(session('error'))
<div class="mb-4 rounded-lg bg-red-100 border border-red-400 text-red-700 px-4 py-3">
{{ session('error') }}
</div>
@endif
@if(session('success'))
<div class="mb-4 rounded-lg bg-green-100 border border-green-400 text-green-700 px-4 py-3">
{{ session('success') }}
</div>
@endif
@if(count($backups) > 0)
<div class="rounded-lg border border-gray-200 bg-white shadow-sm">
<div class="border-b border-gray-200 px-6 py-4">
<h2 class="text-lg font-semibold text-gray-900">Available Backups</h2>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Backup Name</th>
<th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Type</th>
<th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Size</th>
<th class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Created</th>
<th class="px-6 py-3 text-right text-xs font-medium uppercase tracking-wider text-gray-500">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
@foreach($backups as $backup)
<tr class="hover:bg-gray-50">
<td class="px-6 py-4">
<code class="rounded bg-gray-100 px-2 py-1 text-xs">{{ $backup['name'] }}</code>
</td>
<td class="whitespace-nowrap px-6 py-4">
<span class="inline-flex rounded-full px-2 text-xs font-semibold leading-5 {{ $backup['type'] === 'complete' ? 'bg-green-100 text-green-800' : 'bg-blue-100 text-blue-800' }}">
{{ $backup['type'] === 'complete' ? 'Complete Project' : 'Files Only' }}
</span>
</td>
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
{{ $backup['size'] }}
</td>
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
{{ $backup['created_at'] }}
</td>
<td class="whitespace-nowrap px-6 py-4 text-right text-sm font-medium">
<div class="flex items-center justify-end gap-2">
<a href="{{ route('admin.backup.download.files', $backup['name']) }}" class="text-blue-600 hover:text-blue-900">Download</a>
<button onclick="deleteBackup('{{ $backup['name'] }}')" class="text-red-600 hover:text-red-900">Delete</button>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@else
<div class="rounded-lg border border-gray-200 bg-white p-12 text-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="mx-auto h-16 w-16 text-gray-400">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
</svg>
<h3 class="mt-4 text-lg font-semibold text-gray-900">No backups found</h3>
<p class="mt-2 text-sm text-gray-500">Create your first backup to get started</p>
</div>
@endif
@endsection
@push('scripts')
<script>
function createFilesBackup() {
if (!confirm('Create files backup? This will backup storage files and media.')) {
return;
}
fetch('{{ route("admin.backup.files.create") }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
if (window.showToast) {
window.showToast('Files backup created successfully!', 'success');
}
setTimeout(() => location.reload(), 1000);
} else {
if (window.showToast) {
window.showToast('Error creating backup: ' + (data.message || 'Unknown error'), 'error');
}
}
})
.catch(error => {
console.error('Error:', error);
if (window.showToast) {
window.showToast('Error creating backup', 'error');
}
});
}
function deleteBackup(filename) {
if (!confirm('Are you sure you want to delete this backup? This action cannot be undone.')) {
return;
}
fetch(`/admin/backup/${filename}`, {
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
if (window.showToast) {
window.showToast('Backup deleted successfully!', 'success');
}
setTimeout(() => location.reload(), 1000);
} else {
if (window.showToast) {
window.showToast('Error deleting backup: ' + (data.message || 'Unknown error'), 'error');
}
}
})
.catch(error => {
console.error('Error:', error);
if (window.showToast) {
window.showToast('Error deleting backup', 'error');
}
});
}
</script>
@endpush