admin user and ui panel

This commit is contained in:
s.esmaeili
2026-09-21 08:32:31 +03:30
parent 79226c9f13
commit ef1d4638cc
341 changed files with 2270 additions and 657 deletions
@@ -24,7 +24,7 @@
</div>
<div class="nav-right">
<a-dropdown>
<a-dropdown trigger="click" placement="bottomRight" :overlay-class-name="'user-dropdown-overlay'">
<span class="user-chip">
<a-avatar size="small" style="background-color: #1c2d56">
{{ initial }}
@@ -32,13 +32,39 @@
<span class="user-name">{{ displayName }}</span>
</span>
<template #overlay>
<a-menu>
<a-menu-item key="my-data" @click="router.push('/my-data')">
اطلاعات من
</a-menu-item>
<a-menu-divider />
<a-menu-item key="logout" @click="onLogout">خروج</a-menu-item>
</a-menu>
<div class="user-card">
<div class="user-card__head">
<a-avatar size="large" style="background-color: #1c2d56">
{{ initial }}
</a-avatar>
<div class="user-card__id">
<span class="user-card__name">{{ displayName }}</span>
<span class="user-card__mobile">{{ auth.user?.mobile }}</span>
</div>
</div>
<a-divider class="user-card__divider" />
<a-menu class="user-card__menu">
<a-menu-item key="my-data" @click="router.push('/my-data')">
<UserOutlined />
اطلاعات من
</a-menu-item>
<a-menu-item v-if="canSeePermissions" key="permission" @click="router.push('/permission')">
<SafetyCertificateOutlined />
دسترسی ها
</a-menu-item>
</a-menu>
<a-divider class="user-card__divider" />
<a-menu class="user-card__menu">
<a-menu-item key="logout" @click="onLogout">
<LogoutOutlined />
خروج
</a-menu-item>
</a-menu>
</div>
</template>
</a-dropdown>
</div>
@@ -48,8 +74,15 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
import {
LogoutOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
SafetyCertificateOutlined,
UserOutlined,
} from '@ant-design/icons-vue';
import { useAuthStore } from '../../stores/auth';
import { useUsersStore } from '../../stores/users';
interface Crumb {
title: string;
@@ -63,11 +96,13 @@ defineEmits<{ (e: 'toggle-sidebar'): void }>();
const route = useRoute();
const router = useRouter();
const auth = useAuthStore();
const users = useUsersStore();
const pageTitle = computed(() => (route.meta?.pageTitle as string) ?? '');
const breadcrumb = computed(() => route.meta?.breadcrumb as Crumb[] | undefined);
const displayName = computed(() => auth.user?.name ?? auth.user?.fullName ?? 'کاربر');
const initial = computed(() => displayName.value.trim().charAt(0) || 'ک');
const canSeePermissions = computed(() => Boolean(users.hasPermission('user.permission')));
function onLogout() {
auth.logout();
@@ -105,3 +140,84 @@ function onLogout() {
cursor: pointer;
}
</style>
<!--
Unscoped: ant-design-vue's <a-dropdown> teleports its #overlay to <body>, so
a `scoped` block (which relies on a component-instance data attribute) never
matches it. Reach is contained instead by :overlay-class-name="'user-dropdown-overlay'"
above, so every selector below is namespaced under that one class.
-->
<style>
.user-dropdown-overlay .ant-dropdown-menu {
padding: 0;
box-shadow: none;
}
.user-dropdown-overlay .user-card {
width: 220px;
padding: 12px;
background: #fff;
border-radius: 10px;
box-shadow: 0 8px 28px -8px rgba(28, 45, 86, 0.28);
}
.user-dropdown-overlay .user-card__head {
display: flex;
align-items: center;
gap: 10px;
padding: 2px 4px 8px;
}
.user-dropdown-overlay .user-card__id {
display: flex;
flex-direction: column;
min-width: 0;
}
.user-dropdown-overlay .user-card__name {
font-size: 14px;
font-weight: 600;
color: #1c2d56;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.user-dropdown-overlay .user-card__mobile {
font-size: 12px;
color: #8a909c;
direction: ltr;
text-align: right;
}
.user-dropdown-overlay .user-card__divider {
margin: 4px 0;
}
.user-dropdown-overlay .user-card__menu.ant-menu {
border-inline-end: none;
background: transparent;
}
.user-dropdown-overlay .user-card__menu .ant-menu-item {
display: flex;
align-items: center;
gap: 8px;
height: 34px;
line-height: 34px;
margin: 0;
padding-inline: 6px !important;
border-radius: 6px;
width: 100%;
}
.user-dropdown-overlay .user-card__menu .ant-menu-item:hover {
background: #f4f5f6;
color: #1c2d56;
}
.user-dropdown-overlay .user-card__menu .anticon {
font-size: 15px;
color: #8a909c;
}
</style>