ui: login landing and header version

This commit is contained in:
2025-12-30 13:15:25 +01:00
parent 49adf77808
commit 5e7eb6a6e7
3 changed files with 156 additions and 42 deletions

View File

@ -1 +1 @@
0.1.0
0.1.1

View File

@ -97,6 +97,48 @@ body.dark-mode .theme-toggle .sun-icon {
padding: 20px;
}
.hidden {
display: none !important;
}
.login-landing {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background: radial-gradient(circle at 20% 10%, rgba(102, 126, 234, 0.15), transparent 45%),
radial-gradient(circle at 80% 20%, rgba(72, 187, 120, 0.12), transparent 40%),
var(--bg-main);
}
.login-card {
width: min(520px, 100%);
background: var(--bg-panel);
border: 1px solid var(--border-main);
border-radius: 16px;
padding: 32px;
box-shadow: var(--shadow-lg);
}
.login-brand {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 24px;
}
.login-brand i {
width: 40px;
height: 40px;
color: var(--primary);
}
.login-brand h1 {
font-size: 1.6rem;
margin-bottom: 4px;
}
/* Header - Keep the gradient but more professional */
header {
background: var(--bg-header);
@ -105,6 +147,11 @@ header {
border-radius: 12px;
margin-bottom: 30px;
box-shadow: var(--shadow-md);
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
header h1 {
@ -119,6 +166,34 @@ header p {
font-weight: 400;
}
.header-main {
display: flex;
align-items: center;
gap: 12px;
}
.header-main i {
width: 32px;
height: 32px;
}
.header-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6px;
}
.header-version {
font-size: 0.9rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 6px 10px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.2);
}
/* Statistics Dashboard - More visual interest */
.stats {
display: grid;
@ -647,6 +722,14 @@ textarea:focus {
.modal-content {
padding: 24px 20px;
}
.login-card {
padding: 24px;
}
.header-meta {
align-items: flex-start;
}
}
/* NEW STYLES FOR ENHANCED UI */

View File

@ -18,16 +18,63 @@
</svg>
</button>
<div class="container">
<div id="loginLanding" class="login-landing">
<div class="login-card">
<div class="login-brand">
<i data-lucide="shield-check"></i>
<div>
<h1>Safe Kiddo Control</h1>
<p class="text-muted">Anmeldung erforderlich</p>
</div>
</div>
<section id="loginSection">
<h3><i data-lucide="log-in"></i> Anmeldung</h3>
<p class="text-muted mb-1">Melde dich an um Nutzerkonten zu verwalten</p>
<button id="oidcLogin" type="button" class="secondary">
<i data-lucide="key-round"></i>
Login via OIDC
</button>
<div style="margin: 1.5rem 0; border-top: 1px solid var(--color-border); position: relative;">
<span style="position: absolute; top: -0.6rem; left: 50%; transform: translateX(-50%); background: var(--color-surface); padding: 0 1rem; color: var(--color-text-muted); font-size: 0.75rem;">ODER</span>
</div>
<form id="loginForm">
<div class="grid">
<div class="form-group">
<label for="loginUser">Benutzer</label>
<input id="loginUser" name="loginUser" autocomplete="username" required />
</div>
<div class="form-group">
<label for="loginPass">Passwort</label>
<input id="loginPass" name="loginPass" type="password" autocomplete="current-password" required />
</div>
</div>
<button type="submit">
<i data-lucide="log-in"></i>
Anmelden
</button>
</form>
</section>
</div>
</div>
<div id="appContainer" class="container hidden">
<!-- Header -->
<header>
<h1>
<i data-lucide="shield-check"></i>
Safe Kiddo Control
</h1>
<div class="user-info" id="headerStatus">
<span id="currentUser">Nicht angemeldet</span>
<div class="header-main">
<h1>
<i data-lucide="shield-check"></i>
Safe Kiddo Control
</h1>
</div>
<div class="header-meta">
<div class="header-version" id="headerVersion">v-</div>
<div class="user-info" id="headerStatus">
<span id="currentUser">Nicht angemeldet</span>
</div>
</div>
</header>
@ -51,38 +98,6 @@
</div>
</div>
<!-- Login Section -->
<section id="loginSection">
<h3><i data-lucide="log-in"></i> Anmeldung</h3>
<p class="text-muted mb-1">Melde dich an um Nutzerkonten zu verwalten</p>
<button id="oidcLogin" type="button" class="secondary">
<i data-lucide="key-round"></i>
Login via OIDC
</button>
<div style="margin: 1.5rem 0; border-top: 1px solid var(--color-border); position: relative;">
<span style="position: absolute; top: -0.6rem; left: 50%; transform: translateX(-50%); background: var(--color-surface); padding: 0 1rem; color: var(--color-text-muted); font-size: 0.75rem;">ODER</span>
</div>
<form id="loginForm">
<div class="grid">
<div class="form-group">
<label for="loginUser">Benutzer</label>
<input id="loginUser" name="loginUser" autocomplete="username" required />
</div>
<div class="form-group">
<label for="loginPass">Passwort</label>
<input id="loginPass" name="loginPass" type="password" autocomplete="current-password" required />
</div>
</div>
<button type="submit">
<i data-lucide="log-in"></i>
Anmelden
</button>
</form>
</section>
<!-- User Management Section -->
<section id="userSection" class="hidden">
<h3><i data-lucide="users"></i> Nutzerverwaltung</h3>
@ -271,12 +286,27 @@
}
// Authentication
function showLanding() {
document.getElementById('loginLanding').classList.remove('hidden');
document.getElementById('appContainer').classList.add('hidden');
document.getElementById('headerVersion').textContent = 'v-';
history.replaceState(null, '', '#login');
}
function showApp() {
document.getElementById('loginLanding').classList.add('hidden');
document.getElementById('appContainer').classList.remove('hidden');
if (window.location.hash !== '#app') {
history.replaceState(null, '', '#app');
}
}
async function checkSession() {
try {
const data = await api('/me');
currentToken = sessionStorage.getItem('skdToken') || currentToken;
document.getElementById('currentUser').textContent = `Angemeldet als ${data.user} (${data.auth_mode})`;
document.getElementById('loginSection').classList.add('hidden');
showApp();
document.getElementById('userSection').classList.remove('hidden');
document.getElementById('updateSection').classList.remove('hidden');
await refreshUsers();
@ -284,7 +314,7 @@
return true;
} catch (err) {
document.getElementById('currentUser').textContent = 'Nicht angemeldet';
document.getElementById('loginSection').classList.remove('hidden');
showLanding();
document.getElementById('userSection').classList.add('hidden');
document.getElementById('updateSection').classList.add('hidden');
return false;
@ -361,6 +391,7 @@
try {
const data = await api('/update/status');
document.querySelector('#metricVersion .value').textContent = data.current_version;
document.getElementById('headerVersion').textContent = `v${data.current_version}`;
const statusBadge = data.last_status === 'success'
? '<span class="badge success"><i data-lucide="check-circle"></i> Erfolgreich</span>'