designtopack/src/views/Login.vue
2025-05-05 17:46:49 +02:00

113 lines
2.7 KiB
Vue

<template>
<form
@submit.prevent="handleSubmit"
class="px-24 py-32 flex flex-col mx-auto bg-white rounded-xl"
style="--row-gap: 1rem; max-width: 24em"
>
<div class="field | w-full">
<label for="username">Email</label>
<input
@input="updateEmail"
type="email"
v-model="email"
id="username"
placeholder="mail@exemple.com"
autocomplete="username"
class="w-full rounded-md border border-grey-200 px-16 py-12"
:class="{ invalid: !isValidEmail }"
required
/>
</div>
<div class="field | w-full">
<label for="password">Mot de passe</label>
<input
:type="isPasswordVisible ? 'text' : 'password'"
v-model="password"
id="password"
autocomplete="current-password"
class="w-full rounded-md border border-grey-200 px-16 py-12"
required
/>
<button
class="btn | w-full"
type="button"
@click="isPasswordVisible = !isPasswordVisible"
>
{{ isPasswordVisible ? 'masquer' : 'afficher' }}
</button>
</div>
<p class="error" v-if="errorMessage" v-html="errorMessage"></p>
<button
@click="login"
:class="submitBtn.state"
class="btn | w-full"
type="submit"
:disabled="submitBtn.state === 'pending' ? true : undefined"
>
{{ submitBtn.message }}
</button>
</form>
</template>
<script setup>
import { ref, watch } from 'vue';
const email = ref('');
const isValidEmail = ref(false);
const password = ref('');
const isPasswordVisible = ref(false);
const errorMessage = ref(null);
const submitBtn = ref({
message: 'Connexion',
state: 'ready',
});
watch(email, (newEmail) => {
const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
isValidEmail.value = regex.test(newEmail);
});
function updateEmail(event) {
email.value = event.target.value;
}
async function login() {
if (email.value.length === 0 || password.value.length === 0) {
errorMessage.value = 'Veuillez remplir les champs.';
}
submitBtn.value.message = 'En cours…';
submitBtn.value.state = 'pending';
const headers = {
method: 'POST',
body: JSON.stringify({
email: email.value,
password: password.value,
}),
};
const res = await fetch('/login.json', headers);
const json = await res.json();
if (json.status === 'success') {
if (json.role === 'admin') {
location.href = '/panel';
} else {
location.href = '/';
}
} else {
errorMessage.value = json.message;
submitBtn.value.message = 'Réessayer';
submitBtn.value.state = 'ready';
}
}
</script>
<style scoped>
.error {
color: #ee6767;
}
input.invalid:focus-visible {
outline: 2px solid #ef8d8d;
}
</style>