126 lines
7.6 KiB
HTML
126 lines
7.6 KiB
HTML
{{define "layout"}}
|
|
<!DOCTYPE html>
|
|
<html lang="fr" class="h-full">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
{{if .CSRFToken}}<meta name="csrf-token" content="{{.CSRFToken}}">{{end}}
|
|
<title>{{block "title" .}}Dashboard{{end}} — TicketBot Admin</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
|
<link rel="stylesheet" href="/static/app.css">
|
|
<script>
|
|
tailwind.config = {
|
|
theme: { extend: { colors: { discord: { bg: '#1e1f22', card: '#2b2d31', accent: '#5865f2', hover: '#404249', border: '#3f4147', sidebar: '#1e1f22' } } } }
|
|
}
|
|
// HTMX CSRF
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.body.addEventListener('htmx:configRequest', function(e) {
|
|
const meta = document.querySelector('meta[name="csrf-token"]');
|
|
if (meta) e.detail.headers['X-CSRF-Token'] = meta.content;
|
|
});
|
|
});
|
|
</script>
|
|
</head>
|
|
<body class="h-full bg-discord-bg text-gray-100 flex overflow-hidden">
|
|
|
|
<!-- Sidebar -->
|
|
<aside class="w-60 flex-shrink-0 bg-discord-sidebar flex flex-col h-screen border-r border-discord-border">
|
|
<div class="p-4 border-b border-discord-border">
|
|
<span class="font-bold text-white text-lg">TicketBot</span>
|
|
<span class="text-xs text-gray-400 block">Admin Panel</span>
|
|
</div>
|
|
|
|
<nav class="flex-1 overflow-y-auto p-2 space-y-1">
|
|
<a href="/" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded text-gray-300 hover:bg-discord-hover hover:text-white transition-colors {{if eq .ActivePage "dashboard"}}sidebar-link-active{{end}}">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>
|
|
Dashboard
|
|
</a>
|
|
<a href="/panels" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded text-gray-300 hover:bg-discord-hover hover:text-white transition-colors {{if eq .ActivePage "panels"}}sidebar-link-active{{end}}">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/></svg>
|
|
Panels
|
|
</a>
|
|
<a href="/convocations" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded text-gray-300 hover:bg-discord-hover hover:text-white transition-colors {{if eq .ActivePage "convocations"}}sidebar-link-active{{end}}">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"/></svg>
|
|
Convocations
|
|
</a>
|
|
<a href="/transcripts" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded text-gray-300 hover:bg-discord-hover hover:text-white transition-colors {{if eq .ActivePage "transcripts"}}sidebar-link-active{{end}}">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
|
Transcripts
|
|
</a>
|
|
<a href="/audit" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded text-gray-300 hover:bg-discord-hover hover:text-white transition-colors {{if eq .ActivePage "audit"}}sidebar-link-active{{end}}">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
|
|
Audit Log
|
|
</a>
|
|
{{if .Admin}}{{if .Admin.IsSuperadmin}}
|
|
<a href="/sessions" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded text-gray-300 hover:bg-discord-hover hover:text-white transition-colors {{if eq .ActivePage "sessions"}}sidebar-link-active{{end}}">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/></svg>
|
|
Sessions
|
|
</a>
|
|
{{end}}{{end}}
|
|
</nav>
|
|
|
|
<!-- Admin + logout -->
|
|
<div class="p-3 border-t border-discord-border">
|
|
{{if .Admin}}
|
|
<div class="flex items-center gap-2 mb-2">
|
|
{{if .Admin.DiscordAvatar}}
|
|
<img src="https://cdn.discordapp.com/avatars/{{.Admin.DiscordID}}/{{.Admin.DiscordAvatar}}.png?size=32"
|
|
class="w-8 h-8 rounded-full" alt="" onerror="this.style.display='none'">
|
|
{{end}}
|
|
<div class="min-w-0">
|
|
<p class="text-sm font-medium text-white truncate">{{.Admin.DiscordUsername}}</p>
|
|
{{if .Admin.IsSuperadmin}}<p class="text-xs text-discord-accent">Superadmin</p>{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
<form method="POST" action="/auth/logout">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button type="submit" class="w-full text-left flex items-center gap-2 px-2 py-1.5 rounded text-gray-400 hover:text-red-400 hover:bg-discord-hover transition-colors text-sm">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
|
Déconnexion
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main content -->
|
|
<div class="flex-1 flex flex-col min-w-0 h-screen overflow-hidden">
|
|
<!-- Header -->
|
|
<header class="h-14 flex items-center justify-between px-6 border-b border-discord-border bg-discord-card flex-shrink-0">
|
|
<h2 class="font-semibold text-white">{{block "header" .}}Dashboard{{end}}</h2>
|
|
<div class="flex items-center gap-3">
|
|
{{if .BotOnline}}
|
|
<span class="flex items-center gap-1.5 text-sm text-green-400">
|
|
<span class="w-2 h-2 bg-green-400 rounded-full"></span>Bot en ligne
|
|
</span>
|
|
{{else}}
|
|
<span class="flex items-center gap-1.5 text-sm text-red-400">
|
|
<span class="w-2 h-2 bg-red-400 rounded-full"></span>Bot hors ligne
|
|
</span>
|
|
{{end}}
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Page content -->
|
|
<main class="flex-1 overflow-y-auto p-6">
|
|
{{if .Flash}}
|
|
<div id="flash" class="mb-4 px-4 py-3 rounded bg-green-900/50 border border-green-700 text-green-300 text-sm toast-enter">
|
|
{{.Flash}}
|
|
</div>
|
|
{{end}}
|
|
{{if .Error}}
|
|
<div id="error-msg" class="mb-4 px-4 py-3 rounded bg-red-900/50 border border-red-700 text-red-300 text-sm toast-enter">
|
|
{{.Error}}
|
|
</div>
|
|
{{end}}
|
|
{{block "content" .}}{{end}}
|
|
</main>
|
|
</div>
|
|
|
|
<!-- Toast container for HTMX OOB swaps -->
|
|
<div id="toast-container" class="fixed bottom-4 right-4 space-y-2 z-50"></div>
|
|
</body>
|
|
</html>
|
|
{{end}}
|