Django_Basic_Manufacturing/templates/core/database_management.html
2025-08-17 21:42:40 +07:00

250 lines
10 KiB
HTML

{% extends 'base.html' %}
{% block title %}Database Management - Manufacturing App{% endblock %}
{% block content %}
<div class="container-fluid">
<!-- Page header -->
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="bi bi-database me-2"></i>
Database Management
</h1>
</div>
<div class="row">
<!-- Database Information -->
<div class="col-lg-4 mb-4">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-primary">
<i class="bi bi-info-circle me-2"></i>
Database Information
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<strong>Database Engine:</strong>
<span class="badge bg-primary ms-2">SQLite</span>
</div>
<div class="mb-3">
<strong>Database File:</strong>
<code class="ms-2">db.sqlite3</code>
</div>
<div class="mb-3">
<strong>Location:</strong>
<code class="ms-2">Project Root</code>
</div>
<div class="mb-3">
<strong>Size:</strong>
<span class="ms-2">{{ db_size|default:"Calculating..." }}</span>
</div>
<div class="mb-3">
<strong>Last Modified:</strong>
<span class="ms-2">{{ db_modified|default:"Unknown" }}</span>
</div>
</div>
</div>
</div>
<!-- Backup Database -->
<div class="col-lg-4 mb-4">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-success">
<i class="bi bi-download me-2"></i>
Backup Database
</h6>
</div>
<div class="card-body">
<p class="text-muted">
Create a backup of the current database. The backup will be saved in the 'backups' folder.
</p>
<form method="post" action="{% url 'core:backup_database' %}">
{% csrf_token %}
<button type="submit" class="btn btn-success w-100">
<i class="bi bi-download me-2"></i>
Create Backup
</button>
</form>
<small class="text-muted">
Backup files are saved with timestamps for easy identification.
</small>
</div>
</div>
</div>
<!-- Duplicate Database -->
<div class="col-lg-4 mb-4">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-info">
<i class="bi bi-files me-2"></i>
Duplicate Database
</h6>
</div>
<div class="card-body">
<p class="text-muted">
Create a duplicate copy of the current database for testing or development purposes.
</p>
<form method="post" action="{% url 'core:duplicate_database' %}">
{% csrf_token %}
<button type="submit" class="btn btn-info w-100">
<i class="bi bi-files me-2"></i>
Duplicate Database
</button>
</form>
<small class="text-muted">
Duplicate files are saved in the 'backups' folder.
</small>
</div>
</div>
</div>
</div>
<!-- Restore Database -->
<div class="row">
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-warning">
<i class="bi bi-upload me-2"></i>
Restore Database
</h6>
</div>
<div class="card-body">
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>Warning:</strong> Restoring a database will overwrite the current database.
A safety backup of the current database will be created automatically before restoration.
</div>
<form method="post" action="{% url 'core:restore_database' %}" enctype="multipart/form-data">
{% csrf_token %}
<div class="mb-3">
<label for="backup_file" class="form-label">Select Backup File</label>
<input type="file" class="form-control" id="backup_file" name="backup_file"
accept=".sqlite3,.db" required>
<div class="form-text">
Only SQLite database files (.sqlite3, .db) are supported.
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="confirm_restore" required>
<label class="form-check-label" for="confirm_restore">
I understand that this will overwrite the current database
</label>
</div>
</div>
<button type="submit" class="btn btn-warning" id="restore_btn" disabled>
<i class="bi bi-upload me-2"></i>
Restore Database
</button>
</form>
</div>
</div>
</div>
<!-- Available Backups -->
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-primary">
<i class="bi bi-folder me-2"></i>
Available Backups
</h6>
</div>
<div class="card-body">
{% if available_backups %}
<div class="list-group list-group-flush">
{% for backup in available_backups %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<div>
<small class="text-muted">{{ backup.name }}</small>
<br>
<small class="text-muted">{{ backup.size }}</small>
</div>
<small class="text-muted">{{ backup.modified }}</small>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-muted">No backup files found.</p>
{% endif %}
<div class="mt-3">
<a href="#" class="btn btn-outline-primary btn-sm w-100">
<i class="bi bi-folder-open me-2"></i>
Open Backups Folder
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Database Statistics -->
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-primary">
<i class="bi bi-bar-chart me-2"></i>
Database Statistics
</h6>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-md-3 mb-3">
<h4 class="text-primary">{{ total_users|default:"0" }}</h4>
<p class="text-muted">Total Users</p>
</div>
<div class="col-md-3 mb-3">
<h4 class="text-success">{{ total_products|default:"0" }}</h4>
<p class="text-muted">Total Products</p>
</div>
<div class="col-md-3 mb-3">
<h4 class="text-info">{{ total_orders|default:"0" }}</h4>
<p class="text-muted">Total Orders</p>
</div>
<div class="col-md-3 mb-3">
<h4 class="text-warning">{{ total_customers|default:"0" }}</h4>
<p class="text-muted">Total Customers</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Enable/disable restore button based on checkbox
document.getElementById('confirm_restore').addEventListener('change', function() {
document.getElementById('restore_btn').disabled = !this.checked;
});
// File input validation
document.getElementById('backup_file').addEventListener('change', function() {
const file = this.files[0];
if (file) {
const allowedTypes = ['application/x-sqlite3', 'application/vnd.sqlite3', 'application/octet-stream'];
const allowedExtensions = ['.sqlite3', '.db'];
const isValidType = allowedTypes.includes(file.type) ||
allowedExtensions.some(ext => file.name.toLowerCase().endsWith(ext));
if (!isValidType) {
alert('Please select a valid SQLite database file (.sqlite3 or .db)');
this.value = '';
}
}
});
</script>
{% endblock %}