Files
CRM_Montzar/apps/web/src/components/person-profile/ProfileEmptyState.vue
T
MahdiandCursor 6c6e32e099 feat(web): adopt vuesax icons and shared skeleton loading
Replace the inline SVG icon set with the vuesax linear pack, add skeleton primitives for loading states, and keep page scroll inside the app shell.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-05 14:46:35 +03:30

97 lines
3.1 KiB
Vue

<script setup lang="ts">
import { useRouter } from 'vue-router';
import type { RouteLocationRaw } from 'vue-router';
import {
Button as AButton,
Flex as AFlex,
Space as ASpace,
Typography,
} from 'ant-design-vue';
import {
CalendarOutlined,
PlusOutlined,
UserAddOutlined,
} from '@/icons/ant-bridge';
const { Title: ATypographyTitle, Text: ATypographyText } = Typography;
const props = withDefaults(
defineProps<{
title?: string;
description?: string;
primaryLabel: string;
primaryTo: RouteLocationRaw;
secondaryLabel?: string;
secondaryTo?: RouteLocationRaw;
secondaryIcon?: 'calendar' | 'calendar-plus' | 'user-plus';
}>(),
{
title: 'هنوز اطلاعاتی ثبت نشده!',
description:
'برای شروع، اطلاعات اولیه مشتری را ثبت کنید یا اولین فعالیت خود را اضافه نمایید.',
secondaryIcon: 'calendar-plus',
},
);
const router = useRouter();
function go(to: RouteLocationRaw) {
void router.push(to);
}
const secondaryIconComp = () => {
if (props.secondaryIcon === 'user-plus') return UserAddOutlined;
return CalendarOutlined;
};
</script>
<template>
<a-flex vertical align="center" :gap="16" :style="{ width: '100%', textAlign: 'center' }">
<div aria-hidden="true" :style="{ width: '168px' }">
<span aria-hidden="true">✦</span>
<svg viewBox="0 0 168 132" fill="none" :style="{ width: '168px', height: 'auto', display: 'block' }">
<path
d="M26 44c0-7.2 5.8-13 13-13h30l9 9h51c7.2 0 13 5.8 13 13v54c0 7.2-5.8 13-13 13H39c-7.2 0-13-5.8-13-13V44Z"
fill="#D9E6E8"
/>
<path
d="M26 50h116v47c0 7.2-5.8 13-13 13H39c-7.2 0-13-5.8-13-13V50Z"
fill="#E8F1F2"
/>
<rect x="54" y="34" width="60" height="74" rx="11" fill="#fff" />
<rect x="54" y="34" width="60" height="74" rx="11" stroke="#E2E8F0" />
<circle cx="84" cy="60" r="12" fill="#C5D4DA" />
<path
d="M66 96c2.2-9.2 8.4-14 18-14s15.8 4.8 18 14"
stroke="#C5D4DA"
stroke-width="9"
stroke-linecap="round"
/>
<circle cx="122" cy="100" r="17" fill="#14b8a6" />
<circle cx="122" cy="100" r="17" fill="#14b8a6" stroke="#fff" stroke-width="3" />
<path d="M122 92.5v15M114.5 100h15" stroke="#fff" stroke-width="2.8" stroke-linecap="round" />
</svg>
</div>
<a-typography-title :level="4" :style="{ margin: 0 }">{{ title }}</a-typography-title>
<a-typography-text type="secondary">{{ description }}</a-typography-text>
<a-space direction="vertical" style="width: min(100%, 304px)">
<a-button type="primary" block @click="go(primaryTo)">
<template #icon><PlusOutlined /></template>
{{ primaryLabel }}
</a-button>
<a-button
v-if="secondaryLabel && secondaryTo"
block
@click="go(secondaryTo)"
>
<template #icon>
<component :is="secondaryIconComp()" />
</template>
{{ secondaryLabel }}
</a-button>
</a-space>
</a-flex>
</template>