core/frontend/login.html
enzo 562eff8863 fix: CSS variables neu-*, WebSocket token, thème initial
- CSS: remplace var(--bg-*)/var(--text-*)/var(--accent-*)/var(--color-*)
  par les vraies variables --neu-* (neu-bg, neu-surface, neu-text, neu-primary…)
- CSS: supprime body{overflow:hidden} qui bloquait le scroll
- CSS: .auth-layout déplacé dans neu.css pour login/install
- WS: ajoute ?token= aux connexions /ws/proxmox (dashboardPage + proxmoxPage)
- HTML: script inline pour appliquer data-theme avant Alpine (évite FOUC)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 16:39:23 +01:00

132 lines
3.3 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<script>(function(){document.documentElement.setAttribute("data-theme",localStorage.getItem("pxp_theme")||"dark")})()</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ProxmoxPanel — Connexion</title>
<link rel="stylesheet" href="/css/neu.css" />
<link rel="stylesheet" href="/css/dark.css" />
<link rel="stylesheet" href="/css/light.css" />
<script src="/js/vendors/htmx.min.js"></script>
<script src="/js/vendors/swup.iife.js"></script>
<script src="/js/app.js"></script>
<script src="/js/vendors/alpine.min.js" defer></script>
</head>
<body x-data>
<div class="auth-layout" x-data="loginPage()" x-cloak>
<div class="auth-card neu-card">
<div class="auth-logo">
<span class="logo-icon"></span>
<h1 class="auth-title">ProxmoxPanel</h1>
<p class="auth-subtitle" x-text="t('login.subtitle')"></p>
</div>
<form @submit.prevent="submit" class="auth-form">
<div class="form-group">
<label class="form-label" x-text="t('login.username')"></label>
<input
class="neu-input"
type="text"
x-model="username"
:placeholder="t('login.usernamePlaceholder')"
autocomplete="username"
required
/>
</div>
<div class="form-group">
<label class="form-label" x-text="t('login.password')"></label>
<input
class="neu-input"
type="password"
x-model="password"
:placeholder="t('login.passwordPlaceholder')"
autocomplete="current-password"
required
/>
</div>
<div class="form-error" x-show="error" x-text="error" role="alert"></div>
<button class="neu-btn neu-btn--primary auth-submit" type="submit" :disabled="loading">
<span x-show="!loading" x-text="t('login.submit')"></span>
<span x-show="loading" class="spinner"></span>
</button>
</form>
</div>
</div>
<style>
.auth-layout {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
.auth-card {
width: 100%;
max-width: 400px;
padding: 2rem;
}
.auth-logo {
text-align: center;
margin-bottom: 2rem;
}
.logo-icon {
font-size: 3rem;
color: var(--neu-primary);
}
.auth-title {
font-size: 1.5rem;
font-weight: 700;
margin: 0.5rem 0 0.25rem;
}
.auth-subtitle {
font-size: 0.875rem;
color: var(--neu-text-muted);
margin: 0;
}
.auth-form {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-label {
font-size: 0.875rem;
font-weight: 600;
color: var(--neu-text-muted);
}
.form-error {
background: rgba(239,68,68,0.1);
border: 1px solid var(--neu-danger);
border-radius: 0.5rem;
padding: 0.75rem;
font-size: 0.875rem;
color: var(--neu-danger);
}
.auth-submit {
width: 100%;
padding: 0.875rem;
margin-top: 0.5rem;
}
.spinner {
display: inline-block;
width: 1rem;
height: 1rem;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 0.6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
[x-cloak] { display: none !important; }
</style>
</body>
</html>