2026-09-01 16:05:29 +03:30
|
|
|
|
<script setup lang="ts">
|
2026-09-02 16:06:17 +03:30
|
|
|
|
import { computed } from 'vue';
|
2026-11-03 16:51:51 +03:30
|
|
|
|
import { SearchOutlined, SendOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
|
import {
|
|
|
|
|
|
Button as AButton,
|
|
|
|
|
|
Input as AInput,
|
|
|
|
|
|
Typography,
|
|
|
|
|
|
} from 'ant-design-vue';
|
|
|
|
|
|
import { brand } from '@mento/shared';
|
2026-09-15 14:10:52 +03:30
|
|
|
|
import { useAuthStore } from '@/stores/auth';
|
2026-09-01 16:05:29 +03:30
|
|
|
|
|
2026-09-02 16:06:17 +03:30
|
|
|
|
const props = defineProps<{
|
2026-09-01 16:05:29 +03:30
|
|
|
|
greeting: string;
|
|
|
|
|
|
firstName: string;
|
|
|
|
|
|
userInitial: string;
|
|
|
|
|
|
askQuery: string;
|
2026-09-21 16:58:49 +03:30
|
|
|
|
asking?: boolean;
|
|
|
|
|
|
askAnswer?: string;
|
|
|
|
|
|
askError?: string;
|
2026-10-13 14:45:29 +03:30
|
|
|
|
statusText?: string;
|
2026-09-01 16:05:29 +03:30
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
|
'update:askQuery': [value: string];
|
|
|
|
|
|
ask: [];
|
|
|
|
|
|
}>();
|
|
|
|
|
|
|
2026-09-15 14:10:52 +03:30
|
|
|
|
const auth = useAuthStore();
|
2026-11-03 16:51:51 +03:30
|
|
|
|
const { Title: ATypographyTitle, Text: ATypographyText, Paragraph: ATypographyParagraph } =
|
|
|
|
|
|
Typography;
|
2026-09-15 14:10:52 +03:30
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
/** فقط عکس واقعی کاربر؛ پیشفرض عمومی را نشان نده */
|
|
|
|
|
|
const hasCustomPhoto = computed(() => Boolean(auth.user?.hasAvatar));
|
2026-09-21 16:58:49 +03:30
|
|
|
|
|
|
|
|
|
|
const shortcutLabel = computed(() =>
|
|
|
|
|
|
typeof navigator !== 'undefined' && /Mac|iPhone|iPad/i.test(navigator.platform)
|
|
|
|
|
|
? '⌘K'
|
|
|
|
|
|
: 'Ctrl+K',
|
|
|
|
|
|
);
|
2026-11-03 16:51:51 +03:30
|
|
|
|
|
|
|
|
|
|
const statusMessage = computed(() => {
|
|
|
|
|
|
if (props.asking) return props.statusText || 'در حال پاسخ…';
|
|
|
|
|
|
if (props.askError) return props.askError;
|
|
|
|
|
|
if (props.askAnswer) return props.askAnswer;
|
|
|
|
|
|
return '';
|
|
|
|
|
|
});
|
2026-09-01 16:05:29 +03:30
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<div class="flex flex-col gap-3">
|
|
|
|
|
|
<div class="home-hero relative overflow-hidden rounded-2xl border border-emerald-300/50 shadow-sm">
|
|
|
|
|
|
<!-- base gradient -->
|
|
|
|
|
|
<div class="home-hero__gradient pointer-events-none absolute inset-0" aria-hidden="true" />
|
|
|
|
|
|
<!-- geometric pattern -->
|
|
|
|
|
|
<div class="home-hero__pattern pointer-events-none absolute inset-0" aria-hidden="true" />
|
|
|
|
|
|
<!-- soft orbs -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="pointer-events-none absolute -left-20 -top-24 h-52 w-52 rounded-full bg-emerald-400/20 blur-3xl"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="pointer-events-none absolute -right-16 -bottom-20 h-48 w-48 rounded-full bg-teal-500/15 blur-3xl"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
/>
|
2026-09-01 16:05:29 +03:30
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<div
|
|
|
|
|
|
class="relative flex flex-col lg:flex-row items-stretch lg:items-center justify-between gap-4 p-4 sm:p-5"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="flex items-center gap-3.5 min-w-0">
|
|
|
|
|
|
<div class="home-hero__identity relative shrink-0" :aria-label="firstName">
|
|
|
|
|
|
<div class="home-hero__frame">
|
|
|
|
|
|
<img
|
|
|
|
|
|
v-if="hasCustomPhoto"
|
|
|
|
|
|
:src="auth.avatarSrc"
|
|
|
|
|
|
:alt="firstName"
|
|
|
|
|
|
class="home-hero__photo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span v-else class="home-hero__monogram" aria-hidden="true">
|
|
|
|
|
|
{{ userInitial }}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<span class="home-hero__online" title="آنلاین" aria-hidden="true" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="min-w-0">
|
|
|
|
|
|
<p class="m-0 text-[11px] font-semibold tracking-wide text-emerald-700/80">
|
|
|
|
|
|
{{ brand.nameFa }}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<a-typography-title
|
|
|
|
|
|
:level="4"
|
|
|
|
|
|
class="!m-0 !mt-0.5 !text-slate-800 !text-lg sm:!text-xl !font-extrabold !leading-7 truncate"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ greeting }}، {{ firstName }}
|
|
|
|
|
|
</a-typography-title>
|
|
|
|
|
|
<a-typography-text class="!text-slate-500 !text-sm !mt-0.5 block">
|
|
|
|
|
|
از دادهها بپرسید یا کار امروز را از همینجا شروع کنید
|
|
|
|
|
|
</a-typography-text>
|
|
|
|
|
|
</div>
|
2026-09-01 16:05:29 +03:30
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<div
|
|
|
|
|
|
class="flex items-center gap-2 w-full lg:max-w-xl bg-white border border-white/80 rounded-2xl px-3 py-2 shadow-md shadow-emerald-900/5 focus-within:border-emerald-300 focus-within:ring-2 focus-within:ring-emerald-200/70 transition"
|
2026-09-02 16:06:17 +03:30
|
|
|
|
>
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<span
|
|
|
|
|
|
class="w-8 h-8 rounded-xl bg-emerald-50 text-emerald-600 flex items-center justify-center shrink-0"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<SearchOutlined />
|
2026-09-02 16:06:17 +03:30
|
|
|
|
</span>
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<a-input
|
2026-09-21 16:58:49 +03:30
|
|
|
|
id="home-hero-ask"
|
|
|
|
|
|
:value="askQuery"
|
|
|
|
|
|
:placeholder="brand.askPlaceholderFa"
|
|
|
|
|
|
:disabled="asking"
|
2026-11-03 16:51:51 +03:30
|
|
|
|
:bordered="false"
|
|
|
|
|
|
class="flex-1 !bg-transparent"
|
|
|
|
|
|
@update:value="emit('update:askQuery', $event)"
|
|
|
|
|
|
@press-enter="emit('ask')"
|
2026-09-21 16:58:49 +03:30
|
|
|
|
/>
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<kbd
|
|
|
|
|
|
class="hidden sm:inline-flex items-center text-[11px] font-sans text-slate-400 bg-slate-50 px-2 py-1 rounded-lg border border-slate-200 shrink-0"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ shortcutLabel }}
|
|
|
|
|
|
</kbd>
|
|
|
|
|
|
<a-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
shape="round"
|
|
|
|
|
|
:disabled="asking"
|
|
|
|
|
|
:loading="asking"
|
|
|
|
|
|
aria-label="ارسال"
|
|
|
|
|
|
@click="emit('ask')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #icon><SendOutlined /></template>
|
|
|
|
|
|
<span class="hidden sm:inline">بپرس</span>
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
</div>
|
2026-09-21 16:58:49 +03:30
|
|
|
|
</div>
|
2026-09-01 16:05:29 +03:30
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
<div
|
|
|
|
|
|
v-if="statusMessage"
|
|
|
|
|
|
class="rounded-xl border px-3.5 py-2.5"
|
|
|
|
|
|
:class="
|
|
|
|
|
|
askError
|
|
|
|
|
|
? 'border-rose-200 bg-rose-50/70'
|
|
|
|
|
|
: asking
|
|
|
|
|
|
? 'border-emerald-200/70 bg-emerald-50/50'
|
|
|
|
|
|
: 'border-slate-200 bg-slate-50/80'
|
|
|
|
|
|
"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-typography-paragraph
|
|
|
|
|
|
:type="askError ? 'danger' : 'secondary'"
|
|
|
|
|
|
:ellipsis="{ rows: 3 }"
|
|
|
|
|
|
class="!mb-0 !text-sm"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ statusMessage }}
|
|
|
|
|
|
</a-typography-paragraph>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-09-01 16:05:29 +03:30
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
2026-11-03 16:51:51 +03:30
|
|
|
|
.home-hero__gradient {
|
|
|
|
|
|
background:
|
2026-09-02 16:06:17 +03:30
|
|
|
|
linear-gradient(
|
2026-11-03 16:51:51 +03:30
|
|
|
|
115deg,
|
|
|
|
|
|
#ecfdf5 0%,
|
|
|
|
|
|
#d1fae5 28%,
|
|
|
|
|
|
#ccfbf1 55%,
|
|
|
|
|
|
#f0fdfa 78%,
|
|
|
|
|
|
#ffffff 100%
|
2026-09-02 16:06:17 +03:30
|
|
|
|
);
|
2026-09-01 16:05:29 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
.home-hero__pattern {
|
|
|
|
|
|
opacity: 0.45;
|
|
|
|
|
|
background-image:
|
|
|
|
|
|
radial-gradient(circle at 1px 1px, rgba(16, 185, 129, 0.28) 1px, transparent 0),
|
|
|
|
|
|
linear-gradient(
|
|
|
|
|
|
135deg,
|
|
|
|
|
|
rgba(20, 184, 166, 0.08) 25%,
|
|
|
|
|
|
transparent 25%,
|
|
|
|
|
|
transparent 50%,
|
|
|
|
|
|
rgba(20, 184, 166, 0.08) 50%,
|
|
|
|
|
|
rgba(20, 184, 166, 0.08) 75%,
|
|
|
|
|
|
transparent 75%,
|
|
|
|
|
|
transparent
|
|
|
|
|
|
);
|
|
|
|
|
|
background-size:
|
|
|
|
|
|
18px 18px,
|
|
|
|
|
|
28px 28px;
|
|
|
|
|
|
mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.25));
|
2026-09-01 16:05:29 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
.home-hero__identity {
|
|
|
|
|
|
width: 3.25rem;
|
|
|
|
|
|
height: 3.25rem;
|
2026-09-01 16:05:29 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
.home-hero__frame {
|
2026-09-02 16:06:17 +03:30
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
2026-11-03 16:51:51 +03:30
|
|
|
|
border-radius: 1rem;
|
|
|
|
|
|
padding: 2px;
|
|
|
|
|
|
background: linear-gradient(145deg, #34d399 0%, #0d9488 48%, #059669 100%);
|
|
|
|
|
|
box-shadow:
|
|
|
|
|
|
0 0 0 3px rgba(255, 255, 255, 0.85),
|
|
|
|
|
|
0 8px 18px -10px rgba(4, 120, 87, 0.55);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.home-hero__photo,
|
|
|
|
|
|
.home-hero__monogram {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
border-radius: calc(1rem - 2px);
|
2026-09-02 16:06:17 +03:30
|
|
|
|
object-fit: cover;
|
2026-09-01 16:05:29 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-03 16:51:51 +03:30
|
|
|
|
.home-hero__monogram {
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 1.15rem;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
color: #ecfdf5;
|
|
|
|
|
|
background:
|
|
|
|
|
|
radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.22), transparent 45%),
|
|
|
|
|
|
linear-gradient(160deg, #10b981 0%, #0f766e 100%);
|
|
|
|
|
|
letter-spacing: -0.02em;
|
|
|
|
|
|
user-select: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.home-hero__online {
|
2026-09-01 16:05:29 +03:30
|
|
|
|
position: absolute;
|
2026-11-03 16:51:51 +03:30
|
|
|
|
left: -1px;
|
|
|
|
|
|
bottom: -1px;
|
|
|
|
|
|
width: 0.85rem;
|
|
|
|
|
|
height: 0.85rem;
|
2026-09-01 16:05:29 +03:30
|
|
|
|
border-radius: 999px;
|
2026-11-03 16:51:51 +03:30
|
|
|
|
background: #10b981;
|
2026-09-01 16:05:29 +03:30
|
|
|
|
border: 2px solid #fff;
|
2026-11-03 16:51:51 +03:30
|
|
|
|
box-shadow: 0 0 0 1px rgba(16, 185, 129, 0.25);
|
2026-09-01 16:05:29 +03:30
|
|
|
|
}
|
|
|
|
|
|
</style>
|