feat(admin): add admin-only file manager, admin menu, de-emphasize status, improve dashboard

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-21 09:15:27 +00:00
parent 8813e4e8f3
commit 16e7b6478e
6 changed files with 492 additions and 119 deletions
+125
View File
@@ -0,0 +1,125 @@
{% extends "base.html" %}
{% block title %}File Manager Admin{% endblock %}
{% block content %}
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<div class="mb-6">
<h1 class="text-3xl font-bold text-gray-900 flex items-center gap-2">
<i class="fas fa-folder-open text-blue-500"></i>
File Manager
<span class="text-sm font-normal text-red-600 bg-red-50 border border-red-200 rounded px-2 py-0.5 ml-2">Admin Only</span>
</h1>
<p class="text-gray-500 mt-1 text-sm">
Browsing: <code class="bg-gray-100 rounded px-1">{{ workdir }}</code>
{% if current_path %}/ <code class="bg-gray-100 rounded px-1">{{ current_path }}</code>{% endif %}
</p>
</div>
<!-- Breadcrumb -->
<nav class="flex mb-4 text-sm" aria-label="Breadcrumb">
<ol class="inline-flex items-center space-x-1">
<li>
<a href="/admin/files" class="text-blue-600 hover:underline flex items-center">
<i class="fas fa-home mr-1"></i> workdir
</a>
</li>
{% for crumb in breadcrumbs %}
<li class="flex items-center">
<i class="fas fa-chevron-right text-gray-400 mx-1 text-xs"></i>
{% if loop.last %}
<span class="text-gray-700 font-medium">{{ crumb.name }}</span>
{% else %}
<a href="/admin/files?path={{ crumb.path | urlencode }}" class="text-blue-600 hover:underline">{{ crumb.name }}</a>
{% endif %}
</li>
{% endfor %}
</ol>
</nav>
<!-- File listing table -->
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-8"></th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider hidden sm:table-cell">Size</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider hidden md:table-cell">Modified</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<!-- Parent directory row -->
{% if current_path %}
<tr class="hover:bg-gray-50">
<td class="px-6 py-3 text-yellow-500"><i class="fas fa-folder"></i></td>
<td class="px-6 py-3 text-sm font-medium text-gray-900" colspan="3">
<a href="/admin/files{% if parent_path %}?path={{ parent_path | urlencode }}{% endif %}" class="text-blue-600 hover:underline flex items-center gap-1">
<i class="fas fa-level-up-alt text-xs"></i> ..
</a>
</td>
<td class="px-6 py-3"></td>
</tr>
{% endif %}
{% if entries %}
{% for entry in entries %}
<tr class="hover:bg-gray-50">
<td class="px-6 py-3">
{% if entry.is_dir %}
<i class="fas fa-folder text-yellow-400"></i>
{% elif entry.mime_type.startswith('image') %}
<i class="fas fa-file-image text-blue-400"></i>
{% elif entry.mime_type == 'application/pdf' %}
<i class="fas fa-file-pdf text-red-400"></i>
{% elif 'text' in entry.mime_type %}
<i class="fas fa-file-alt text-gray-400"></i>
{% elif 'json' in entry.mime_type %}
<i class="fas fa-file-code text-green-400"></i>
{% else %}
<i class="fas fa-file text-gray-400"></i>
{% endif %}
</td>
<td class="px-6 py-3 text-sm font-medium text-gray-900">
{% if entry.is_dir %}
<a href="/admin/files?path={{ entry.rel_path | urlencode }}" class="text-blue-600 hover:underline">
{{ entry.name }}
</a>
{% else %}
<span>{{ entry.name }}</span>
{% endif %}
</td>
<td class="px-6 py-3 text-sm text-gray-500 hidden sm:table-cell">
{{ entry.size }}
</td>
<td class="px-6 py-3 text-sm text-gray-500 hidden md:table-cell">
{{ entry.modified }}
</td>
<td class="px-6 py-3 text-sm">
{% if not entry.is_dir %}
<a href="/admin/files/download?path={{ entry.rel_path | urlencode }}"
class="inline-flex items-center px-2.5 py-1 border border-gray-300 text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50"
title="Download">
<i class="fas fa-download mr-1"></i> Download
</a>
{% endif %}
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="5" class="px-6 py-10 text-center text-sm text-gray-500">
<i class="fas fa-folder-open text-gray-300 text-3xl mb-2 block"></i>
This directory is empty.
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
{% endblock %}