216 lines
8.9 KiB
HTML
216 lines
8.9 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>
|
|
|
|
</div>
|
|
|
|
<!-- Change Password -->
|
|
<div class="row mt-4">
|
|
<div class="col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="m-0 font-weight-bold text-info">
|
|
<i class="bi bi-key me-2"></i>
|
|
Change Password
|
|
</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="alert alert-info">
|
|
<i class="bi bi-info-circle me-2"></i>
|
|
<strong>Info:</strong> Change the password for any user account in the system.
|
|
</div>
|
|
|
|
<form method="post" action="{% url 'core:change_password' %}">
|
|
{% csrf_token %}
|
|
<div class="mb-3">
|
|
<label for="username" class="form-label">Username</label>
|
|
<input type="text" class="form-control" id="username" name="username" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="new_password" class="form-label">New Password</label>
|
|
<input type="password" class="form-control" id="new_password" name="new_password" required>
|
|
<div class="form-text">
|
|
Password must be at least 8 characters long.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="confirm_password" class="form-label">Confirm New Password</label>
|
|
<input type="password" class="form-control" id="confirm_password" name="confirm_password" required>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-info">
|
|
<i class="bi bi-key me-2"></i>
|
|
Change Password
|
|
</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>
|
|
</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 %}
|