@sidebase/nuxt-auth component

This commit is contained in:
2025-08-06 16:21:56 +02:00
parent 589dabfb8e
commit 22d731a334
7 changed files with 632 additions and 516 deletions

View File

@@ -1,81 +1,102 @@
<template>
<v-app>
<v-main>
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="6" lg="4">
<v-card class="elevation-12">
<v-toolbar color="green-darken-2" dark flat>
<v-toolbar-title>Iniciar Sesión</v-toolbar-title>
<v-spacer />
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn icon large>
<v-icon>mdi-help-circle</v-icon>
</v-btn>
</template>
<span>Ayuda</span>
</v-tooltip>
</v-toolbar>
<v-app>
<v-main>
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="6" lg="4">
<v-card class="elevation-12">
<v-toolbar color="green-darken-2" dark flat>
<v-toolbar-title
>Iniciar Sesión</v-toolbar-title
>
<v-spacer />
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn icon large>
<v-icon>mdi-help-circle</v-icon>
</v-btn>
</template>
<span>Ayuda</span>
</v-tooltip>
</v-toolbar>
<v-card-text>
<v-form @submit.prevent="login">
<v-text-field
v-model="username"
label="Nombre de usuario"
name="username"
prepend-icon="mdi-account"
type="text"
:rules="usernameRules"
required
/>
<v-card-text>
<v-form @submit.prevent="login">
<v-text-field
v-model="username"
label="Nombre de usuario"
name="username"
prepend-icon="mdi-account"
type="text"
:rules="usernameRules"
required
/>
<v-text-field
v-model="password"
label="Contraseña"
name="password"
prepend-icon="mdi-lock"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword = !showPassword"
:rules="passwordRules"
required
/>
<v-text-field
v-model="password"
label="Contraseña"
name="password"
prepend-icon="mdi-lock"
:append-icon="
showPassword
? 'mdi-eye'
: 'mdi-eye-off'
"
:type="
showPassword ? 'text' : 'password'
"
@click:append="
showPassword = !showPassword
"
:rules="passwordRules"
required
/>
<v-checkbox
v-model="remember"
label="Recordar sesión"
color="green-darken-2"
/>
<v-checkbox
v-model="remember"
label="Recordar sesión"
color="green-darken-2"
/>
<v-btn
type="submit"
color="green-darken-2"
block
:loading="loading"
dark
>
Iniciar Sesión
</v-btn>
</v-form>
</v-card-text>
<v-btn
type="submit"
color="green-darken-2"
block
:loading="loading"
dark
>
Iniciar Sesión
</v-btn>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn text color="green-darken-2" to="/register">Registrarse</v-btn>
<v-btn text color="green-darken-1" to="/forgot-password"
>¿Olvidaste tu contraseña?</v-btn
>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
<v-card-actions>
<v-spacer />
<v-btn
text
color="green-darken-2"
to="/register"
>Registrarse</v-btn
>
<v-btn
text
color="green-darken-1"
to="/forgot-password"
>¿Olvidaste tu contraseña?</v-btn
>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script setup>
definePageMeta({
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: "/" },
});
import { ref } from "vue";
import { useRouter } from "vue-router";
@@ -87,37 +108,43 @@ const remember = ref(false);
const showPassword = ref(false);
const loading = ref(false);
const { signIn } = useAuth();
const usernameRules = [
(v) => !!v || "El nombre de usuario es requerido",
(v) => (v && v.length >= 3) || "El usuario debe tener al menos 3 caracteres",
(v) => !!v || "El nombre de usuario es requerido",
(v) =>
(v && v.length >= 3) || "El usuario debe tener al menos 3 caracteres",
];
const passwordRules = [
(v) => !!v || "La contraseña es requerida",
(v) => (v && v.length >= 6) || "La contraseña debe tener al menos 6 caracteres",
(v) => !!v || "La contraseña es requerida",
(v) =>
(v && v.length >= 5) ||
"La contraseña debe tener al menos 5 caracteres",
];
const login = () => {
loading.value = true;
const login = async () => {
loading.value = true;
await signIn({ username: "admin", password: "admin" });
// Simular una llamada a API
setTimeout(() => {
loading.value = false;
// Redirigir al dashboard después del login
router.push("/dashboard");
}, 2000);
setTimeout(() => {
loading.value = false;
// Redirigir al dashboard después del login
console.log("signIn", signIn);
router.push("/");
}, 2000);
};
</script>
<style scoped>
.fill-height {
min-height: 100vh;
background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
min-height: 100vh;
background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
}
/* Opcional: Personalización adicional del tema verde */
.v-btn--active,
.v-btn:hover {
background-color: rgba(27, 94, 32, 0.8) !important;
background-color: rgba(27, 94, 32, 0.8) !important;
}
</style>

View File

@@ -1,9 +1,13 @@
<template>
<v-container
class="fill-height d-flex flex-column align-center justify-center text-center"
>
<h1>Forgot Password</h1>
</v-container>
<v-container
class="fill-height d-flex flex-column align-center justify-center text-center"
>
<h1>Forgot Password</h1>
</v-container>
</template>
<script setup></script>
<script setup>
definePageMeta({
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: "/" },
});
</script>

View File

@@ -2,18 +2,29 @@
<v-container
class="fill-height d-flex flex-column align-center justify-center text-center"
>
<img :src="norrisStore.response.icon_url" alt="chuck norris" size="64" />
<img
:src="norrisStore.response.icon_url"
alt="chuck norris"
size="64"
/>
<div class="mt-3">My Application's Home Page</div>
<div>
{{ norrisStore.response }}
</div>
<div>
{{ data }}
</div>
</v-container>
</template>
<script setup>
definePageMeta({
auth: true,
});
import { ref, onMounted } from "vue";
import { useChuckNorris } from "~/stores/chuck";
const norrisStore = useChuckNorris();
const { data } = useAuth();
onMounted(async () => {
await norrisStore.getData();

View File

@@ -1,11 +1,15 @@
<template>
<v-container
class="fill-height d-flex flex-column align-center justify-center text-center"
>
<h1>Register</h1>
</v-container>
<v-container
class="fill-height d-flex flex-column align-center justify-center text-center"
>
<h1>Register</h1>
</v-container>
</template>
<script setup></script>
<script setup>
definePageMeta({
auth: { unauthenticatedOnly: true, navigateAuthenticatedTo: "/" },
});
</script>
<style></style>