216 lines
11 KiB
HTML
216 lines
11 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Leftover Media - Admin - DigiServer v2{% endblock %}
|
|
|
|
{% block content %}
|
|
<div style="max-width: 1400px; margin: 0 auto;">
|
|
<div style="margin-bottom: 30px; display: flex; justify-content: space-between; align-items: center;">
|
|
<h1 style="display: flex; align-items: center; gap: 0.5rem;">
|
|
🗑️ Manage Leftover Media
|
|
</h1>
|
|
<a href="{{ url_for('admin.admin_panel') }}" class="btn btn-secondary">
|
|
← Back to Admin
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Overview Stats -->
|
|
<div class="card" style="margin-bottom: 30px;">
|
|
<h2>📊 Overview</h2>
|
|
<p style="color: #6c757d; margin-bottom: 20px;">
|
|
Media files that are not assigned to any playlist. These can be safely deleted to free up storage.
|
|
</p>
|
|
<div class="stats-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
|
<div class="stat-item" style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
|
|
<div style="font-size: 12px; color: #6c757d; margin-bottom: 5px;">Total Leftover Files</div>
|
|
<div style="font-size: 24px; font-weight: bold;">{{ total_leftover }}</div>
|
|
</div>
|
|
<div class="stat-item" style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
|
|
<div style="font-size: 12px; color: #6c757d; margin-bottom: 5px;">Total Size</div>
|
|
<div style="font-size: 24px; font-weight: bold;">{{ "%.2f"|format(total_leftover_size_mb) }} MB</div>
|
|
</div>
|
|
<div class="stat-item" style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
|
|
<div style="font-size: 12px; color: #6c757d; margin-bottom: 5px;">Images</div>
|
|
<div style="font-size: 24px; font-weight: bold;">{{ leftover_images|length }} ({{ "%.2f"|format(images_size_mb) }} MB)</div>
|
|
</div>
|
|
<div class="stat-item" style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
|
|
<div style="font-size: 12px; color: #6c757d; margin-bottom: 5px;">Videos</div>
|
|
<div style="font-size: 24px; font-weight: bold;">{{ leftover_videos|length }} ({{ "%.2f"|format(videos_size_mb) }} MB)</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Images Section -->
|
|
<div class="card" style="margin-bottom: 30px;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
|
<h2>📷 Leftover Images ({{ leftover_images|length }})</h2>
|
|
{% if leftover_images %}
|
|
<form method="POST" action="{{ url_for('admin.delete_leftover_images') }}"
|
|
onsubmit="return confirm('Are you sure you want to delete ALL {{ leftover_images|length }} leftover images? This cannot be undone!');"
|
|
style="display: inline;">
|
|
<button type="submit" class="btn btn-danger">
|
|
🗑️ Delete All Images
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if leftover_images %}
|
|
<div style="max-height: 400px; overflow-y: auto;">
|
|
<table class="table" style="width: 100%; border-collapse: collapse;">
|
|
<thead style="position: sticky; top: 0; background: #f8f9fa;">
|
|
<tr>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Filename</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Size</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Duration</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Uploaded</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6; width: 80px;">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for img in leftover_images %}
|
|
<tr style="border-bottom: 1px solid #dee2e6;">
|
|
<td style="padding: 10px;">📷 {{ img.filename }}</td>
|
|
<td style="padding: 10px;">{{ "%.2f"|format(img.file_size_mb) }} MB</td>
|
|
<td style="padding: 10px;">{{ img.duration }}s</td>
|
|
<td style="padding: 10px;">{{ img.uploaded_at | localtime if img.uploaded_at else 'N/A' }}</td>
|
|
<td style="padding: 10px;">
|
|
<form method="POST" action="{{ url_for('admin.delete_single_leftover', content_id=img.id) }}" style="display: inline;" onsubmit="return confirm('Delete this image?');">
|
|
<button type="submit" class="btn btn-danger btn-sm" style="padding: 4px 8px; font-size: 12px;">🗑️</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div style="text-align: center; padding: 40px; color: #999;">
|
|
<div style="font-size: 48px; margin-bottom: 15px;">✓</div>
|
|
<p>No leftover images found. All images are assigned to playlists!</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Videos Section -->
|
|
<div class="card" style="margin-bottom: 30px;">
|
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
|
<h2 style="margin: 0;">🎥 Leftover Videos ({{ leftover_videos|length }})</h2>
|
|
{% if leftover_videos %}
|
|
<form method="POST" action="{{ url_for('admin.delete_leftover_videos') }}" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete ALL {{ leftover_videos|length }} leftover videos? This action cannot be undone!');">
|
|
<button type="submit" class="btn btn-danger" style="padding: 8px 16px; font-size: 14px;">
|
|
🗑️ Delete All Videos
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if leftover_videos %}
|
|
<div style="max-height: 400px; overflow-y: auto; margin-top: 20px;">
|
|
<table class="table" style="width: 100%; border-collapse: collapse;">
|
|
<thead style="position: sticky; top: 0; background: #f8f9fa;">
|
|
<tr>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Filename</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Size</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Duration</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Uploaded</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6; width: 80px;">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for video in leftover_videos %}
|
|
<tr style="border-bottom: 1px solid #dee2e6;">
|
|
<td style="padding: 10px;">🎥 {{ video.filename }}</td>
|
|
<td style="padding: 10px;">{{ "%.2f"|format(video.file_size_mb) }} MB</td>
|
|
<td style="padding: 10px;">{{ video.duration }}s</td>
|
|
<td style="padding: 10px;">{{ video.uploaded_at | localtime if video.uploaded_at else 'N/A' }}</td>
|
|
<td style="padding: 10px;">
|
|
<form method="POST" action="{{ url_for('admin.delete_single_leftover', content_id=video.id) }}" style="display: inline;" onsubmit="return confirm('Delete this video?');">
|
|
<button type="submit" class="btn btn-danger btn-sm" style="padding: 4px 8px; font-size: 12px;">🗑️</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div style="text-align: center; padding: 40px; color: #999;">
|
|
<div style="font-size: 48px; margin-bottom: 15px;">✓</div>
|
|
<p>No leftover videos found. All videos are assigned to playlists!</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- PDFs Section -->
|
|
<div class="card" style="margin-bottom: 30px;">
|
|
<h2>📄 Leftover PDFs ({{ leftover_pdfs|length }})</h2>
|
|
|
|
{% if leftover_pdfs %}
|
|
<div style="max-height: 400px; overflow-y: auto; margin-top: 20px;">
|
|
<table class="table" style="width: 100%; border-collapse: collapse;">
|
|
<thead style="position: sticky; top: 0; background: #f8f9fa;">
|
|
<tr>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Filename</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Size</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Duration</th>
|
|
<th style="padding: 10px; text-align: left; border-bottom: 2px solid #dee2e6;">Uploaded</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for pdf in leftover_pdfs %}
|
|
<tr style="border-bottom: 1px solid #dee2e6;">
|
|
<td style="padding: 10px;">📄 {{ pdf.filename }}</td>
|
|
<td style="padding: 10px;">{{ "%.2f"|format(pdf.file_size_mb) }} MB</td>
|
|
<td style="padding: 10px;">{{ pdf.duration }}s</td>
|
|
<td style="padding: 10px;">{{ pdf.uploaded_at | localtime if pdf.uploaded_at else 'N/A' }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div style="text-align: center; padding: 40px; color: #999;">
|
|
<div style="font-size: 48px; margin-bottom: 15px;">✓</div>
|
|
<p>No leftover PDFs found. All PDFs are assigned to playlists!</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
body.dark-mode .card {
|
|
background: #2d3748;
|
|
color: #e2e8f0;
|
|
}
|
|
|
|
body.dark-mode h1,
|
|
body.dark-mode h2 {
|
|
color: #e2e8f0;
|
|
}
|
|
|
|
body.dark-mode .stat-item {
|
|
background: #1a202c !important;
|
|
color: #e2e8f0;
|
|
}
|
|
|
|
body.dark-mode .table thead {
|
|
background: #1a202c !important;
|
|
}
|
|
|
|
body.dark-mode .table th,
|
|
body.dark-mode .table td {
|
|
color: #e2e8f0;
|
|
border-color: #4a5568 !important;
|
|
}
|
|
|
|
body.dark-mode .table tr {
|
|
border-color: #4a5568 !important;
|
|
}
|
|
|
|
body.dark-mode .table tr:hover {
|
|
background: #1a202c;
|
|
}
|
|
</style>
|
|
|
|
{% endblock %}
|