Compare commits
2 Commits
2c59441ff2
...
def9a0f357
| Author | SHA1 | Date |
|---|---|---|
|
|
def9a0f357 | |
|
|
8e1c6e1cd7 |
|
|
@ -1,4 +1,4 @@
|
|||
import { useAuthStore } from "@/stores";
|
||||
import { useAuthStore, useAlertStore } from "@/stores";
|
||||
|
||||
export const fetchWrapper = {
|
||||
get: request("GET"),
|
||||
|
|
@ -51,7 +51,14 @@ async function handleResponse(response) {
|
|||
}
|
||||
|
||||
// get error message from body or default to response status
|
||||
const error = (data && data.message) || response.status;
|
||||
// const error = (data && data.message) || response.status;
|
||||
const error = data["error"];
|
||||
//TODO: need standard messages
|
||||
console.log("error: ", error);
|
||||
|
||||
const alertStore = useAlertStore();
|
||||
alertStore.error(error);
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,8 +198,12 @@
|
|||
<HelpCircleIcon class="w-4 h-4 mr-2" /> Help</DropdownItem
|
||||
>
|
||||
<DropdownDivider class="border-white/[0.08]" />
|
||||
<DropdownItem class="dropdown-item hover:bg-white/5">
|
||||
<ToggleRightIcon class="w-4 h-4 mr-2" /> Logout</DropdownItem
|
||||
<DropdownItem
|
||||
class="dropdown-item hover:bg-white/5"
|
||||
@click="onLogout"
|
||||
>
|
||||
<ToggleRightIcon class="w-4 h-4 mr-2" />
|
||||
Logout</DropdownItem
|
||||
>
|
||||
</DropdownContent>
|
||||
</DropdownMenu>
|
||||
|
|
@ -212,6 +216,7 @@
|
|||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useAuthStore } from "@/stores";
|
||||
|
||||
const searchDropdown = ref(false);
|
||||
const showSearchDropdown = () => {
|
||||
|
|
@ -220,4 +225,10 @@ const showSearchDropdown = () => {
|
|||
const hideSearchDropdown = () => {
|
||||
searchDropdown.value = false;
|
||||
};
|
||||
|
||||
const onLogout = () => {
|
||||
console.log("Logout");
|
||||
const authStore = useAuthStore();
|
||||
return authStore.logout();
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
// localStorage items
|
||||
export const USER = "user";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from "./constants";
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import { defineStore } from "pinia";
|
||||
|
||||
import { fetchWrapper } from "@/api";
|
||||
// import { router } from "@/router";
|
||||
import { useAlertStore } from "@/stores";
|
||||
import router from "@/router";
|
||||
import { USER } from "@/helpers";
|
||||
|
||||
const baseUrl = `${import.meta.env.VITE_API_URL}/api`;
|
||||
|
||||
|
|
@ -10,7 +9,7 @@ export const useAuthStore = defineStore({
|
|||
id: "auth",
|
||||
state: () => ({
|
||||
// initialize state from local storage to enable user to stay logged in
|
||||
user: JSON.parse(localStorage.getItem("user")),
|
||||
user: JSON.parse(localStorage.getItem(USER)),
|
||||
returnUrl: null,
|
||||
}),
|
||||
actions: {
|
||||
|
|
@ -18,22 +17,20 @@ export const useAuthStore = defineStore({
|
|||
return fetchWrapper
|
||||
.post(`${baseUrl}/login`, { email, password })
|
||||
.then((response) => {
|
||||
console.log("response: " + response);
|
||||
// get user
|
||||
let client = response["success"]["client"];
|
||||
|
||||
console.log("user: " + response["success"]["token"]["plainTextToken"]);
|
||||
// add user token
|
||||
client["token"] = response["success"]["token"]["plainTextToken"];
|
||||
|
||||
// update pinia state
|
||||
this.user = user;
|
||||
this.user = client;
|
||||
|
||||
// store user details and jwt in local storage to keep user logged in between page refreshes
|
||||
// localStorage.setItem("user", JSON.stringify(user));
|
||||
localStorage.setItem(USER, JSON.stringify(this.user));
|
||||
|
||||
// redirect to previous url or default to home page
|
||||
// router.push(this.returnUrl || "/");
|
||||
})
|
||||
.catch((error) => {
|
||||
const alertStore = useAlertStore();
|
||||
alertStore.error(error);
|
||||
// redirect to home page
|
||||
router.push({ path: "/" });
|
||||
});
|
||||
},
|
||||
async register(newUser) {
|
||||
|
|
@ -59,9 +56,9 @@ export const useAuthStore = defineStore({
|
|||
});
|
||||
},
|
||||
logout() {
|
||||
// this.user = null;
|
||||
// localStorage.removeItem("user");
|
||||
// router.push("/account/login");
|
||||
this.user = null;
|
||||
localStorage.removeItem(USER);
|
||||
router.push({ path: "/login" });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,17 +6,28 @@
|
|||
<!-- BEGIN: Login Info -->
|
||||
<div class="hidden xl:flex flex-col min-h-screen">
|
||||
<a href="" class="-intro-x flex items-center pt-5">
|
||||
<img alt="Midone Tailwind HTML Admin Template" class="w-6" src="@/assets/images/logo.svg" />
|
||||
<img
|
||||
alt="Midone Tailwind HTML Admin Template"
|
||||
class="w-6"
|
||||
src="@/assets/images/logo.svg"
|
||||
/>
|
||||
<span class="text-white text-lg ml-3"> Icewall </span>
|
||||
</a>
|
||||
<div class="my-auto">
|
||||
<img alt="Midone Tailwind HTML Admin Template" class="-intro-x w-1/2 -mt-16"
|
||||
src="@/assets/images/illustration.svg" />
|
||||
<div class="-intro-x text-white font-medium text-4xl leading-tight mt-10">
|
||||
<img
|
||||
alt="Midone Tailwind HTML Admin Template"
|
||||
class="-intro-x w-1/2 -mt-16"
|
||||
src="@/assets/images/illustration.svg"
|
||||
/>
|
||||
<div
|
||||
class="-intro-x text-white font-medium text-4xl leading-tight mt-10"
|
||||
>
|
||||
A few more clicks to <br />
|
||||
sign in to your account.
|
||||
</div>
|
||||
<div class="-intro-x mt-5 text-lg text-white text-opacity-70 dark:text-slate-400">
|
||||
<div
|
||||
class="-intro-x mt-5 text-lg text-white text-opacity-70 dark:text-slate-400"
|
||||
>
|
||||
Manage all your e-commerce accounts in one place
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -25,39 +36,90 @@
|
|||
<!-- BEGIN: Login Form -->
|
||||
<div class="h-screen xl:h-auto flex py-5 xl:py-0 my-10 xl:my-0">
|
||||
<div
|
||||
class="my-auto mx-auto xl:ml-20 bg-white dark:bg-darkmode-600 xl:bg-transparent px-5 sm:px-8 py-8 xl:p-0 rounded-md shadow-md xl:shadow-none w-full sm:w-3/4 lg:w-2/4 xl:w-auto">
|
||||
<h2 class="intro-x font-bold text-2xl xl:text-3xl text-center xl:text-left">
|
||||
class="my-auto mx-auto xl:ml-20 bg-white dark:bg-darkmode-600 xl:bg-transparent px-5 sm:px-8 py-8 xl:p-0 rounded-md shadow-md xl:shadow-none w-full sm:w-3/4 lg:w-2/4 xl:w-auto"
|
||||
>
|
||||
<h2
|
||||
class="intro-x font-bold text-2xl xl:text-3xl text-center xl:text-left"
|
||||
>
|
||||
Sign In
|
||||
</h2>
|
||||
<div class="intro-x mt-2 text-slate-400 xl:hidden text-center">
|
||||
A few more clicks to sign in to your account. Manage all your e-commerce
|
||||
accounts in one place
|
||||
A few more clicks to sign in to your account. Manage all your
|
||||
e-commerce accounts in one place
|
||||
</div>
|
||||
<div class="intro-x mt-8">
|
||||
<input type="text" class="intro-x login__input form-control py-3 px-4 block" placeholder="Email" />
|
||||
<input type="password" class="intro-x login__input form-control py-3 px-4 block mt-4"
|
||||
placeholder="Password" />
|
||||
<input
|
||||
type="text"
|
||||
v-model.trim="validate.email.$model"
|
||||
class="intro-x login__input form-control py-3 px-4 block mt-4"
|
||||
:class="{ 'border-danger': validate.email.$error }"
|
||||
placeholder="Email"
|
||||
/>
|
||||
<template v-if="validate.email.$error">
|
||||
<div
|
||||
v-for="(error, index) in validate.email.$errors"
|
||||
:key="index"
|
||||
class="text-danger mt-2"
|
||||
>
|
||||
{{ error.$message }}
|
||||
</div>
|
||||
</template>
|
||||
<input
|
||||
type="password"
|
||||
v-model.trim="validate.password.$model"
|
||||
class="intro-x login__input form-control py-3 px-4 block mt-4"
|
||||
:class="{ 'border-danger': validate.password.$error }"
|
||||
placeholder="Password"
|
||||
/>
|
||||
<template v-if="validate.password.$error">
|
||||
<div
|
||||
v-for="(error, index) in validate.password.$errors"
|
||||
:key="index"
|
||||
class="text-danger mt-2"
|
||||
>
|
||||
{{ error.$message }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="intro-x flex text-slate-600 dark:text-slate-500 text-xs sm:text-sm mt-4">
|
||||
<div
|
||||
class="intro-x flex text-slate-600 dark:text-slate-500 text-xs sm:text-sm mt-4"
|
||||
>
|
||||
<div class="flex items-center mr-auto">
|
||||
<input id="remember-me" type="checkbox" class="form-check-input border mr-2" />
|
||||
<label class="cursor-pointer select-none" for="remember-me">Remember me</label>
|
||||
<input
|
||||
id="remember-me"
|
||||
type="checkbox"
|
||||
class="form-check-input border mr-2"
|
||||
/>
|
||||
<label class="cursor-pointer select-none" for="remember-me"
|
||||
>Remember me</label
|
||||
>
|
||||
</div>
|
||||
<a href="">Forgot Password?</a>
|
||||
</div>
|
||||
<div class="intro-x mt-5 xl:mt-8 text-center xl:text-left">
|
||||
<button class="btn btn-primary py-3 px-4 w-full xl:w-32 xl:mr-3 align-top" @click.prevent="onSubmit">
|
||||
<button
|
||||
class="btn btn-primary py-3 px-4 w-full xl:w-32 xl:mr-3 align-top"
|
||||
@click.prevent="onSubmit"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary py-3 px-4 w-full xl:w-32 mt-3 xl:mt-0 align-top">
|
||||
<button
|
||||
class="btn btn-outline-secondary py-3 px-4 w-full xl:w-32 mt-3 xl:mt-0 align-top"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div class="intro-x mt-10 xl:mt-24 text-slate-600 dark:text-slate-500 text-center xl:text-left">
|
||||
<div
|
||||
class="intro-x mt-10 xl:mt-24 text-slate-600 dark:text-slate-500 text-center xl:text-left"
|
||||
>
|
||||
By signin up, you agree to our
|
||||
<a class="text-primary dark:text-slate-200" href="">Terms and Conditions</a>
|
||||
<a class="text-primary dark:text-slate-200" href=""
|
||||
>Terms and Conditions</a
|
||||
>
|
||||
&
|
||||
<a class="text-primary dark:text-slate-200" href="">Privacy Policy</a>
|
||||
<a class="text-primary dark:text-slate-200" href=""
|
||||
>Privacy Policy</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -68,16 +130,36 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from "vue";
|
||||
import { onMounted, reactive, toRefs } from "vue";
|
||||
import DarkModeSwitcher from "@/components/dark-mode-switcher/Main.vue";
|
||||
import dom from "@left4code/tw-starter/dist/js/dom";
|
||||
import { useAuthStore } from '@/stores'
|
||||
import { useVuelidate } from "@vuelidate/core";
|
||||
import { required, minLength, email } from "@vuelidate/validators";
|
||||
import { useAuthStore } from "@/stores";
|
||||
|
||||
const formData = reactive({
|
||||
email: "",
|
||||
password: "",
|
||||
});
|
||||
|
||||
const rules = {
|
||||
email: {
|
||||
required,
|
||||
email,
|
||||
},
|
||||
|
||||
password: {
|
||||
required,
|
||||
minLength: minLength(8),
|
||||
},
|
||||
};
|
||||
|
||||
const validate = useVuelidate(rules, toRefs(formData));
|
||||
|
||||
const onSubmit = () => {
|
||||
console.log("onSubmit");
|
||||
console.log("onSubmit", formData.email, " ", formData.password);
|
||||
const authStore = useAuthStore();
|
||||
// const { username, password } = values;
|
||||
return authStore.login("ilmedovamahri@gmail.com", "12345678");
|
||||
return authStore.login(formData.email, formData.password);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue