Merge pull request 'Fix for loader' (#2) from atamrakar/Dolphin-Frontent-Boilerplate:loader_fix into dev

Reviewed-on: Mavorion/Dolphin-Frontent-Boilerplate#2
This commit is contained in:
Sandip Ghimire 2026-01-06 15:53:09 +05:45
commit 3695e6b6af
5 changed files with 45 additions and 43 deletions

View File

@ -60,11 +60,6 @@ const authChildren: Array<RouteRecordRaw> = [
name: "loader", name: "loader",
component: () => import("@/views/Components/Loader.vue"), component: () => import("@/views/Components/Loader.vue"),
}, },
{
path: "image-cropper",
name: "image-cropper",
component: () => import("@/views/Components/ImageCropper.vue"),
},
], ],
}, },
{ {

View File

@ -2,18 +2,28 @@ import { defineStore } from "pinia";
export const useLoader = defineStore("loader", { export const useLoader = defineStore("loader", {
state: () => ({ state: () => ({
loader: false, loader: {} as Record<string, boolean>,
}), }),
getters: { getters: {
isLoading(state) { isLoading(state) {
return state.loader; return (key: string): boolean => {
return state.loader[key] === true;
};
}, },
}, },
actions: { actions: {
setLoaderStatus(value: boolean) { start(key: string) {
this.loader = value; if (!key) return;
this.loader[key] = true;
},
stop(key: string) {
if (!key) return;
if (!(key in this.loader)) return;
this.loader[key] = false;
}, },
}, },
}); });

View File

@ -10,59 +10,73 @@ export const useAuth = defineStore("auth", {
loginDetails: {} as LoginDetails, loginDetails: {} as LoginDetails,
isAuthenticated: false, isAuthenticated: false,
user: {} as UserDetails, user: {} as UserDetails,
loginError: false,
}), }),
getters: { getters: {
getLoginDetails(state) { getLoginDetails(state) {
return state.loginDetails; return state.loginDetails;
}, },
getLoginError(state) {
return state.loginError;
},
}, },
actions: { actions: {
async login() { async login() {
const loaderStore = useLoader(); const loaderStore = useLoader();
loaderStore.setLoaderStatus(true); loaderStore.start("login");
await api await api
.post(auth.login, this.loginDetails) .post(auth.login, this.loginDetails)
.then(() => { .then(() => {
loaderStore.setLoaderStatus(false); loaderStore.stop("login");
this.isAuthenticated = true; this.isAuthenticated = true;
router.push({ name: "dashboard" }); router.push({ name: "dashboard" });
}) })
.catch(() => { .catch(() => {
loaderStore.setLoaderStatus(false); loaderStore.stop("login");
this.isAuthenticated = false; this.isAuthenticated = false;
this.hasLoginError();
}); });
}, },
async getUser() { async getUser() {
const loaderStore = useLoader(); const loaderStore = useLoader();
loaderStore.setLoaderStatus(true); loaderStore.start("getUser");
await api await api
.get(user.self) .get(user.self)
.then((e) => { .then((e) => {
this.user = e.data.data; this.user = e.data.data;
loaderStore.setLoaderStatus(false); loaderStore.stop("getUser");
this.isAuthenticated = true; this.isAuthenticated = true;
}) })
.catch(() => { .catch(() => {
this.user = {} as UserDetails; this.user = {} as UserDetails;
loaderStore.setLoaderStatus(false); loaderStore.stop("getUser");
this.isAuthenticated = false; this.isAuthenticated = false;
}); });
}, },
async logout() { async logout() {
const loaderStore = useLoader(); const loaderStore = useLoader();
loaderStore.setLoaderStatus(true); loaderStore.start("logout");
await api await api
.post(auth.logout) .post(auth.logout)
.then(() => { .then(() => {
this.isAuthenticated = false; this.isAuthenticated = false;
router.push({ name: "login" }); router.push({ name: "login" });
loaderStore.stop("logout");
}) })
.catch((e) => { .catch((e) => {
console.log(e); console.log(e);
}); });
}, },
hasLoginError(status: boolean = true) {
if (status) {
this.loginError = true;
setTimeout(() => {
this.loginError = false;
}, 5000);
}
},
}, },
}); });

View File

@ -5,13 +5,16 @@
<img src="/img/Dolphin/dolphin-logo.png" class="w-36 my-5" /> <img src="/img/Dolphin/dolphin-logo.png" class="w-36 my-5" />
</div> </div>
<div class="border border-[#99A1AF] rounded-xs px-10 py-10 bg-white select-none"> <div class="border border-[#99A1AF] rounded-xs px-10 py-10 bg-white select-none">
<div class="text-center" :class="getLoginError ? '' : 'mb-[10px]'"> <div class="text-center mb-[10px]">
<p class="text-[30px] text-semibold">Sign In</p> <p class="text-[30px] text-semibold">Sign In</p>
<div class="text-sm font-normal">Fill your detail to sign in to Dolphin PIS.</div> <div class="text-sm font-normal">Fill your detail to sign in to Dolphin PIS.</div>
</div> </div>
<div class="mt-[12px] mb-[-19px]" v-if="getLoginError"> <div class="mt-[12px] mb-[-19px] h-[20px]">
<div class="text-sm text-red-700 font-semibold text-center flex gap-[10px]"> <div
v-if="getLoginError"
class="text-sm text-red-700 font-semibold text-center flex gap-[10px] justify-center"
>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20" viewBox="0 0 20 20"
@ -76,7 +79,7 @@
<button <button
type="submit" type="submit"
class="btn btn-primary w-full max-h-[40px]! h-[40px]! text-lg!" class="btn btn-primary w-full max-h-[40px]! h-[40px]! text-lg!"
:class="isLoading ? 'btn-loading' : ''" :class="loaderStore.isLoading('login') ? 'btn-loading' : ''"
> >
Sign In Sign In
</button> </button>
@ -85,7 +88,7 @@
<div class="text-xs text-center my-5 select-none"> <div class="text-xs text-center my-5 select-none">
<div> <div>
© 2024 © {{ dateYear }}
<a href="https://mavorion.com" class="text-[#224CAD] underline">Mavorion Systems</a> <a href="https://mavorion.com" class="text-[#224CAD] underline">Mavorion Systems</a>
. All rights reserved. . All rights reserved.
</div> </div>
@ -101,10 +104,9 @@ import { ref } from "vue";
const authStore = useAuth(); const authStore = useAuth();
const loaderStore = useLoader(); const loaderStore = useLoader();
const { loginDetails } = storeToRefs(authStore); const { loginDetails, getLoginError } = storeToRefs(authStore);
const { isLoading } = storeToRefs(loaderStore);
const showPassword = ref(false); const showPassword = ref(false);
const getLoginError = ""; const dateYear = new Date().getFullYear();
</script> </script>

View File

@ -1,19 +0,0 @@
<template>
<button class="btn btn-primary" @click="showModal = true">Open Modal</button>
<UploadImage :show="showModal" @onClose="showModal = false" @onCrop="handleCrop" :uploadSize="2" />
<img :src="croppedImageVal" alt="" />
</template>
<script setup lang="ts">
import { UploadImage } from "dolphin-components";
import { ref } from "vue";
const showModal = ref(false);
const croppedImageVal = ref("");
const handleCrop = (croppedImage: string) => {
croppedImageVal.value = croppedImage;
console.log("Cropped Image:", croppedImage);
showModal.value = false;
};
</script>