Initial commit
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
<div class="card max-w-sm mx-auto mt-16">
|
||||
<header>
|
||||
<h2>Connexion</h2>
|
||||
<p>Connectez-vous à votre compte PokeShare</p>
|
||||
</header>
|
||||
<section>
|
||||
<form id="login-form" class="grid gap-4">
|
||||
<div role="group" class="field">
|
||||
<label for="username">Nom d'utilisateur</label>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
placeholder="votre@email.com"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div role="group" class="field">
|
||||
<label for="password">Mot de passe</label>
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="••••••••"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<footer class="flex-col gap-2">
|
||||
<button
|
||||
class="btn w-full"
|
||||
type="submit"
|
||||
form="login-form"
|
||||
id="login-submit"
|
||||
>
|
||||
Se connecter
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const form = document.getElementById("login-form");
|
||||
const submitBtn = document.getElementById(
|
||||
"login-submit",
|
||||
) as HTMLButtonElement;
|
||||
const toaster = document.getElementById("toaster") as ToasterElement;
|
||||
|
||||
const showToast = (
|
||||
category: "success" | "error",
|
||||
title: string,
|
||||
description: string,
|
||||
) => {
|
||||
if (toaster?.toast) {
|
||||
toaster.toast({ category, title, description });
|
||||
}
|
||||
};
|
||||
|
||||
form?.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(form as HTMLFormElement);
|
||||
const username = formData.get("username");
|
||||
const password = formData.get("password");
|
||||
|
||||
submitBtn.disabled = true;
|
||||
const originalText = submitBtn.innerHTML;
|
||||
submitBtn.innerHTML = `<svg aria-label="Loading" role="status" data-icon="inline-start" class="animate-spin lucide lucide-loader-circle" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56" /></svg> Connexion...`;
|
||||
|
||||
try {
|
||||
const res = await fetch("/api/login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username, password }),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
window.location.href = "/";
|
||||
} else {
|
||||
const data = await res.json();
|
||||
showToast(
|
||||
"error",
|
||||
"Erreur",
|
||||
data.error ?? "Identifiants incorrects",
|
||||
);
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
}
|
||||
} catch {
|
||||
showToast("error", "Erreur", "Erreur réseau");
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,304 @@
|
||||
---
|
||||
const { pb } = Astro.locals;
|
||||
const user = pb.authStore.record;
|
||||
const initials = user
|
||||
? (user.name || user.email || "")
|
||||
.split(/[\s@.]+/)
|
||||
.filter(Boolean)
|
||||
.slice(0, 2)
|
||||
.map((s: string) => s[0].toUpperCase())
|
||||
.join("")
|
||||
: "";
|
||||
---
|
||||
|
||||
<header
|
||||
class="sticky top-0 z-50 border-b border-border bg-background/95 backdrop-blur"
|
||||
>
|
||||
<nav
|
||||
class="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-8"
|
||||
>
|
||||
<a
|
||||
href="/"
|
||||
class="flex items-center gap-2 text-lg font-bold no-underline"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1.2em"
|
||||
height="1.2em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2a10 10 0 0 1 10 10a10 10 0 0 1-10 10A10 10 0 0 1 2 12A10 10 0 0 1 12 2m0 2c-4.08 0-7.45 3.05-7.94 7h4.07c.44-1.73 2.01-3 3.87-3s3.43 1.27 3.87 3h4.07c-.49-3.95-3.86-7-7.94-7m0 16c4.08 0 7.45-3.05 7.94-7h-4.07c-.44 1.73-2.01 3-3.87 3s-3.43-1.27-3.87-3H4.06c.49 3.95 3.86 7 7.94 7m0-10a2 2 0 0 0-2 2a2 2 0 0 0 2 2a2 2 0 0 0 2-2a2 2 0 0 0-2-2"
|
||||
></path>
|
||||
</svg>
|
||||
PokeShare
|
||||
</a>
|
||||
|
||||
<ul class="flex items-center gap-1 list-none m-0 p-0">
|
||||
<li>
|
||||
<a
|
||||
href="/friends"
|
||||
class="btn relative"
|
||||
data-variant="ghost"
|
||||
data-size="icon-sm"
|
||||
aria-label="Amis"
|
||||
title="Amis"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"
|
||||
></path>
|
||||
<circle cx="9" cy="7" r="4"></circle>
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87"></path>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/search"
|
||||
class="btn"
|
||||
data-variant="ghost"
|
||||
data-size="sm"
|
||||
>
|
||||
<svg
|
||||
data-icon="inline-start"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5l-1.5 1.5l-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16A6.5 6.5 0 0 1 3 9.5A6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14S14 12 14 9.5S12 5 9.5 5"
|
||||
></path>
|
||||
</svg>
|
||||
<span class="hidden sm:inline">Rechercher</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/mycards"
|
||||
class="btn"
|
||||
data-variant="ghost"
|
||||
data-size="sm"
|
||||
>
|
||||
<svg
|
||||
data-icon="inline-start"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="m12.1 18.55l-.1.1l-.11-.1C7.14 14.24 4 11.39 4 8.5C4 6.5 5.5 5 7.5 5c1.54 0 3.04 1 3.57 2.36h1.86C13.46 6 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5c0 2.89-3.14 5.74-7.9 10.05M16.5 3c-1.74 0-3.41.81-4.5 2.08C10.91 3.81 9.24 3 7.5 3C4.42 3 2 5.41 2 8.5c0 3.77 3.4 6.86 8.55 11.53L12 21.35l1.45-1.32C18.6 15.36 22 12.27 22 8.5C22 5.41 19.58 3 16.5 3"
|
||||
></path>
|
||||
</svg>
|
||||
<span class="hidden sm:inline">Mes cartes</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{
|
||||
user ? (
|
||||
<li class="ml-2">
|
||||
<div id="user-menu" class="dropdown-menu">
|
||||
<button
|
||||
type="button"
|
||||
id="user-menu-trigger"
|
||||
aria-haspopup="menu"
|
||||
aria-controls="user-menu-dropdown"
|
||||
aria-expanded="false"
|
||||
class="btn rounded-full"
|
||||
data-variant="ghost"
|
||||
data-size="sm"
|
||||
>
|
||||
<span class="avatar" data-size="sm">
|
||||
<span>{initials}</span>
|
||||
</span>
|
||||
<span class="hidden sm:inline ml-1 text-sm">
|
||||
{user.name || user.email}
|
||||
</span>
|
||||
<svg
|
||||
data-icon="inline-end"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m6 9 6 6 6-6" />
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
id="user-menu-popover"
|
||||
data-popover
|
||||
aria-hidden="true"
|
||||
data-align="end"
|
||||
class="w-48"
|
||||
>
|
||||
<div
|
||||
role="menu"
|
||||
id="user-menu-dropdown"
|
||||
aria-labelledby="user-menu-trigger"
|
||||
>
|
||||
<div role="group">
|
||||
<div
|
||||
role="heading"
|
||||
class="px-2 py-1.5 text-xs opacity-60"
|
||||
>
|
||||
{user.email}
|
||||
</div>
|
||||
<div
|
||||
role="menuitem"
|
||||
onclick="window.location.href='/mycards'"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m12.1 18.55-.1.1-.11-.1C7.14 14.24 4 11.39 4 8.5C4 6.5 5.5 5 7.5 5c1.54 0 3.04 1 3.57 2.36h1.86C13.46 6 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05" />
|
||||
</svg>
|
||||
Ma collection
|
||||
</div>
|
||||
<div
|
||||
role="menuitem"
|
||||
onclick="window.location.href='/profile'"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="12" cy="7" r="4" />
|
||||
</svg>
|
||||
Profil
|
||||
</div>
|
||||
</div>
|
||||
<hr role="separator" />
|
||||
<div role="group">
|
||||
<div
|
||||
role="menuitem"
|
||||
onclick="fetch('/api/logout', { method: 'POST' }).finally(() => window.location.href='/login')"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m16 17 5-5-5-5" />
|
||||
<path d="M21 12H9" />
|
||||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
|
||||
</svg>
|
||||
Déconnexion
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
) : (
|
||||
<li>
|
||||
<a
|
||||
href="/login"
|
||||
class="btn"
|
||||
data-variant="outline"
|
||||
data-size="sm"
|
||||
>
|
||||
Login
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Toggle dark mode"
|
||||
onclick="window.basecoat.theme.toggle()"
|
||||
class="btn"
|
||||
data-variant="ghost"
|
||||
data-size="icon-sm"
|
||||
>
|
||||
<span class="hidden dark:block">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="12" r="4"></circle>
|
||||
<path d="M12 2v2"></path>
|
||||
<path d="M12 20v2"></path>
|
||||
<path d="m4.93 4.93 1.41 1.41"></path>
|
||||
<path d="m17.66 17.66 1.41 1.41"></path>
|
||||
<path d="M2 12h2"></path>
|
||||
<path d="M20 12h2"></path>
|
||||
<path d="m6.34 17.66-1.41 1.41"></path>
|
||||
<path d="m19.07 4.93-1.41 1.41"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="block dark:hidden">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401"
|
||||
></path>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
Reference in New Issue
Block a user