feat: add first page with auth and containers list and agents
This commit is contained in:
94
web/src/routes/login/+page.svelte
Normal file
94
web/src/routes/login/+page.svelte
Normal file
@ -0,0 +1,94 @@
|
||||
<script lang="ts">
|
||||
import { login } from "$lib/auth";
|
||||
import { goto } from "$app/navigation";
|
||||
|
||||
let username = $state("");
|
||||
let password = $state("");
|
||||
let error = $state<string | null>(null);
|
||||
let loading = $state(false);
|
||||
|
||||
async function submit(e: SubmitEvent) {
|
||||
e.preventDefault();
|
||||
error = null;
|
||||
loading = true;
|
||||
try {
|
||||
await login(username, password);
|
||||
goto("/");
|
||||
} catch (err: any) {
|
||||
error = err.message;
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Connexion — Containarr</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="min-h-screen bg-abyss-900 bg-grid-faint bg-grid flex items-center justify-center p-4">
|
||||
<div class="w-full max-w-[360px]">
|
||||
|
||||
<!-- Logo -->
|
||||
<div class="flex flex-col items-center gap-3 mb-8">
|
||||
<img src="/icon-192.png" alt="Containarr" class="w-14 h-14 rounded-2xl shadow-glow-emerald" />
|
||||
<div class="text-center">
|
||||
<h1 class="text-lg font-semibold text-slate-100 tracking-tight">Containarr</h1>
|
||||
<p class="text-xs text-slate-600 mt-0.5">Gestionnaire de containers Docker</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card -->
|
||||
<form onsubmit={submit} class="card p-6 space-y-4">
|
||||
|
||||
{#if error}
|
||||
<div class="flex items-center gap-2 px-3 py-2.5 rounded-lg bg-signal-red/10
|
||||
border border-signal-red/20 text-signal-red text-xs">
|
||||
<svg class="w-3.5 h-3.5 shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{error}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="space-y-1">
|
||||
<label class="block text-xs font-medium text-slate-500" for="username">Utilisateur</label>
|
||||
<input
|
||||
id="username"
|
||||
type="text"
|
||||
bind:value={username}
|
||||
autocomplete="username"
|
||||
required
|
||||
class="w-full bg-abyss-700 border border-white/[0.08] rounded-lg px-3 py-2.5 text-sm
|
||||
text-slate-100 placeholder-slate-700 outline-none
|
||||
focus:border-emerald/60 focus:ring-1 focus:ring-emerald/30 transition-all"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<label class="block text-xs font-medium text-slate-500" for="password">Mot de passe</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
bind:value={password}
|
||||
autocomplete="current-password"
|
||||
required
|
||||
class="w-full bg-abyss-700 border border-white/[0.08] rounded-lg px-3 py-2.5 text-sm
|
||||
text-slate-100 placeholder-slate-700 outline-none
|
||||
focus:border-emerald/60 focus:ring-1 focus:ring-emerald/30 transition-all"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
class="w-full mt-2 bg-emerald hover:bg-emerald-bright disabled:opacity-50
|
||||
text-white text-sm font-medium py-2.5 rounded-lg transition-colors
|
||||
shadow-glow-emerald"
|
||||
>
|
||||
{loading ? "Connexion…" : "Se connecter"}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user