@sidebase/nuxt-auth component
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,16 +1,37 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
compatibilityDate: "2025-07-15",
|
||||
//pages: true,
|
||||
ssr: false,
|
||||
devtools: { enabled: false },
|
||||
modules: ["@pinia/nuxt", "@sidebase/nuxt-auth"],
|
||||
runtimeConfig: {
|
||||
baseURL: "http://localhost:3000",
|
||||
},
|
||||
auth: {
|
||||
globalAppMiddleware: false,
|
||||
baseURL: "http://localhost:8000/auth",
|
||||
provider: {
|
||||
type: "local",
|
||||
endpoints: {
|
||||
signIn: { path: "/jwt/create/", method: "post" },
|
||||
signOut: false,
|
||||
signUp: { path: "/users/", method: "post" },
|
||||
getSession: { path: "/users/me/", method: "get" },
|
||||
},
|
||||
pages: {
|
||||
login: "/login",
|
||||
},
|
||||
token: {
|
||||
signInResponseTokenPointer: "/access",
|
||||
type: "JWT",
|
||||
headerName: "Authorization",
|
||||
},
|
||||
sessionDataType: {},
|
||||
},
|
||||
enableSessionRefreshPeriodically: 5000,
|
||||
enableSessionRefreshOnWindowFocus: true,
|
||||
},
|
||||
css: ["vuetify/styles", "@mdi/font/css/materialdesignicons.min.css"],
|
||||
plugins: ["~/plugins/vuetify.js"],
|
||||
components: true,
|
||||
build: {
|
||||
transpile: ["vuetify"],
|
||||
},
|
||||
modules: [
|
||||
'@pinia/nuxt',
|
||||
],
|
||||
});
|
||||
|
||||
871
package-lock.json
generated
871
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/font": "^7.4.47",
|
||||
"@nuxtjs/auth-next": "5.0.0-1667386184.dfbbb54",
|
||||
"@pinia/nuxt": "^0.11.2",
|
||||
"@sidebase/nuxt-auth": "^1.0.1",
|
||||
"nuxt": "^4.0.1",
|
||||
"pinia": "^3.0.3",
|
||||
"vue": "^3.5.18",
|
||||
|
||||
Reference in New Issue
Block a user