129 lines
6.9 KiB
Vue
129 lines
6.9 KiB
Vue
<script setup>
|
|
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
|
|
import { Link, usePage } from '@inertiajs/inertia-vue3';
|
|
import { useGlobalStore } from '../../store/Global';
|
|
import UiInput from '../ui/UiInput.vue';
|
|
import GlobalSvg from '../svg/global.svg';
|
|
import EditProfileModal from '../dashboard/EditProfileModal.vue';
|
|
import { formatPrice } from '../../utils/numberUtils';
|
|
const globalStore = useGlobalStore();
|
|
const { props } = usePage();
|
|
|
|
const walletBalance = computed(() => formatPrice(props.value.auth?.wallet_balance || 0));
|
|
|
|
const toggleSidebar = () => {
|
|
globalStore.sidebarOpen = !globalStore.sidebarOpen;
|
|
};
|
|
|
|
const userMenuOpen = ref(false);
|
|
const userMenuRef = ref(null);
|
|
const editProfileVisible = ref(false);
|
|
|
|
const toggleUserMenu = () => {
|
|
userMenuOpen.value = !userMenuOpen.value;
|
|
};
|
|
|
|
const openEditProfile = () => {
|
|
userMenuOpen.value = false;
|
|
editProfileVisible.value = true;
|
|
};
|
|
|
|
const closeOnClickOutside = (event) => {
|
|
if (userMenuRef.value && !userMenuRef.value.contains(event.target)) {
|
|
userMenuOpen.value = false;
|
|
}
|
|
};
|
|
|
|
onMounted(() => document.addEventListener('click', closeOnClickOutside));
|
|
onBeforeUnmount(() => document.removeEventListener('click', closeOnClickOutside));
|
|
|
|
const menuItems = [
|
|
{ label: 'کیف پول', icon: 'fi-rr-wallet', href: '/dashboard/wallet' },
|
|
{ label: 'فاکتورها', icon: 'fi-rr-receipt', href: '/dashboard/invoices' },
|
|
{ label: 'برنامه شیفتها', icon: 'fi-rr-calendar-clock', href: '/dashboard/shifts' },
|
|
];
|
|
</script>
|
|
|
|
<template>
|
|
<header class="flex items-center gap-3 sm:gap-4 shadow-client-gray/10 px-4 lg:!ps-[16rem] fixed top-0 left-0 right-0 z-20 w-full h-[4.5rem] bg-white">
|
|
<Button
|
|
icon="fi-rr-menu-burger"
|
|
class="lg:!hidden !w-10 !h-10 shrink-0 !border-dominant-50"
|
|
pt:icon="flex !text-dominant-300 justify-center items-center"
|
|
variant="outlined"
|
|
size="large"
|
|
@click="toggleSidebar"
|
|
/>
|
|
<div class="flex-1 min-w-0 max-w-[30rem]">
|
|
<UiInput
|
|
placeholder="جستجو سریع: نام سرپرست، نام حیوان و یا شماره پرونده"
|
|
variant="outlined"
|
|
prefixClasses="!border-dominant-50"
|
|
class="!w-full"
|
|
prefixColor="dominant-700"
|
|
iconStart="svg:SearchSvg"
|
|
wrapperBorderClass="!border-dominant-50"
|
|
customClass="placeholder:!text-dominant-300 !border-dominant-50 !font-normal !text-[11px] truncate"
|
|
/>
|
|
</div>
|
|
<div class="flex items-center gap-2 sm:gap-4 shrink-0 ms-auto">
|
|
<Link href="/dashboard/wallet" class="flex items-center gap-2.5 rounded-lg bg-dominant-light border border-dominant-50 ps-1.5 pe-3 py-1.5 transition-colors hover:border-dominant-100">
|
|
<span class="flex items-center justify-center w-8 h-8 rounded-lg bg-white border border-dominant-50 text-dominant-400">
|
|
<i class="fi fi-rr-wallet flex text-[15px]"></i>
|
|
</span>
|
|
<span class="hidden md:flex flex-col">
|
|
<span class="text-[10px] font-normal text-dominant-200">موجودی کیف پول</span>
|
|
<span class="text-[12px] font-bold text-dominant-500">{{ walletBalance }} <span class="text-[10px] font-normal text-dominant-300">تومان</span></span>
|
|
</span>
|
|
</Link>
|
|
<div class="hidden sm:flex items-center justify-center border-l-[1px] !border-dominant-50 pl-4">
|
|
<GlobalSvg />
|
|
</div>
|
|
<div ref="userMenuRef" class="relative">
|
|
<button type="button" class="flex items-center gap-2 cursor-pointer" @click="toggleUserMenu">
|
|
<span class="flex items-center justify-center w-9 h-9 rounded-full bg-dominant-light border border-dominant-50 overflow-hidden">
|
|
<img v-if="globalStore.current_user.profile_url" :src="globalStore.current_user.profile_url" alt="تصویر پروفایل" class="w-full h-full object-cover" />
|
|
<i v-else class="fi fi-rr-user flex text-sm text-dominant-300"></i>
|
|
</span>
|
|
<span class="text-dominant-300 text-[12px] font-normal hidden md:inline">
|
|
{{ globalStore.current_user.fullname }}
|
|
</span>
|
|
<i class="fi fi-rr-angle-small-down flex text-sm text-dominant-300 transition-transform duration-200" :class="{ 'rotate-180': userMenuOpen }"></i>
|
|
</button>
|
|
<Transition
|
|
enter-active-class="transition duration-150 ease-out"
|
|
enter-from-class="opacity-0 -translate-y-1"
|
|
enter-to-class="opacity-100 translate-y-0"
|
|
leave-active-class="transition duration-100 ease-in"
|
|
leave-from-class="opacity-100 translate-y-0"
|
|
leave-to-class="opacity-0 -translate-y-1"
|
|
>
|
|
<nav v-if="userMenuOpen" class="absolute left-0 top-full mt-2 w-52 rounded-xl bg-white border border-complement-100 shadow-all py-2 z-30">
|
|
<ul class="flex flex-col">
|
|
<li>
|
|
<button type="button" class="w-full flex items-center gap-2.5 px-4 py-2.5 text-[12px] font-normal text-complement-900 cursor-pointer transition-colors hover:bg-complement-50" @click="openEditProfile">
|
|
<i class="fi fi-rr-user-pen flex text-[14px] text-complement-700"></i>
|
|
ویرایش حساب کاربری
|
|
</button>
|
|
</li>
|
|
<li v-for="item in menuItems" :key="item.href">
|
|
<Link :href="item.href" class="flex items-center gap-2.5 px-4 py-2.5 text-[12px] font-normal text-complement-900 transition-colors hover:bg-complement-50" @click="userMenuOpen = false">
|
|
<i class="fi flex text-[14px] text-complement-700" :class="item.icon"></i>
|
|
{{ item.label }}
|
|
</Link>
|
|
</li>
|
|
<li class="border-t border-complement-100 mt-1 pt-1">
|
|
<Link href="/dashboard/logout" class="flex items-center gap-2.5 px-4 py-2.5 text-[12px] font-normal text-dominant-400 transition-colors hover:bg-dominant-light">
|
|
<i class="fi fi-rr-sign-out-alt flex text-[14px]"></i>
|
|
خروج از حساب
|
|
</Link>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</Transition>
|
|
</div>
|
|
</div>
|
|
<EditProfileModal v-model:visible="editProfileVisible" />
|
|
</header>
|
|
</template>
|