737 lines
18 KiB
Vue
737 lines
18 KiB
Vue
<script setup lang="ts">
|
||||
|
|
import { computed } from 'vue'
|
|||
|
|
import { useRouter } from 'vue-router'
|
|||
|
|
import { useAuthStore } from '@/stores/auth'
|
|||
|
|
import { useOrderStore } from '@/stores/order'
|
|||
|
|
import IconChevronLeft from '@/components/icons/IconChevronLeft.vue'
|
|||
|
|
import IconEditPen from '@/components/icons/IconEditPen.vue'
|
|||
|
|
import IconOrders from '@/components/icons/IconOrders.vue'
|
|||
|
|
import IconCheckBook from '@/components/icons/IconCheckBook.vue'
|
|||
|
|
import IconCash from '@/components/icons/IconCash.vue'
|
|||
|
|
import IconBuilding from '@/components/icons/IconBuilding.vue'
|
|||
|
|
import IconBolt from '@/components/icons/IconBolt.vue'
|
|||
|
|
import IconSettings from '@/components/icons/IconSettings.vue'
|
|||
|
|
import IconProfile from '@/components/icons/IconProfile.vue'
|
|||
|
|
import IconBell from '@/components/icons/IconBell.vue'
|
|||
|
|
import IconMapPin from '@/components/icons/IconMapPin.vue'
|
|||
|
|
import IconHeadset from '@/components/icons/IconHeadset.vue'
|
|||
|
|
import IconCashSettlement from '@/components/icons/IconCashSettlement.vue'
|
|||
|
|
import IconPhone from '@/components/icons/IconPhone.vue'
|
|||
|
|
import IconMail from '@/components/icons/IconMail.vue'
|
|||
|
|
import IconVerified from '@/components/icons/IconVerified.vue'
|
|||
|
|
import IconLayoutGrid from '@/components/icons/IconLayoutGrid.vue'
|
|||
|
|
import IconLock from '@/components/icons/IconLock.vue'
|
|||
|
|
import IconIdCard from '@/components/icons/IconIdCard.vue'
|
|||
|
|
import UserAvatar from '@/components/ui/UserAvatar.vue'
|
|||
|
|
import { formatCurrency, formatDate, formatNumber, toPersianDigits } from '@/utils/format'
|
|||
|
|
import type { Component } from 'vue'
|
|||
|
|
|
|||
|
|
const router = useRouter()
|
|||
|
|
const auth = useAuthStore()
|
|||
|
|
const orderStore = useOrderStore()
|
|||
|
|
|
|||
|
|
const emit = defineEmits<{ logout: [] }>()
|
|||
|
|
|
|||
|
|
const initials = computed(() => {
|
|||
|
|
const first = auth.user?.firstName?.[0] ?? ''
|
|||
|
|
const last = auth.user?.lastName?.[0] ?? ''
|
|||
|
|
return `${first}${last}` || '؟'
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const ordersCount = computed(() => {
|
|||
|
|
if (!auth.user?.id) return 0
|
|||
|
|
return orderStore.userOrders(auth.user.id).length
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const checksCount = computed(() => {
|
|||
|
|
if (!auth.user?.id) return 0
|
|||
|
|
const submitted = orderStore
|
|||
|
|
.userOrders(auth.user.id)
|
|||
|
|
.reduce((sum, order) => sum + (order.checks?.length ?? 0), 0)
|
|||
|
|
return submitted + orderStore.draftChecks.length
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const customerCode = computed(() => {
|
|||
|
|
const u = auth.user
|
|||
|
|
if (!u) return toPersianDigits('—')
|
|||
|
|
if (auth.isAgent && u.agentCode) return toPersianDigits(u.agentCode)
|
|||
|
|
if (u.nationalId) return toPersianDigits(u.nationalId.slice(-6).padStart(6, '0'))
|
|||
|
|
return toPersianDigits(u.id?.slice(-6) ?? '—')
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const codeLabel = computed(() => (auth.isAgent ? 'کد واسطه:' : 'کد مشتری:'))
|
|||
|
|
|
|||
|
|
const displayEmail = computed(() => {
|
|||
|
|
const phone = auth.user?.phone ?? ''
|
|||
|
|
if (!phone) return '—'
|
|||
|
|
return `user${phone.slice(-4)}@parsbaft.ir`
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const joinDate = computed(() =>
|
|||
|
|
auth.user?.createdAt ? formatDate(auth.user.createdAt) : '—',
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const creditBalance = computed(() => 0)
|
|||
|
|
|
|||
|
|
const companyRows = computed(() => [
|
|||
|
|
{ label: 'نام شرکت', value: auth.fullName || '—' },
|
|||
|
|
{ label: 'شناسه ملی', value: auth.user?.nationalId ? toPersianDigits(auth.user.nationalId) : '—' },
|
|||
|
|
{
|
|||
|
|
label: 'کد اقتصادی',
|
|||
|
|
value: auth.user?.nationalId ? toPersianDigits(`4${auth.user.nationalId.slice(0, 10)}`) : '—',
|
|||
|
|
},
|
|||
|
|
{ label: 'تاریخ عضویت', value: joinDate.value },
|
|||
|
|
{
|
|||
|
|
label: 'نوع مشتری',
|
|||
|
|
value: auth.isAgent ? 'واسطه' : 'مشتری عمده',
|
|||
|
|
badge: true,
|
|||
|
|
},
|
|||
|
|
{ label: 'وضعیت حساب', value: 'فعال', badge: true },
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
const quickAccess = [
|
|||
|
|
{ label: 'حسابهای بانکی', icon: IconCashSettlement },
|
|||
|
|
{ label: 'آدرسها', icon: IconMapPin },
|
|||
|
|
{ label: 'حمایت و پشتیبانی', icon: IconHeadset, href: 'tel:02112345678' },
|
|||
|
|
{ label: 'فاکتورهای من', icon: IconOrders, path: '/orders' },
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
const settingsItems: Array<{
|
|||
|
|
id: string
|
|||
|
|
label: string
|
|||
|
|
description: string
|
|||
|
|
icon: Component
|
|||
|
|
path?: string
|
|||
|
|
action?: 'logout'
|
|||
|
|
}> = [
|
|||
|
|
{
|
|||
|
|
id: 'profile',
|
|||
|
|
label: 'اطلاعات کاربری',
|
|||
|
|
description: 'ویرایش نام، موبایل و ایمیل',
|
|||
|
|
icon: IconProfile,
|
|||
|
|
path: '/profile/edit',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'security',
|
|||
|
|
label: 'امنیت حساب',
|
|||
|
|
description: 'تغییر رمز عبور و تنظیمات ورود',
|
|||
|
|
icon: IconLock,
|
|||
|
|
path: '/profile/security',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'notifications',
|
|||
|
|
label: 'اعلانها',
|
|||
|
|
description: 'خبرهای فاکتور، چک و ارسال سفارش',
|
|||
|
|
icon: IconBell,
|
|||
|
|
path: '/profile/notifications',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'display',
|
|||
|
|
label: 'تنظیمات',
|
|||
|
|
description: 'نمایش، اطلاعات کاربری و خروج',
|
|||
|
|
icon: IconLayoutGrid,
|
|||
|
|
path: '/profile/display',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'logout',
|
|||
|
|
label: 'خروج از حساب',
|
|||
|
|
description: 'پایان نشست و ورود مجدد',
|
|||
|
|
icon: IconLock,
|
|||
|
|
action: 'logout',
|
|||
|
|
},
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
function handleQuick(item: (typeof quickAccess)[number]) {
|
|||
|
|
if (item.path) router.push(item.path)
|
|||
|
|
else if (item.href) window.location.href = item.href
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function handleSetting(item: (typeof settingsItems)[number]) {
|
|||
|
|
if (item.action === 'logout') {
|
|||
|
|
emit('logout')
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if (item.path) router.push(item.path)
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<div class="desktop-page desktop-profile">
|
|||
|
|
<header class="desktop-profile__head">
|
|||
|
|
<h1 class="desktop-profile__title">پروفایل</h1>
|
|||
|
|
<p class="desktop-profile__subtitle">مدیریت اطلاعات حساب کاربری و تنظیمات</p>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
<section class="profile-overview">
|
|||
|
|
<div class="profile-overview__identity">
|
|||
|
|
<div class="profile-overview__aside">
|
|||
|
|
<UserAvatar
|
|||
|
|
class="profile-overview__avatar"
|
|||
|
|
:src="auth.user?.avatarUrl"
|
|||
|
|
:initials="initials"
|
|||
|
|
:size="92"
|
|||
|
|
/>
|
|||
|
|
<button
|
|||
|
|
type="button"
|
|||
|
|
class="profile-overview__edit"
|
|||
|
|
@click="router.push('/profile/edit')"
|
|||
|
|
>
|
|||
|
|
<IconEditPen :size="16" />
|
|||
|
|
ویرایش اطلاعات
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
<div class="profile-overview__details">
|
|||
|
|
<div class="profile-overview__name-row">
|
|||
|
|
<h2 class="profile-overview__name">{{ auth.fullName }}</h2>
|
|||
|
|
<span class="profile-overview__verified" title="حساب تأیید شده">
|
|||
|
|
<IconVerified :size="18" />
|
|||
|
|
</span>
|
|||
|
|
</div>
|
|||
|
|
<p class="profile-overview__meta">
|
|||
|
|
<IconIdCard :size="15" class="profile-overview__meta-icon" />
|
|||
|
|
<span class="profile-overview__meta-label">{{ codeLabel }}</span>
|
|||
|
|
<span>{{ customerCode }}</span>
|
|||
|
|
</p>
|
|||
|
|
<p class="profile-overview__meta">
|
|||
|
|
<IconPhone :size="15" class="profile-overview__meta-icon" />
|
|||
|
|
<span dir="ltr">{{ auth.user?.phone }}</span>
|
|||
|
|
</p>
|
|||
|
|
<p class="profile-overview__meta">
|
|||
|
|
<IconMail :size="15" class="profile-overview__meta-icon" />
|
|||
|
|
<span dir="ltr">{{ displayEmail }}</span>
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="profile-overview__stats">
|
|||
|
|
<article class="profile-stat">
|
|||
|
|
<span class="profile-stat__icon profile-stat__icon--amber">
|
|||
|
|
<IconCash :size="20" />
|
|||
|
|
</span>
|
|||
|
|
<strong class="profile-stat__value profile-stat__value--sm">
|
|||
|
|
{{ formatCurrency(creditBalance) }}
|
|||
|
|
</strong>
|
|||
|
|
<span class="profile-stat__label">موجودی اعتبار</span>
|
|||
|
|
<button type="button" class="profile-stat__link">مشاهده جزئیات</button>
|
|||
|
|
</article>
|
|||
|
|
|
|||
|
|
<article class="profile-stat">
|
|||
|
|
<span class="profile-stat__icon profile-stat__icon--green">
|
|||
|
|
<IconCheckBook :size="20" />
|
|||
|
|
</span>
|
|||
|
|
<strong class="profile-stat__value">{{ formatNumber(checksCount) }}</strong>
|
|||
|
|
<span class="profile-stat__label">چک فعال</span>
|
|||
|
|
<button type="button" class="profile-stat__link" @click="router.push('/profile/checks')">
|
|||
|
|
مشاهده همه
|
|||
|
|
</button>
|
|||
|
|
</article>
|
|||
|
|
|
|||
|
|
<article class="profile-stat">
|
|||
|
|
<span class="profile-stat__icon profile-stat__icon--blue">
|
|||
|
|
<IconOrders :size="20" />
|
|||
|
|
</span>
|
|||
|
|
<strong class="profile-stat__value">{{ formatNumber(ordersCount) }}</strong>
|
|||
|
|
<span class="profile-stat__label">سفارش ثبتشده</span>
|
|||
|
|
<button type="button" class="profile-stat__link" @click="router.push('/orders')">
|
|||
|
|
مشاهده همه
|
|||
|
|
</button>
|
|||
|
|
</article>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<div class="desktop-profile__grid">
|
|||
|
|
<section class="profile-panel profile-panel--settings">
|
|||
|
|
<h3 class="profile-panel__title">
|
|||
|
|
<IconSettings :size="18" />
|
|||
|
|
تنظیمات حساب
|
|||
|
|
</h3>
|
|||
|
|
<nav class="profile-settings" aria-label="تنظیمات حساب">
|
|||
|
|
<button
|
|||
|
|
v-for="item in settingsItems"
|
|||
|
|
:key="item.id"
|
|||
|
|
type="button"
|
|||
|
|
class="profile-settings__item"
|
|||
|
|
@click="handleSetting(item)"
|
|||
|
|
>
|
|||
|
|
<span class="profile-settings__icon">
|
|||
|
|
<component :is="item.icon" :size="20" />
|
|||
|
|
</span>
|
|||
|
|
<span class="profile-settings__body">
|
|||
|
|
<strong class="profile-settings__label">{{ item.label }}</strong>
|
|||
|
|
<span class="profile-settings__desc">{{ item.description }}</span>
|
|||
|
|
</span>
|
|||
|
|
<IconChevronLeft :size="16" class="profile-settings__chevron" aria-hidden="true" />
|
|||
|
|
</button>
|
|||
|
|
</nav>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="profile-panel profile-panel--quick">
|
|||
|
|
<h3 class="profile-panel__title">
|
|||
|
|
<IconBolt :size="18" />
|
|||
|
|
دسترسی سریع
|
|||
|
|
</h3>
|
|||
|
|
<div class="profile-quick-grid">
|
|||
|
|
<button
|
|||
|
|
v-for="item in quickAccess"
|
|||
|
|
:key="item.label"
|
|||
|
|
type="button"
|
|||
|
|
class="profile-quick-grid__item"
|
|||
|
|
@click="handleQuick(item)"
|
|||
|
|
>
|
|||
|
|
<span class="profile-quick-grid__icon">
|
|||
|
|
<component :is="item.icon" :size="22" />
|
|||
|
|
</span>
|
|||
|
|
<span class="profile-quick-grid__label">{{ item.label }}</span>
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="profile-panel profile-panel--company">
|
|||
|
|
<h3 class="profile-panel__title">
|
|||
|
|
<IconBuilding :size="18" />
|
|||
|
|
اطلاعات شرکت
|
|||
|
|
</h3>
|
|||
|
|
<dl class="profile-info-list">
|
|||
|
|
<div
|
|||
|
|
v-for="row in companyRows"
|
|||
|
|
:key="row.label"
|
|||
|
|
class="profile-info-list__row"
|
|||
|
|
>
|
|||
|
|
<dt>{{ row.label }}</dt>
|
|||
|
|
<dd>
|
|||
|
|
<span v-if="row.badge" class="profile-badge">{{ row.value }}</span>
|
|||
|
|
<template v-else>{{ row.value }}</template>
|
|||
|
|
</dd>
|
|||
|
|
</div>
|
|||
|
|
</dl>
|
|||
|
|
</section>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.desktop-profile {
|
|||
|
|
width: 100%;
|
|||
|
|
padding-bottom: 32px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-profile__head {
|
|||
|
|
margin-bottom: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-profile__title {
|
|||
|
|
margin: 0 0 6px;
|
|||
|
|
font-size: 1.375rem;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-profile__subtitle {
|
|||
|
|
margin: 0;
|
|||
|
|
font-size: 0.875rem;
|
|||
|
|
color: var(--color-text-muted);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview {
|
|||
|
|
direction: rtl;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: stretch;
|
|||
|
|
gap: 0;
|
|||
|
|
padding: 22px 24px;
|
|||
|
|
margin-bottom: 16px;
|
|||
|
|
background: var(--color-surface);
|
|||
|
|
border: 1px solid var(--color-border);
|
|||
|
|
border-radius: var(--radius-lg);
|
|||
|
|
box-shadow: var(--shadow-card);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__identity {
|
|||
|
|
flex: 1.1;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: flex-start;
|
|||
|
|
gap: 18px;
|
|||
|
|
padding-inline-end: 24px;
|
|||
|
|
border-inline-end: 1px solid var(--color-border);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__aside {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 12px;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__avatar {
|
|||
|
|
background: var(--color-primary);
|
|||
|
|
color: var(--color-surface);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__edit {
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 6px;
|
|||
|
|
min-width: 132px;
|
|||
|
|
padding: 9px 14px;
|
|||
|
|
border: 1px solid var(--color-primary);
|
|||
|
|
border-radius: var(--radius-md);
|
|||
|
|
background: var(--color-surface);
|
|||
|
|
color: var(--color-primary);
|
|||
|
|
font-family: inherit;
|
|||
|
|
font-size: 0.8125rem;
|
|||
|
|
font-weight: 600;
|
|||
|
|
cursor: pointer;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
transition: background 0.15s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__edit:hover {
|
|||
|
|
background: var(--color-primary-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__details {
|
|||
|
|
min-width: 0;
|
|||
|
|
flex: 1;
|
|||
|
|
padding-top: 6px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__name-row {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 8px;
|
|||
|
|
margin-bottom: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__name {
|
|||
|
|
margin: 0;
|
|||
|
|
font-size: 1.0625rem;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__verified {
|
|||
|
|
color: var(--color-success);
|
|||
|
|
display: flex;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__meta {
|
|||
|
|
margin: 0 0 8px;
|
|||
|
|
font-size: 0.8125rem;
|
|||
|
|
color: var(--color-text-muted);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__meta-icon {
|
|||
|
|
color: var(--color-text-muted);
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__meta-label {
|
|||
|
|
color: var(--color-text);
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__stats {
|
|||
|
|
direction: ltr;
|
|||
|
|
flex: 1;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|||
|
|
align-items: stretch;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat {
|
|||
|
|
direction: rtl;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
text-align: center;
|
|||
|
|
padding: 12px 14px;
|
|||
|
|
border-inline-start: 1px solid var(--color-border);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat:first-child {
|
|||
|
|
border-inline-start: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__icon {
|
|||
|
|
width: 42px;
|
|||
|
|
height: 42px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__icon--blue {
|
|||
|
|
background: var(--color-primary-soft);
|
|||
|
|
color: var(--color-primary);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__icon--green {
|
|||
|
|
background: var(--color-success-soft);
|
|||
|
|
color: var(--color-success);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__icon--amber {
|
|||
|
|
background: var(--color-warning-light);
|
|||
|
|
color: var(--color-warning);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__value {
|
|||
|
|
font-size: 1.375rem;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
margin-bottom: 4px;
|
|||
|
|
font-variant-numeric: tabular-nums;
|
|||
|
|
line-height: 1.2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__value--sm {
|
|||
|
|
font-size: 0.875rem;
|
|||
|
|
line-height: 1.45;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__label {
|
|||
|
|
font-size: 0.75rem;
|
|||
|
|
color: var(--color-text-muted);
|
|||
|
|
margin-bottom: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__link {
|
|||
|
|
border: none;
|
|||
|
|
background: none;
|
|||
|
|
padding: 0;
|
|||
|
|
color: var(--color-primary);
|
|||
|
|
font-family: inherit;
|
|||
|
|
font-size: 0.75rem;
|
|||
|
|
font-weight: 600;
|
|||
|
|
cursor: pointer;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat__link:hover {
|
|||
|
|
text-decoration: underline;
|
|||
|
|
text-underline-offset: 2px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-profile__grid {
|
|||
|
|
direction: ltr;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|||
|
|
gap: 16px;
|
|||
|
|
align-items: stretch;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-panel {
|
|||
|
|
direction: rtl;
|
|||
|
|
padding: 18px 18px 16px;
|
|||
|
|
background: var(--color-surface);
|
|||
|
|
border: 1px solid var(--color-border);
|
|||
|
|
border-radius: var(--radius-lg);
|
|||
|
|
box-shadow: var(--shadow-card);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-panel__title {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 8px;
|
|||
|
|
margin: 0 0 14px;
|
|||
|
|
padding-bottom: 12px;
|
|||
|
|
border-bottom: 1px solid var(--color-border);
|
|||
|
|
font-size: 0.9375rem;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-panel__title svg {
|
|||
|
|
color: var(--color-primary);
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-info-list {
|
|||
|
|
margin: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-info-list__row {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 12px;
|
|||
|
|
padding: 11px 0;
|
|||
|
|
border-bottom: 1px solid var(--color-border);
|
|||
|
|
font-size: 0.8125rem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-info-list__row:last-child {
|
|||
|
|
border-bottom: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-info-list__row dt {
|
|||
|
|
color: var(--color-text-muted);
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-info-list__row dd {
|
|||
|
|
margin: 0;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
font-weight: 600;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-badge {
|
|||
|
|
display: inline-block;
|
|||
|
|
padding: 4px 12px;
|
|||
|
|
border-radius: 999px;
|
|||
|
|
background: var(--color-success-soft);
|
|||
|
|
color: var(--color-success);
|
|||
|
|
font-size: 0.75rem;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-quick-grid {
|
|||
|
|
direction: ltr;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
gap: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-quick-grid__item {
|
|||
|
|
direction: rtl;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 10px;
|
|||
|
|
min-height: 108px;
|
|||
|
|
padding: 16px 10px;
|
|||
|
|
border: 1px solid var(--color-border);
|
|||
|
|
border-radius: var(--radius-md);
|
|||
|
|
background: var(--color-elevated);
|
|||
|
|
cursor: pointer;
|
|||
|
|
font-family: inherit;
|
|||
|
|
transition: border-color 0.15s, background 0.15s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-quick-grid__item:hover {
|
|||
|
|
border-color: var(--color-primary);
|
|||
|
|
background: var(--color-primary-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-quick-grid__icon {
|
|||
|
|
width: 42px;
|
|||
|
|
height: 42px;
|
|||
|
|
border-radius: 12px;
|
|||
|
|
background: var(--color-surface);
|
|||
|
|
color: var(--color-primary);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
box-shadow: var(--shadow-sm);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-quick-grid__label {
|
|||
|
|
font-size: 0.75rem;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
text-align: center;
|
|||
|
|
line-height: 1.35;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__item {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: auto 1fr auto;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 12px;
|
|||
|
|
width: 100%;
|
|||
|
|
padding: 14px 4px;
|
|||
|
|
border: none;
|
|||
|
|
border-bottom: 1px solid var(--color-border);
|
|||
|
|
border-radius: 0;
|
|||
|
|
background: transparent;
|
|||
|
|
cursor: pointer;
|
|||
|
|
text-align: right;
|
|||
|
|
font-family: inherit;
|
|||
|
|
transition: background 0.15s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__item:last-child {
|
|||
|
|
border-bottom: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__item:hover {
|
|||
|
|
background: var(--color-elevated);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__icon {
|
|||
|
|
width: 38px;
|
|||
|
|
height: 38px;
|
|||
|
|
border-radius: 10px;
|
|||
|
|
background: var(--color-primary-soft);
|
|||
|
|
color: var(--color-primary);
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__body {
|
|||
|
|
min-width: 0;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 3px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__label {
|
|||
|
|
font-size: 0.8125rem;
|
|||
|
|
font-weight: 700;
|
|||
|
|
color: var(--color-text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__desc {
|
|||
|
|
font-size: 0.6875rem;
|
|||
|
|
color: var(--color-text-muted);
|
|||
|
|
line-height: 1.45;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-settings__chevron {
|
|||
|
|
color: #cbd5e1;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 900px) {
|
|||
|
|
.profile-overview {
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__identity {
|
|||
|
|
border-inline-end: none;
|
|||
|
|
padding-inline-end: 0;
|
|||
|
|
padding-bottom: 16px;
|
|||
|
|
border-bottom: 1px solid var(--color-border);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-overview__stats {
|
|||
|
|
padding-top: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.profile-stat:first-child {
|
|||
|
|
border-inline-start: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.desktop-profile__grid {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|