feat: complete UI/UX improvements, vuesax icons, media server, and section management
This commit is contained in:
@@ -110,7 +110,8 @@ onMounted(load);
|
||||
</a-button>
|
||||
</PageHeader>
|
||||
|
||||
<a-card :body-style="{ padding: 0 }">
|
||||
<!-- Desktop Table (Preserved for lg+) -->
|
||||
<a-card :body-style="{ padding: 0 }" class="max-lg:hidden">
|
||||
<a-table :columns="columns" :data-source="rows" :loading="loading" row-key="id" :pagination="false" :scroll="{ x: 700 }">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'phone'"><span dir="ltr">{{ record.phone }}</span></template>
|
||||
@@ -139,6 +140,155 @@ onMounted(load);
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<!-- Mobile User Cards (App Experience for <lg) -->
|
||||
<div class="lg:hidden space-y-3">
|
||||
<a-spin :spinning="loading">
|
||||
<div v-if="!rows.length && !loading" class="rounded-xl border border-dashed border-gray-200 bg-white p-8 text-center">
|
||||
<div class="text-sm text-gray-500">کاربری یافت نشد</div>
|
||||
</div>
|
||||
<div v-else class="space-y-3">
|
||||
<div
|
||||
v-for="user in rows"
|
||||
:key="user.id"
|
||||
class="rounded-xl border border-gray-100 bg-white p-4 shadow-sm transition-all"
|
||||
>
|
||||
<!-- Header: User Avatar & Role Tag -->
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="flex size-11 flex-shrink-0 items-center justify-center rounded-full font-bold text-white shadow-sm"
|
||||
:class="user.role === 'ADMIN' ? 'bg-gradient-to-tr from-orange-600 to-amber-500' : 'bg-gradient-to-tr from-blue-600 to-sky-500'"
|
||||
>
|
||||
{{ user.name.slice(0, 1) }}
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-bold text-gray-900">{{ user.name }}</div>
|
||||
<a
|
||||
:href="`tel:${user.phone}`"
|
||||
class="mt-0.5 inline-block text-xs font-mono text-gray-500 hover:text-orange-600"
|
||||
dir="ltr"
|
||||
>
|
||||
{{ user.phone }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-end gap-1">
|
||||
<a-tag :color="user.role === 'ADMIN' ? 'orange' : 'blue'" class="!m-0 text-[11px]">
|
||||
{{ ROLE_LABELS[user.role as keyof typeof ROLE_LABELS] }}
|
||||
</a-tag>
|
||||
<a-tag :color="user.isActive ? 'green' : 'default'" class="!m-0 text-[10px]">
|
||||
{{ user.isActive ? "فعال" : "غیرفعال" }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Meta & Actions -->
|
||||
<div class="mt-3.5 flex items-center justify-between border-t border-gray-100 pt-3 text-xs text-gray-400">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<span>آخرین ورود:</span>
|
||||
<span class="font-medium text-gray-600">{{ jalali(user.lastLoginAt) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1.5">
|
||||
<a-button size="small" class="!flex !items-center !gap-1" @click="openEdit(user)">
|
||||
<template #icon><VuesaxIcon name="edit-2" :size="14" /></template>
|
||||
<span>ویرایش</span>
|
||||
</a-button>
|
||||
|
||||
<a-popconfirm
|
||||
v-if="user.id !== auth.user?.id"
|
||||
title="این کاربر حذف شود؟"
|
||||
ok-text="حذف"
|
||||
cancel-text="انصراف"
|
||||
@confirm="remove(user)"
|
||||
>
|
||||
<a-button size="small" danger class="!px-2">
|
||||
<template #icon><VuesaxIcon name="trash" :size="14" /></template>
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Floating Action Button (FAB) for New User -->
|
||||
<button
|
||||
type="button"
|
||||
class="lg:hidden fixed bottom-20 left-4 z-30 flex size-13 items-center justify-center rounded-full bg-[#ff5a00] text-white shadow-lg shadow-orange-500/30 transition-transform active:scale-95"
|
||||
title="کاربر جدید"
|
||||
@click="openNew"
|
||||
>
|
||||
<VuesaxIcon name="add" :size="24" />
|
||||
</button>
|
||||
|
||||
<!-- Mobile Collapsible Role Permissions Guide -->
|
||||
<details class="lg:hidden mt-4 rounded-xl border border-gray-200 bg-white p-3 text-xs shadow-sm">
|
||||
<summary class="cursor-pointer font-bold text-gray-700 flex items-center justify-between select-none">
|
||||
<span class="flex items-center gap-1.5">
|
||||
<VuesaxIcon name="info-circle" :size="16" class="text-orange-500" />
|
||||
راهنمای نقشها و مجوزهای دسترسی
|
||||
</span>
|
||||
<span class="text-gray-400 text-[10px]">لمس برای مشاهده</span>
|
||||
</summary>
|
||||
<div class="mt-3 space-y-3 pt-3 border-t border-gray-100">
|
||||
<div class="rounded-lg border border-orange-200 bg-orange-50/40 p-2.5">
|
||||
<div class="flex items-center gap-2 font-bold text-orange-700">
|
||||
<a-tag color="orange">مدیر کل (ADMIN)</a-tag>
|
||||
<span class="text-[11px]">دسترسی ارشد سیستمی</span>
|
||||
</div>
|
||||
<ul class="mt-2 space-y-1 text-[11px] text-gray-600 list-disc list-inside">
|
||||
<li>مدیریت کاربران، نقشها و تنظیمات امنیتی</li>
|
||||
<li>تنظیمات پایه سایت، سئو، شبکهها و ساعات کاری</li>
|
||||
<li>حذف دادهها (محصولات، دستهها، پیامها، رسانهها)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border border-blue-200 bg-blue-50/40 p-2.5">
|
||||
<div class="flex items-center gap-2 font-bold text-blue-700">
|
||||
<a-tag color="blue">ویرایشگر (EDITOR)</a-tag>
|
||||
<span class="text-[11px]">دسترسی محتوایی</span>
|
||||
</div>
|
||||
<ul class="mt-2 space-y-1 text-[11px] text-gray-600 list-disc list-inside">
|
||||
<li>ایجاد، ویرایش و انتشار محصولات و دستهبندیها</li>
|
||||
<li>ویرایش محتوای بخشهای صفحه اصلی</li>
|
||||
<li>آپلود تصاویر در رسانه و مشاهده پیامهای تماس</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Desktop Role Permissions Reference Cards -->
|
||||
<div class="mt-6 max-lg:hidden grid gap-4 md:grid-cols-2">
|
||||
<a-card size="small" class="border-orange-200 bg-orange-50/30">
|
||||
<div class="flex items-center gap-2 font-bold text-orange-700">
|
||||
<a-tag color="orange">مدیر کل (ADMIN)</a-tag>
|
||||
<span class="text-xs">دسترسی ارشد سیستمی</span>
|
||||
</div>
|
||||
<ul class="mt-2.5 space-y-1.5 text-xs text-gray-600 list-disc list-inside">
|
||||
<li>مدیریت کاربران، افزودن کاربر و تغییر نقشها و وضعیت حساب</li>
|
||||
<li>دسترسی کامل به تنظیمات پایه سایت، ساعات کاری، شبکهها و سئو</li>
|
||||
<li>مجوز حذف محصولات، دستهبندیها، رسانهها و پیامهای تماس</li>
|
||||
<li>مشاهده لاگهای امنیتی و رویدادهای کامل سامانه</li>
|
||||
</ul>
|
||||
</a-card>
|
||||
|
||||
<a-card size="small" class="border-blue-200 bg-blue-50/30">
|
||||
<div class="flex items-center gap-2 font-bold text-blue-700">
|
||||
<a-tag color="blue">ویرایشگر (EDITOR)</a-tag>
|
||||
<span class="text-xs">دسترسی محتوایی</span>
|
||||
</div>
|
||||
<ul class="mt-2.5 space-y-1.5 text-xs text-gray-600 list-disc list-inside">
|
||||
<li>ایجاد، ویرایش، کپی و انتشار محصولات و گروهها</li>
|
||||
<li>ویرایش محتوای بخشهای صفحه اصلی و فعال/مخفیسازی نمایش آنها</li>
|
||||
<li>آپلود و ویرایش اطلاعات رسانهها در کتابخانه رسانه</li>
|
||||
<li>مشاهده پیامهای تماس و بهروزرسانی وضعیت (بدون دسترسی حذف یا مدیریت کاربران)</li>
|
||||
</ul>
|
||||
</a-card>
|
||||
</div>
|
||||
|
||||
<a-modal
|
||||
:open="editing !== null"
|
||||
:title="isNew ? 'کاربر جدید' : 'ویرایش کاربر'"
|
||||
@@ -168,6 +318,9 @@ onMounted(load);
|
||||
:disabled="editing === auth.user?.id"
|
||||
:options="ROLE_OPTIONS"
|
||||
/>
|
||||
<div class="mt-1.5 text-[11px] text-gray-500">
|
||||
{{ model.role === 'ADMIN' ? 'مدیر کل: دسترسی کامل سیستمی، حذف دادهها، تنظیمات و مدیریت کاربران' : 'ویرایشگر: ویرایش محتوا، محصولات، بخشها و پیامها (بدون حذف)' }}
|
||||
</div>
|
||||
</FormField>
|
||||
<FormField v-if="!isNew" path="isActive">
|
||||
<a-checkbox v-model:checked="model.isActive" :disabled="editing === auth.user?.id">حساب فعال است</a-checkbox>
|
||||
|
||||
Reference in New Issue
Block a user