feat: add withdraw request functionality and UI components

This commit is contained in:
2026-08-27 02:39:57 +03:30
parent aeef95339d
commit 4ce663c669
115 changed files with 4064 additions and 315 deletions
@@ -1,14 +1,47 @@
<script setup>
import { ref } from 'vue';
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 ArrowDownSvg from '../svg/arrowDown.svg';
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>
@@ -39,17 +72,63 @@ const toggleSidebar = () => {
/>
</div>
</div>
<div class="flex gap-4">
<div class="flex items-center gap-4">
<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="flex flex-col max-sm:hidden">
<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="flex items-center justify-center border-l-[1px] !border-dominant-50 pl-4">
<GlobalSvg />
</div>
<div class="grid grid-cols-2a justify-start items-center gap-2">
<span class="text-dominant-300 text-[12px] font-normal">
{{ globalStore.current_user.fullname }}
</span>
<ArrowDownSvg class="!w-4 !h-4 flex -mt-0.5"/>
<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 max-sm:hidden">
{{ 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>