From e1436f1eff59cf11faadcb2590f7710a6f0f707b Mon Sep 17 00:00:00 2001 From: Saadani-Malek92 <saadani.malek@yandex.com> Date: Thu, 16 May 2024 15:57:39 +0100 Subject: [PATCH] first commit authentifications pages --- package.json | 1 + src/router/constants.js | 5 + src/router/index.js | 72 +++++++++++++- src/views/Auth/AdminLogin.vue | 99 ++++++++++++++++++++ src/views/Auth/UserLogin.vue | 171 ++++++++++++++++++++++++++++++++++ 5 files changed, 344 insertions(+), 4 deletions(-) create mode 100644 src/router/constants.js create mode 100644 src/views/Auth/AdminLogin.vue create mode 100644 src/views/Auth/UserLogin.vue diff --git a/package.json b/package.json index a63c0e8..4c403fe 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@popperjs/core": "2.11.5", + "axios": "^1.6.8", "bootstrap": "5.1.3", "pinia": "2.0.14", "prismjs": "1.28.0", diff --git a/src/router/constants.js b/src/router/constants.js new file mode 100644 index 0000000..cee1edb --- /dev/null +++ b/src/router/constants.js @@ -0,0 +1,5 @@ +export const Role = { + Admin: 'admin', + User: 'user', + Guest: 'guest', + }; \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index 6257f01..3e9606e 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -23,6 +23,12 @@ import ElDropdowns from "../layouts/sections/elements/dropdowns/DropdownsView.vu import ElProgressBars from "../layouts/sections/elements/progress-bars/ProgressBarsView.vue"; import ElToggles from "../layouts/sections/elements/toggles/TogglesView.vue"; import ElTypography from "../layouts/sections/elements/typography/TypographyView.vue"; + + import AdminLoginView from "../views/Auth/AdminLogin.vue"; + import UserLoginView from "../views/Auth/UserLogin.vue"; +// import AdminView from "../views/LandingPages/Author/AuthorView.vue"; +import { Role } from './constants'; + const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ @@ -30,6 +36,7 @@ const router = createRouter({ path: "/", name: "presentation", component: PresentationView, + //meta: { requiresAuth: true, requiredRole: Role.Admin }, }, { path: "/pages/landing-pages/about-us", @@ -146,7 +153,64 @@ const router = createRouter({ name: "el-typography", component: ElTypography, }, - ], -}); - -export default router; + + { + path: '/admin/auth', + component: AdminLoginView, + name: "admin-login", + }, + // { + // path: "/unauthorized", + // name: "unauthorized", + // component: UnauthorizedView, + // }, + { + path: "/user/login", + name: "user-login", + component: UserLoginView, + }, + + ], + }); + + + function isAuthenticated() { + // Check if the user is authenticated, e.g., by verifying the presence of a valid token or logged-in state + // Return true if authenticated, false otherwise + // Example: return localStorage.getItem('token') !== null; + + return true; + } + + function getCurrentUserRole() { + // Retrieve the current user's role from your authentication system or state management + // Return the role of the current user + // Example: return localStorage.getItem('userRole'); + return "guest"; + } + + // Route guard + router.beforeEach((to, from, next) => { + if (to.meta.requiresAuth) { + // Check if the user is authenticated, e.g., by checking the presence of a valid token or logged-in state + if (isAuthenticated()) { + // Check if the user has the required role + if (to.meta.requiredRole && getCurrentUserRole() !== to.meta.requiredRole) { + // Redirect to a different route or show an error message + next({ path: '/unauthorized' }); + } else { + // Proceed to the requested route + next(); + } + } else { + // Redirect to the login page or a suitable route for unauthenticated users + next({ path: '/logout' }); + } + } else { + // No authentication required for the route + next(); + } + }); + + export default router; + \ No newline at end of file diff --git a/src/views/Auth/AdminLogin.vue b/src/views/Auth/AdminLogin.vue new file mode 100644 index 0000000..450c696 --- /dev/null +++ b/src/views/Auth/AdminLogin.vue @@ -0,0 +1,99 @@ +<script setup> +import { onMounted } from "vue"; +import Header from "@/examples/Header.vue"; +import MaterialInput from "@/components/MaterialInput.vue"; +import MaterialButton from "@/components/MaterialButton.vue"; +import setMaterialInput from "@/assets/js/material-input"; +import axios from "axios"; +onMounted(() => { + setMaterialInput(); +}); + +const handleLogin = async () => { + try { + const response = await axios.post('https://jsonplaceholder.typicode.com/posts?userId=1'); + console.log(response.data); + + // Redirect the user to the admin dashboard + // router.push('/admin/dashboard'); + } catch (err) { + console.log('Error:', err); + } +}; +</script> +<template> + <Header> + <div + class="page-header align-items-start min-vh-100" + :style="{ + backgroundImage: + 'url(https://images.unsplash.com/photo-1497294815431-9365093b7331?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1950&q=80)' + }" + loading="lazy" + > + <span class="mask bg-gradient-dark opacity-6"></span> + <div class="container my-auto"> + <div class="row"> + <div class="col-lg-4 col-md-8 col-12 mx-auto"> + <div class="card z-index-0 fadeIn3 fadeInBottom"> + <div + class="card-header p-0 position-relative mt-n4 mx-3 z-index-2" + > + <div + class="bg-gradient-info shadow-success border-radius-lg py-3 pe-1" + > + <h4 + class="text-white font-weight-bolder text-center mt-2 mb-0" + > + Admin Sign in + </h4> + + </div> + </div> + <div class="card-body"> + <form role="form" class="text-start" @submit.prevent="handleLogin"> + <MaterialInput + id="email" + class="input-group-outline my-3" + :label="{ text: 'Email', class: 'form-label' }" + type="email" + /> + <MaterialInput + id="password" + class="input-group-outline mb-3" + :label="{ text: 'Password', class: 'form-label' }" + type="password" + /> + <button type="submit">login</button> + <div class="text-center"> + <MaterialButton + class="my-4 mb-2" + variant="gradient" + color="info" + fullWidth + >Sign in</MaterialButton + > + </div> + </form> + </div> + </div> + </div> + </div> + </div> + <footer class="footer position-absolute bottom-2 py-2 w-100"> + <div class="container"> + <div class="row align-items-center justify-content-lg-between"> + <div class="col-12 col-md-6 my-auto"> + <div + class="copyright text-center text-sm text-white text-lg-start" + > + © {{ new Date().getFullYear() }} + </div> + </div> + + </div> + </div> + </footer> + </div> + </Header> +</template> diff --git a/src/views/Auth/UserLogin.vue b/src/views/Auth/UserLogin.vue new file mode 100644 index 0000000..868347b --- /dev/null +++ b/src/views/Auth/UserLogin.vue @@ -0,0 +1,171 @@ +<script setup> +import { onMounted } from "vue"; + +// example components +import DefaultNavbar from "@/examples/navbars/NavbarDefault.vue"; +import Header from "@/examples/Header.vue"; + +//Vue Material Kit 2 components +import MaterialInput from "@/components/MaterialInput.vue"; +import MaterialSwitch from "@/components/MaterialSwitch.vue"; +import MaterialButton from "@/components/MaterialButton.vue"; + +// material-input +import setMaterialInput from "@/assets/js/material-input"; +onMounted(() => { + setMaterialInput(); +}); +</script> +<template> + <DefaultNavbar transparent /> + <Header> + <div + class="page-header align-items-start min-vh-100" + :style="{ + backgroundImage: + 'url(https://images.unsplash.com/photo-1497294815431-9365093b7331?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1950&q=80)' + }" + loading="lazy" + > + <span class="mask bg-gradient-dark opacity-6"></span> + <div class="container my-auto"> + <div class="row"> + <div class="col-lg-4 col-md-8 col-12 mx-auto"> + <div class="card z-index-0 fadeIn3 fadeInBottom"> + <div + class="card-header p-0 position-relative mt-n4 mx-3 z-index-2" + > + <div + class="bg-gradient-success shadow-success border-radius-lg py-3 pe-1" + > + <h4 + class="text-white font-weight-bolder text-center mt-2 mb-0" + > + Sign in + </h4> + <div class="row mt-3"> + <div class="col-2 text-center ms-auto"> + <a class="btn btn-link px-3" href="javascript:;"> + <i class="fa fa-facebook text-white text-lg"></i> + </a> + </div> + <div class="col-2 text-center px-1"> + <a class="btn btn-link px-3" href="javascript:;"> + <i class="fa fa-github text-white text-lg"></i> + </a> + </div> + <div class="col-2 text-center me-auto"> + <a class="btn btn-link px-3" href="javascript:;"> + <i class="fa fa-google text-white text-lg"></i> + </a> + </div> + </div> + </div> + </div> + <div class="card-body"> + <form role="form" class="text-start"> + <MaterialInput + id="email" + class="input-group-outline my-3" + :label="{ text: 'Email', class: 'form-label' }" + type="email" + /> + <MaterialInput + id="password" + class="input-group-outline mb-3" + :label="{ text: 'Password', class: 'form-label' }" + type="password" + /> + <MaterialSwitch + class="d-flex align-items-center mb-3" + id="rememberMe" + labelClass="mb-0 ms-3" + checked + >Remember me</MaterialSwitch + > + + <div class="text-center"> + <MaterialButton + class="my-4 mb-2" + variant="gradient" + color="success" + fullWidth + >Sign in</MaterialButton + > + </div> + <p class="mt-4 text-sm text-center"> + Don't have an account? + <a + href="#" + class="text-success text-gradient font-weight-bold" + >Sign up</a + > + </p> + </form> + </div> + </div> + </div> + </div> + </div> + <footer class="footer position-absolute bottom-2 py-2 w-100"> + <div class="container"> + <div class="row align-items-center justify-content-lg-between"> + <div class="col-12 col-md-6 my-auto"> + <div + class="copyright text-center text-sm text-white text-lg-start" + > + © {{ new Date().getFullYear() }}, made with + <i class="fa fa-heart" aria-hidden="true"></i> by + <a + href="https://www.creative-tim.com" + class="font-weight-bold text-white" + target="_blank" + >Creative Tim</a + > + for a better web. + </div> + </div> + <div class="col-12 col-md-6"> + <ul + class="nav nav-footer justify-content-center justify-content-lg-end" + > + <li class="nav-item"> + <a + href="https://www.creative-tim.com" + class="nav-link text-white" + target="_blank" + >Creative Tim</a + > + </li> + <li class="nav-item"> + <a + href="https://www.creative-tim.com/presentation" + class="nav-link text-white" + target="_blank" + >About Us</a + > + </li> + <li class="nav-item"> + <a + href="https://www.creative-tim.com/blog" + class="nav-link text-white" + target="_blank" + >Blog</a + > + </li> + <li class="nav-item"> + <a + href="https://www.creative-tim.com/license" + class="nav-link pe-0 text-white" + target="_blank" + >License</a + > + </li> + </ul> + </div> + </div> + </div> + </footer> + </div> + </Header> +</template>