All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 30s
297 lines
19 KiB
HTML
297 lines
19 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Admin Dashboard - Mischkomposition</title>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
|
<link rel="stylesheet" href="/assets/css/main.min.css" />
|
|
<style>
|
|
body { background: #101316; color: rgba(255,255,255,.86); }
|
|
#wrapper { min-height: 100vh; }
|
|
#header { z-index: 20; }
|
|
.admin-shell { display: grid; grid-template-columns: 260px minmax(0, 1fr); min-height: calc(100vh - 3.25em); padding-top: 3.25em; }
|
|
.admin-sidebar { position: sticky; top: 3.25em; height: calc(100vh - 3.25em); padding: 1em; border-right: 1px solid rgba(255,255,255,.08); background: rgba(15,18,21,.96); display: flex; flex-direction: column; gap: 1em; }
|
|
.admin-brand { padding: .65em .45em; }
|
|
.admin-brand strong { display: block; color: #fff; font-size: 1em; letter-spacing: .02em; }
|
|
.admin-brand span { display: block; color: rgba(255,255,255,.48); font-size: .8em; margin-top: .2em; }
|
|
.admin-nav { display: grid; gap: .35em; }
|
|
.nav-item { width: 100%; height: auto; min-height: 2.75em; padding: .65em .75em; border: 1px solid transparent; border-radius: 7px; background: transparent; color: rgba(255,255,255,.68) !important; display: flex; align-items: center; gap: .75em; text-align: left; box-shadow: none; line-height: 1.2; }
|
|
.nav-item i { width: 1.15em; text-align: center; color: rgba(255,255,255,.42); }
|
|
.nav-item:hover, .nav-item.active { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.09); color: #fff !important; }
|
|
.nav-item.active i { color: #8ee6d2; }
|
|
.sidebar-footer { margin-top: auto; display: grid; gap: .5em; }
|
|
.sidebar-footer a { border-bottom: 0; color: rgba(255,255,255,.64); }
|
|
.admin-content { min-width: 0; padding: 1.1em; }
|
|
.admin-view { display: none; max-width: 1220px; margin: 0 auto; }
|
|
.admin-view.active { display: block; }
|
|
.view-head { display: flex; justify-content: space-between; gap: 1em; align-items: flex-end; margin-bottom: 1em; }
|
|
.view-head h2 { margin: 0; color: #fff; font-size: 1.35em; letter-spacing: .01em; }
|
|
.view-head p { margin: .25em 0 0; color: rgba(255,255,255,.54); font-size: .92em; }
|
|
.view-actions { display: flex; gap: .5em; flex-wrap: wrap; justify-content: flex-end; }
|
|
.admin-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: .85em; align-items: start; }
|
|
.panel { background: rgba(22,25,29,.94); border: 1px solid rgba(255,255,255,.08); border-radius: 8px; padding: 1em; min-width: 0; box-shadow: 0 12px 30px rgba(0,0,0,.18); }
|
|
.span-3 { grid-column: span 3; }
|
|
.span-4 { grid-column: span 4; }
|
|
.span-5 { grid-column: span 5; }
|
|
.span-6 { grid-column: span 6; }
|
|
.span-7 { grid-column: span 7; }
|
|
.span-8 { grid-column: span 8; }
|
|
.span-12 { grid-column: 1 / -1; }
|
|
.panel h3 { margin: 0 0 .75em; color: #fff; font-size: .92em; letter-spacing: .08em; text-transform: uppercase; }
|
|
.panel p { margin: 0 0 .75em; color: rgba(255,255,255,.58); font-size: .9em; }
|
|
.stat-card { min-height: 106px; display: flex; flex-direction: column; justify-content: space-between; }
|
|
.stat-label { color: rgba(255,255,255,.52); font-size: .74em; letter-spacing: .09em; text-transform: uppercase; }
|
|
.stat-value { color: #fff; font-size: 2.05em; line-height: 1; margin-top: .25em; }
|
|
.stat-sub { color: rgba(255,255,255,.48); font-size: .82em; margin-top: .45em; }
|
|
.compact-form { display: grid; grid-template-columns: repeat(4, minmax(130px, 1fr)); gap: .65em; align-items: end; }
|
|
.compact-form .field-inline { min-width: 0; }
|
|
.compact-form label { display:block; margin: 0 0 .25em; font-size:.72em; text-transform:uppercase; letter-spacing:.08em; color:rgba(255,255,255,.55); }
|
|
.compact-form input, .compact-form select, .panel select { height: 2.45em; }
|
|
table { width: 100%; border-collapse: collapse; font-size: .9em; }
|
|
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid rgba(255,255,255,.09); vertical-align: middle; }
|
|
th { color: rgba(255,255,255,.58); font-size: .72em; text-transform: uppercase; letter-spacing: .08em; font-weight: 400; }
|
|
.table-wrap { overflow-x: auto; }
|
|
.badge { display: inline-block; padding: 2px 7px; border-radius: 999px; font-size: .76em; line-height: 1.6; white-space: nowrap; }
|
|
.badge-admin { background: #d76345; }
|
|
.badge-user { background: #2d7fb8; }
|
|
.badge-client { background: #3f9f79; }
|
|
.badge-expired { background: #666; }
|
|
.folder-badge { background: rgba(52,165,142,.16); color:#8ee6d2; margin: 2px 3px 2px 0; border: 1px solid rgba(52,165,142,.28); }
|
|
.muted { color: rgba(255,255,255,.48); }
|
|
.btn-small { padding: 3px 9px; font-size: .78em; margin: 2px; cursor: pointer; height: auto; line-height: 1.6; border-radius: 5px; }
|
|
.btn-danger { border-color: rgba(228,77,38,.55) !important; color: #ffad9c !important; }
|
|
.folder-grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap:.75em; }
|
|
.folder-card { border: 1px solid rgba(255,255,255,.09); border-radius: 8px; padding:.85em; background: rgba(255,255,255,.035); }
|
|
.folder-card h3 { margin:0 0 .35em; font-size:1em; color:#fff; text-transform:none; letter-spacing:0; }
|
|
.folder-meta { display:flex; gap:.45em; flex-wrap:wrap; margin:.5em 0; }
|
|
.folder-pill { border:1px solid rgba(255,255,255,.12); border-radius:999px; padding:.15em .55em; font-size:.78em; color:rgba(255,255,255,.68); }
|
|
.folder-actions { margin-top:.65em; display:flex; gap:.35em; flex-wrap:wrap; }
|
|
.access-list { display:grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap:.4em .7em; margin-top:.75em; }
|
|
.access-item { display:flex; align-items:center; gap:.45em; padding:.55em .65em; border:1px solid rgba(255,255,255,.08); border-radius:6px; background:rgba(255,255,255,.025); cursor:pointer; }
|
|
.access-item input { width:auto; margin:0; }
|
|
.preview-grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap:.55em; margin-top:.75em; max-height: 560px; overflow:auto; padding-right:.25em; }
|
|
.preview-grid a { border:0; display:block; border-radius:6px; overflow:hidden; background:#0b0d10; aspect-ratio: 1 / 1; }
|
|
.preview-grid img { width:100%; height:100%; object-fit:cover; display:block; }
|
|
.signal-list { display: grid; gap: .55em; }
|
|
.signal-item { display: flex; align-items: center; justify-content: space-between; gap: .7em; padding: .6em .7em; border: 1px solid rgba(255,255,255,.08); border-radius: 7px; background: rgba(255,255,255,.03); }
|
|
.signal-item strong { color: #fff; font-weight: 400; }
|
|
#assign-status { font-size:.85em; color:#8ee6d2; display:inline-block; margin-top:10px; }
|
|
@media screen and (max-width: 1000px) {
|
|
.admin-shell { grid-template-columns: 1fr; padding-top: 3.25em; }
|
|
.admin-sidebar { position: static; height: auto; border-right: 0; border-bottom: 1px solid rgba(255,255,255,.08); }
|
|
.admin-nav { grid-template-columns: repeat(auto-fit, minmax(145px, 1fr)); }
|
|
.sidebar-footer { margin-top: 0; }
|
|
.span-3, .span-4, .span-5, .span-6, .span-7, .span-8 { grid-column: 1 / -1; }
|
|
.compact-form { grid-template-columns: 1fr; }
|
|
}
|
|
@media screen and (max-width: 600px) {
|
|
.admin-content { padding: .75em; }
|
|
.view-head { display: block; }
|
|
.view-actions { justify-content: flex-start; margin-top: .75em; }
|
|
table { font-size:.82em; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="is-preload">
|
|
<div id="wrapper">
|
|
<header id="header">
|
|
<h1><a href="/index.html"><strong>Mischkomposition</strong> Admin</a></h1>
|
|
<nav><ul>
|
|
<li><a href="/index.html">Website</a></li>
|
|
<li><a href="#" id="logout-btn">Logout <i class="fa fa-sign-out"></i></a></li>
|
|
</ul></nav>
|
|
</header>
|
|
|
|
<main id="main" class="admin-shell">
|
|
<aside class="admin-sidebar">
|
|
<div class="admin-brand">
|
|
<strong>Kontrollraum</strong>
|
|
<span id="admin-user-label">Admin</span>
|
|
</div>
|
|
<nav class="admin-nav" aria-label="Admin Bereiche">
|
|
<button type="button" class="nav-item active" data-view="overview"><i class="fa fa-chart-pie"></i><span>Uebersicht</span></button>
|
|
<button type="button" class="nav-item" data-view="users"><i class="fa fa-users"></i><span>Nutzer und Rollen</span></button>
|
|
<button type="button" class="nav-item" data-view="folders"><i class="fa fa-folder-open"></i><span>Ordner</span></button>
|
|
<button type="button" class="nav-item" data-view="access"><i class="fa fa-key"></i><span>Freigaben</span></button>
|
|
<button type="button" class="nav-item" data-view="preview"><i class="fa fa-images"></i><span>Ordnerinhalt</span></button>
|
|
<button type="button" class="nav-item" data-view="account"><i class="fa fa-user-shield"></i><span>Account</span></button>
|
|
<button type="button" class="nav-item" data-view="system"><i class="fa fa-server"></i><span>System</span></button>
|
|
</nav>
|
|
<div class="sidebar-footer">
|
|
<a href="/index.html"><i class="fa fa-arrow-left"></i> Zur Galerie</a>
|
|
</div>
|
|
</aside>
|
|
|
|
<div class="admin-content">
|
|
<section class="admin-view active" data-view="overview">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2>Uebersicht</h2>
|
|
<p>Aktuelle Nutzer, private Ordner und offene Freigaben.</p>
|
|
</div>
|
|
<div class="view-actions">
|
|
<button type="button" class="btn-small" id="refresh-dashboard">Aktualisieren</button>
|
|
</div>
|
|
</div>
|
|
<div class="admin-grid">
|
|
<div class="panel stat-card span-3"><div><div class="stat-label">Nutzer</div><div class="stat-value" id="stat-users">0</div></div><div class="stat-sub" id="stat-users-sub">0 Admins</div></div>
|
|
<div class="panel stat-card span-3"><div><div class="stat-label">Private Ordner</div><div class="stat-value" id="stat-folders">0</div></div><div class="stat-sub" id="stat-folders-sub">0 Bilder</div></div>
|
|
<div class="panel stat-card span-3"><div><div class="stat-label">Freigaben</div><div class="stat-value" id="stat-access">0</div></div><div class="stat-sub" id="stat-access-sub">0 ohne Zugriff</div></div>
|
|
<div class="panel stat-card span-3"><div><div class="stat-label">Clients</div><div class="stat-value" id="stat-clients">0</div></div><div class="stat-sub" id="stat-clients-sub">0 abgelaufen</div></div>
|
|
<div class="panel span-6">
|
|
<h3>Aufmerksamkeit</h3>
|
|
<div id="attention-list" class="signal-list"></div>
|
|
</div>
|
|
<div class="panel span-6">
|
|
<h3>Rollenverteilung</h3>
|
|
<div id="role-list" class="signal-list"></div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="admin-view" data-view="users">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2>Nutzer und Rollen</h2>
|
|
<p>Accounts, Laufzeiten, Rollen und Ordnerzugriffe.</p>
|
|
</div>
|
|
</div>
|
|
<div class="admin-grid">
|
|
<div class="panel span-12">
|
|
<h3>Nutzer erstellen</h3>
|
|
<form id="create-user-form" class="compact-form">
|
|
<div class="field-inline">
|
|
<label>Username</label>
|
|
<input type="text" id="new-username" placeholder="Nutzername" required />
|
|
</div>
|
|
<div class="field-inline">
|
|
<label>Passwort</label>
|
|
<input type="password" id="new-password" placeholder="Passwort" required />
|
|
</div>
|
|
<div class="field-inline">
|
|
<label>Rolle</label>
|
|
<select id="new-role">
|
|
<option value="client">Client (30 Tage)</option>
|
|
<option value="user">User (permanent)</option>
|
|
<option value="admin">Admin</option>
|
|
</select>
|
|
</div>
|
|
<div><button type="submit">Erstellen</button></div>
|
|
</form>
|
|
</div>
|
|
<div class="panel span-12">
|
|
<h3>Bestand</h3>
|
|
<div class="table-wrap">
|
|
<table>
|
|
<thead><tr><th>ID</th><th>Username</th><th>Rolle</th><th>Status</th><th>Ordnerzugriff</th><th>Aktionen</th></tr></thead>
|
|
<tbody id="users-tbody"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="admin-view" data-view="folders">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2>Ordner</h2>
|
|
<p>Unterordner im Bilderpfad sind privat und werden nur explizit freigegeben.</p>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<div id="folders-overview" class="folder-grid"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="admin-view" data-view="access">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2>Freigaben</h2>
|
|
<p>Nutzer auswaehlen und private Ordner zuweisen.</p>
|
|
</div>
|
|
</div>
|
|
<div class="admin-grid">
|
|
<div class="panel span-4">
|
|
<h3>Nutzer</h3>
|
|
<select id="user-select"><option value="">Nutzer waehlen...</option></select>
|
|
<div id="selected-user-summary" class="signal-list" style="margin-top:.75em;"></div>
|
|
</div>
|
|
<div class="panel span-8">
|
|
<h3>Ordnerzugriff</h3>
|
|
<div id="folder-table-wrap" style="display:none;">
|
|
<div id="folder-access-list" class="access-list"></div>
|
|
<span id="assign-status"></span>
|
|
</div>
|
|
<p id="folder-access-empty" class="muted">Kein Nutzer ausgewaehlt.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="admin-view" data-view="preview">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2 id="folder-preview-title">Ordnerinhalt</h2>
|
|
<p id="folder-preview-note">Waehle einen Ordner aus der Ordneruebersicht.</p>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<div id="folder-preview" class="preview-grid"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="admin-view" data-view="account">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2>Account</h2>
|
|
<p>Passwort fuer den aktuellen Admin-Zugang.</p>
|
|
</div>
|
|
</div>
|
|
<div class="panel">
|
|
<form id="admin-pw-form" class="compact-form">
|
|
<div class="field-inline">
|
|
<label>Altes Passwort</label>
|
|
<input type="password" id="admin-pw-old" required />
|
|
</div>
|
|
<div class="field-inline">
|
|
<label>Neues Passwort</label>
|
|
<input type="password" id="admin-pw-new" required />
|
|
</div>
|
|
<div><button type="submit" class="btn-small">Aendern</button></div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="admin-view" data-view="system">
|
|
<div class="view-head">
|
|
<div>
|
|
<h2>System</h2>
|
|
<p>Deployment- und Laufzeitdaten fuer tom.mischlabs.de.</p>
|
|
</div>
|
|
</div>
|
|
<div class="admin-grid">
|
|
<div class="panel span-6">
|
|
<h3>Deployment</h3>
|
|
<div class="signal-list">
|
|
<div class="signal-item"><strong>Registry</strong><span>git.mischlabs.de/mrdiderot/photography:latest</span></div>
|
|
<div class="signal-item"><strong>Updates</strong><span>Watchtower</span></div>
|
|
<div class="signal-item"><strong>Port</strong><span>8090</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="panel span-6">
|
|
<h3>Speicherorte</h3>
|
|
<div class="signal-list">
|
|
<div class="signal-item"><strong>Bilder</strong><span>/app/public/images/fulls</span></div>
|
|
<div class="signal-item"><strong>Thumbnails</strong><span>/app/public/images/thumbs</span></div>
|
|
<div class="signal-item"><strong>Datenbank</strong><span>/app/data/database.sqlite</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
<script src="/assets/js/jquery.min.js"></script>
|
|
<script src="/assets/js/admin.js?v=3"></script>
|
|
</body>
|
|
</html>
|