189 lines
5.9 KiB
Vue
189 lines
5.9 KiB
Vue
<template>
|
|
<div
|
|
id="account_menu"
|
|
v-if="isAcctMenuOpen"
|
|
class="absolute top-0 w-[232px] bg-white right-[0px] rounded shadow-lg bg-[#ffffff]"
|
|
>
|
|
<div id="greeting" class="w-full border-b border-[#CBD5E1]">
|
|
<span class="m-4 h-[48px]">
|
|
{{ i18next.t("AcctMgmt.hi") }}{{ userData.name }}
|
|
</span>
|
|
</div>
|
|
<ul class="w-full min-h-10">
|
|
<!-- Not using a loop here because SVGs won't display if src is a variable -->
|
|
<li
|
|
v-if="isAdmin"
|
|
id="btn_acct_mgmt"
|
|
class="w-full h-[40px] flex py-2 px-4 hover:text-[#000000] hover:bg-[#F1F5F9] cursor-pointer items-center"
|
|
@click="onBtnAcctMgmtClick"
|
|
>
|
|
<span class="w-[24px] h-[24px] flex"
|
|
><img src="@/assets/icon-crown.svg" alt="accountManagement"
|
|
/></span>
|
|
<span class="flex ml-[8px]">{{ i18next.t("AcctMgmt.acctMgmt") }}</span>
|
|
</li>
|
|
<li
|
|
id="btn_mang_ur_acct"
|
|
class="w-full h-[40px] flex py-2 px-4 hover:text-[#000000] hover:bg-[#F1F5F9] cursor-pointer items-center"
|
|
@click="onBtnMyAccountClick"
|
|
>
|
|
<span class="w-[24px] h-[24px] flex"
|
|
><img src="@/assets/icon-head-black.svg" alt="head-black"
|
|
/></span>
|
|
<span class="flex ml-[8px]">{{
|
|
i18next.t("AcctMgmt.mangUrAcct")
|
|
}}</span>
|
|
</li>
|
|
<li
|
|
id="btn_logout_in_menu"
|
|
class="w-full h-[40px] flex py-2 px-4 hover:text-[#000000] hover:bg-[#F1F5F9] cursor-pointer items-center"
|
|
@click="onLogoutBtnClick"
|
|
>
|
|
<span class="w-[24px] h-[24px] flex"
|
|
><img src="@/assets/icon-logout.svg" alt="logout"
|
|
/></span>
|
|
<span class="flex ml-[8px]">{{ i18next.t("AcctMgmt.Logout") }}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
// The Lucia project.
|
|
// Copyright 2024-2026 DSP, inc. All rights reserved.
|
|
// Authors:
|
|
// cindy.chang@dsp.im (Cindy Chang), 2024/5/30
|
|
// imacat.yang@dsp.im (imacat), 2023/9/23
|
|
/**
|
|
* @module components/AccountMenu/AcctMenu Dropdown account menu
|
|
* with links to account management, my account, and logout.
|
|
*/
|
|
|
|
import { computed, onMounted, onBeforeUnmount, ref } from "vue";
|
|
import { storeToRefs } from "pinia";
|
|
import i18next from "@/i18n/i18n";
|
|
import { useRouter, useRoute } from "vue-router";
|
|
import { useLoginStore } from "@/stores/login";
|
|
import { useAcctMgmtStore } from "@/stores/acctMgmt";
|
|
import { useAllMapDataStore } from "@/stores/allMapData";
|
|
import { useConformanceStore } from "@/stores/conformance";
|
|
import { leaveFilter, leaveConformance } from "@/module/alertModal.js";
|
|
import emitter from "@/utils/emitter";
|
|
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
const loginStore = useLoginStore();
|
|
const allMapDataStore = useAllMapDataStore();
|
|
const conformanceStore = useConformanceStore();
|
|
const acctMgmtStore = useAcctMgmtStore();
|
|
|
|
const { logOut } = loginStore;
|
|
const { tempFilterId } = storeToRefs(allMapDataStore);
|
|
const { conformanceLogTempCheckId, conformanceFilterTempCheckId } =
|
|
storeToRefs(conformanceStore);
|
|
const { userData } = storeToRefs(loginStore);
|
|
const { isAcctMenuOpen } = storeToRefs(acctMgmtStore);
|
|
|
|
const loginUserData = ref(null);
|
|
const currentViewingUserDetail = computed(
|
|
() => acctMgmtStore.currentViewingUser.detail,
|
|
);
|
|
const isAdmin = ref(false);
|
|
|
|
/** Fetches user data and determines if the current user is an admin. */
|
|
const getIsAdminValue = async () => {
|
|
try {
|
|
await loginStore.getUserData();
|
|
loginUserData.value = loginStore.userData;
|
|
await acctMgmtStore.getUserDetail(loginUserData.value.username);
|
|
isAdmin.value = acctMgmtStore.currentViewingUser.is_admin;
|
|
} catch (error) {
|
|
console.error("Failed to fetch admin status:", error);
|
|
}
|
|
};
|
|
|
|
/** Navigates to the My Account page. */
|
|
const onBtnMyAccountClick = async () => {
|
|
try {
|
|
acctMgmtStore.closeAcctMenu();
|
|
await acctMgmtStore.getAllUserAccounts(); // in case we haven't fetched yet
|
|
await acctMgmtStore.setCurrentViewingUser(loginUserData.value.username);
|
|
await router.push("/my-account");
|
|
} catch (error) {
|
|
console.error("Failed to navigate to My Account:", error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Closes the menu when clicking outside. Stored as a named
|
|
* function so it can be removed in onBeforeUnmount.
|
|
* @param {MouseEvent} event - The click event.
|
|
*/
|
|
const handleDocumentClick = (event) => {
|
|
const acctMgmtButton = document.getElementById("acct_mgmt_button");
|
|
const acctMgmtMenu = document.getElementById("account_menu");
|
|
if (
|
|
acctMgmtMenu &&
|
|
acctMgmtButton &&
|
|
!acctMgmtMenu.contains(event.target) &&
|
|
!acctMgmtButton.contains(event.target)
|
|
) {
|
|
acctMgmtStore.closeAcctMenu();
|
|
}
|
|
};
|
|
|
|
/** Registers a click listener to close the menu when clicking outside. */
|
|
const clickOtherPlacesThenCloseMenu = () => {
|
|
document.addEventListener("click", handleDocumentClick);
|
|
};
|
|
|
|
/** Navigates to the Account Admin page. */
|
|
const onBtnAcctMgmtClick = () => {
|
|
router.push({ name: "AcctAdmin" });
|
|
acctMgmtStore.closeAcctMenu();
|
|
};
|
|
|
|
/** Handles logout with unsaved-changes confirmation for Map and Conformance pages. */
|
|
const onLogoutBtnClick = () => {
|
|
if (
|
|
(route.name === "Map" || route.name === "CheckMap") &&
|
|
tempFilterId.value
|
|
) {
|
|
// Notify Map to close the Sidebar.
|
|
emitter.emit("leaveFilter", false);
|
|
leaveFilter(false, allMapDataStore.addFilterId, false, logOut);
|
|
} else if (
|
|
(route.name === "Conformance" || route.name === "CheckConformance") &&
|
|
(conformanceLogTempCheckId.value || conformanceFilterTempCheckId.value)
|
|
) {
|
|
leaveConformance(
|
|
false,
|
|
conformanceStore.addConformanceCreateCheckId,
|
|
false,
|
|
logOut,
|
|
);
|
|
} else {
|
|
logOut();
|
|
}
|
|
};
|
|
|
|
// created
|
|
loginStore.getUserData();
|
|
|
|
// mounted
|
|
onMounted(async () => {
|
|
await getIsAdminValue();
|
|
clickOtherPlacesThenCloseMenu();
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
document.removeEventListener("click", handleDocumentClick);
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
#account_menu {
|
|
z-index: 2147483648;
|
|
}
|
|
</style>
|