Files
ohm_streaming/templates/components/admin_panel.html
root 4101d98a41 feat: complete UI redesign with DaisyUI + Tailwind CSS v4
Design system overhaul using DaisyUI v5 on Tailwind CSS v4:

- Custom 'ohmstream' dark theme with orange primary (#FF9F1C),
  magenta secondary, gold accent matching existing palette
- Tailwind CSS-first config (input.css source, style.css built output)
- DaisyUI components: navbar, drawer, cards, badges, alerts, tables,
  progress bars, tabs, toggles, stats, form controls, tooltips
- Mobile-first responsive layout with drawer navigation
- Eliminated ~500+ lines of embedded CSS across 15+ template files
- Removed all inline style spam from admin_panel and settings_section
- Preserved all HTMX triggers, Alpine.js state, and Jinja2 logic
- Updated auth-ui.js for DaisyUI tab-active class compatibility

Build: npm run build:css (minified) / npm run watch:css (dev)
2026-04-11 19:46:52 +00:00

107 lines
5.7 KiB
HTML

<div class="mb-10">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold">Administration</h2>
</div>
<!-- Stats Cards -->
<div class="stats stats-vertical md:stats-horizontal shadow w-full mb-6">
<div class="stat bg-base-200 border border-base-300 rounded-box">
<div class="stat-title">Utilisateurs</div>
<div class="stat-value text-primary">{{ users|length }}</div>
</div>
<div class="stat bg-base-200 border border-base-300 rounded-box">
<div class="stat-title">Actifs</div>
<div class="stat-value text-secondary">{{ users|selectattr('is_active')|list|length }}</div>
</div>
<div class="stat bg-base-200 border border-base-300 rounded-box">
<div class="stat-title">Admins</div>
<div class="stat-value text-warning">{{ users|selectattr('is_admin')|list|length }}</div>
</div>
</div>
<!-- Users Table -->
<div class="bg-base-200 border border-base-300 rounded-box overflow-hidden">
<div class="px-6 py-5 border-b border-base-300">
<h3 class="font-bold text-primary m-0">Gestion des utilisateurs</h3>
</div>
{% if users %}
<div class="overflow-x-auto">
<table class="table table-sm">
<thead>
<tr>
<th>Utilisateur</th>
<th>Email</th>
<th class="text-center">Statut</th>
<th class="text-center">Role</th>
<th>Derniere connexion</th>
<th>Inscription</th>
<th class="text-center">Actions</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr class="{% if not user.is_active %}opacity-50{% endif %}">
<td>
<div class="font-semibold">{{ user.username }}</div>
{% if user.full_name %}
<div class="text-xs text-base-content/50">{{ user.full_name }}</div>
{% endif %}
</td>
<td class="text-base-content/60 text-sm">{{ user.email or '-' }}</td>
<td class="text-center">
{% if user.is_active %}
<span class="badge badge-success badge-sm">Actif</span>
{% else %}
<span class="badge badge-error badge-sm">Inactif</span>
{% endif %}
</td>
<td class="text-center">
{% if user.is_admin %}
<span class="badge badge-primary badge-sm">Admin</span>
{% else %}
<span class="badge badge-ghost badge-sm">User</span>
{% endif %}
</td>
<td class="text-base-content/50 text-sm">
{{ user.last_login.strftime('%d/%m/%Y %H:%M') if user.last_login else '-' }}
</td>
<td class="text-base-content/50 text-sm">
{{ user.created_at.strftime('%d/%m/%Y') if user.created_at else '-' }}
</td>
<td class="text-center whitespace-nowrap">
{% if user.id != current_user.id %}
<button class="btn btn-xs {% if user.is_active %}btn-ghost{% else %}btn-success{% endif %}"
hx-put="/api/admin/users/{{ user.id }}/toggle-active" hx-swap="none"
hx-on::after-request="htmx.ajax('GET', '/api/admin/ui', {target: '#admin-panel-content'})"
title="{% if user.is_active %}Desactiver{% else %}Activer{% endif %}">
{% if user.is_active %}Desactiver{% else %}Activer{% endif %}
</button>
<button class="btn btn-xs {% if user.is_admin %}btn-ghost{% else %}btn-success{% endif %}"
hx-put="/api/admin/users/{{ user.id }}/toggle-admin" hx-swap="none"
hx-on::after-request="htmx.ajax('GET', '/api/admin/ui', {target: '#admin-panel-content'})"
title="{% if user.is_admin %}Retrograder{% else %}Promouvoir{% endif %}">
{% if user.is_admin %}Retrograder{% else %}Admin{% endif %}
</button>
<button class="btn btn-xs btn-error"
hx-delete="/api/admin/users/{{ user.id }}" hx-swap="none"
hx-confirm="Supprimer {{ user.username }} ?"
hx-on::after-request="htmx.ajax('GET', '/api/admin/ui', {target: '#admin-panel-content'})"
title="Supprimer">
<i class="fas fa-trash"></i>
</button>
{% else %}
<span class="text-base-content/40 text-xs">Vous</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="p-10 text-center text-base-content/40">Aucun utilisateur</div>
{% endif %}
</div>
</div>