feat: redesign login page with password toggle
This commit is contained in:
@@ -1,47 +1,123 @@
|
|||||||
{{define "title"}}Login{{end}}
|
{{define "title"}}Login{{end}}
|
||||||
{{define "content"}}
|
{{define "content"}}
|
||||||
<div class="flex min-h-screen items-center justify-center p-4">
|
<main class="flex min-h-dvh items-center justify-center bg-[url(/static/images/background.png)] bg-cover bg-center px-3 py-4 sm:px-4 sm:py-8">
|
||||||
<div class="w-full max-w-md">
|
<div class="mx-auto w-full max-w-[31.25rem] bg-background-surface px-5 pb-6 pt-7 shadow-sm sm:px-8 sm:pb-8 sm:pt-11 lg:px-12">
|
||||||
<h1 class="heading-serif mb-2 text-3xl font-normal text-foreground">Sign in</h1>
|
<h1 class="mb-6 text-2xl font-normal leading-tight tracking-[-0.02em] text-foreground sm:mb-8 sm:text-3xl sm:leading-none">
|
||||||
<p class="text-foreground-muted mb-8">Enter your credentials to continue.</p>
|
Sign in to your account
|
||||||
|
</h1>
|
||||||
|
|
||||||
<form method="POST" action="/login" class="flex flex-col gap-6">
|
<form method="POST" action="/login" class="space-y-5 sm:space-y-7">
|
||||||
<label class="flex flex-col gap-2">
|
<div class="space-y-3">
|
||||||
<span class="text-foreground text-sm">Username</span>
|
<label for="username" class="block font-normal text-foreground">
|
||||||
|
Email address
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
id="username"
|
||||||
name="username"
|
name="username"
|
||||||
value="{{.Username}}"
|
type="text"
|
||||||
|
autocomplete="username"
|
||||||
|
spellcheck="false"
|
||||||
required
|
required
|
||||||
placeholder="username"
|
value="{{.Username}}"
|
||||||
class="bg-background-surface text-foreground placeholder-foreground-muted border-none px-4 py-3 focus:outline-none focus-within:ring-2 focus-within:ring-accent rounded-sm"
|
class="h-10 w-full bg-background-surface px-3 text-foreground outline-none transition focus:ring-1 focus:ring-accent rounded-none!"
|
||||||
/>
|
/>
|
||||||
</label>
|
</div>
|
||||||
|
|
||||||
<label class="flex flex-col gap-2">
|
<div class="space-y-3">
|
||||||
<span class="text-foreground text-sm">Password</span>
|
<label for="password" class="block font-normal text-foreground">
|
||||||
<div class="relative group focus-within:ring-2 focus-within:ring-accent rounded-sm">
|
Password
|
||||||
|
</label>
|
||||||
|
<div class="flex h-10 w-full bg-background-surface transition focus-within:ring-1 focus-within:ring-accent rounded-none!">
|
||||||
<input
|
<input
|
||||||
type="password"
|
id="password"
|
||||||
name="password"
|
name="password"
|
||||||
|
type="password"
|
||||||
|
autocomplete="current-password"
|
||||||
required
|
required
|
||||||
placeholder="Password"
|
class="min-w-0 flex-1 bg-transparent px-3 text-foreground outline-none rounded-none!"
|
||||||
class="bg-background-surface text-foreground placeholder-foreground-muted w-full border-none px-4 py-3 focus:outline-none rounded-sm"
|
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="flex w-12 items-center justify-center text-foreground sm:w-12.5"
|
||||||
|
aria-label="Show password"
|
||||||
|
data-toggle-password
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="h-5 w-5"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-eye-open
|
||||||
|
>
|
||||||
|
<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
|
||||||
|
<circle cx="12" cy="12" r="3" />
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="hidden h-5 w-5"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-eye-closed
|
||||||
|
>
|
||||||
|
<path d="M9.88 9.88a3 3 0 1 0 4.24 4.24" />
|
||||||
|
<path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" />
|
||||||
|
<path d="M6.61 6.61A13.52 13.52 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" />
|
||||||
|
<line x1="2" x2="22" y1="2" y2="22" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</div>
|
||||||
|
|
||||||
|
{{if .Error}}
|
||||||
|
<p class="text-sm font-normal text-red-700" role="alert">
|
||||||
|
{{.Error}}
|
||||||
|
</p>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="mt-2 bg-accent px-4 py-3 font-normal text-on-accent transition-colors rounded-sm hover:opacity-90"
|
class="mt-1 h-10 w-full rounded-[2px] bg-[#cccccc] font-normal text-black transition hover:bg-[#bfbfbf] active:bg-[#b3b3b3] sm:h-9"
|
||||||
>
|
>
|
||||||
Sign in
|
Sign In
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{{if .Error}}
|
|
||||||
<p class="mt-6 text-sm text-red-500">{{.Error}}</p>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(() => {
|
||||||
|
const button = document.querySelector('[data-toggle-password]');
|
||||||
|
const input = document.getElementById('password');
|
||||||
|
const openEye = document.querySelector('[data-eye-open]');
|
||||||
|
const closedEye = document.querySelector('[data-eye-closed]');
|
||||||
|
if (!(button instanceof HTMLButtonElement)) return;
|
||||||
|
if (!(input instanceof HTMLInputElement)) return;
|
||||||
|
if (!(openEye instanceof SVGElement)) return;
|
||||||
|
if (!(closedEye instanceof SVGElement)) return;
|
||||||
|
|
||||||
|
let showPassword = false;
|
||||||
|
const render = () => {
|
||||||
|
input.type = showPassword ? 'text' : 'password';
|
||||||
|
button.setAttribute('aria-label', showPassword ? 'Hide password' : 'Show password');
|
||||||
|
openEye.classList.toggle('hidden', showPassword);
|
||||||
|
closedEye.classList.toggle('hidden', !showPassword);
|
||||||
|
};
|
||||||
|
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
showPassword = !showPassword;
|
||||||
|
render();
|
||||||
|
});
|
||||||
|
render();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
Reference in New Issue
Block a user