Improve boursecu UX: banners, support FAB, wallet deposit guide, fund/physical layouts, nav, and sidebar credit.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
import { computed, ref } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { useConfigStore } from '@/store/configStore'
|
||||
import {
|
||||
getProjectBaleContactLink,
|
||||
getProjectSupportContactLink,
|
||||
getProjectSupportPhoneLink,
|
||||
isBazretalaProject,
|
||||
} from '@/utils/config'
|
||||
import {
|
||||
buildDepositSmsUrl,
|
||||
buildSupportPhoneUrl,
|
||||
loadSupportMessengerFromSettings,
|
||||
messengerNeedsClipboardCopy,
|
||||
openSupportMessengerEntry,
|
||||
openSupportMessengerWithMessage,
|
||||
resolveDepositGuideText,
|
||||
resolveDepositSupportMessage,
|
||||
resolveSupportMessengerEntries,
|
||||
resolveSupportMessengerLink,
|
||||
resolveSupportMessengerMeta,
|
||||
supportMessengerPickerAnchor,
|
||||
supportMessengerPickerOpen,
|
||||
supportMessengerSettings,
|
||||
type ResolvedSupportMessengerEntry,
|
||||
} from '@/utils/supportMessenger'
|
||||
import {
|
||||
copyDepositFieldValue,
|
||||
displayDepositCardNumber,
|
||||
displayDepositSheba,
|
||||
getDepositGuideVarsFromSettings,
|
||||
getDepositSettingLabel,
|
||||
hasDepositFieldValue,
|
||||
} from '@/utils/depositGuideText'
|
||||
import { useSettingsStore } from '@/store/settingsStore'
|
||||
|
||||
/** plain: منوی شناور / درباره ما — بدون پیشمتن | deposit: مودال واریز — با deposit_support_message_text */
|
||||
type SupportPickerIntent = 'plain' | 'deposit'
|
||||
|
||||
export function useSupportMessenger() {
|
||||
const config = useConfigStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const supportPickerOpen = supportMessengerPickerOpen
|
||||
const supportPickerIntent = ref<SupportPickerIntent>('plain')
|
||||
|
||||
const legacySupportLink = computed(() => {
|
||||
if (config.config?.name === 'garoosi' || isBazretalaProject()) {
|
||||
return getProjectBaleContactLink()
|
||||
}
|
||||
return getProjectSupportContactLink()
|
||||
})
|
||||
|
||||
const depositSupportMessage = computed(() => resolveDepositSupportMessage())
|
||||
|
||||
/** لینکهای تمیز بدون پیشمتن — متن فقط موقع باز کردن (قصد deposit) اضافه میشود */
|
||||
const supportMessengerEntries = computed(() =>
|
||||
resolveSupportMessengerEntries(supportMessengerSettings.value),
|
||||
)
|
||||
|
||||
const primaryMessengerEntry = computed(() => supportMessengerEntries.value[0] ?? null)
|
||||
|
||||
const messengerType = computed(
|
||||
() => (primaryMessengerEntry.value?.messenger ?? supportMessengerSettings.value.messenger ?? '').trim().toLowerCase(),
|
||||
)
|
||||
|
||||
const messengerMeta = computed(() =>
|
||||
primaryMessengerEntry.value
|
||||
? {
|
||||
label: primaryMessengerEntry.value.label,
|
||||
icon: primaryMessengerEntry.value.icon,
|
||||
accent: primaryMessengerEntry.value.accent,
|
||||
}
|
||||
: resolveSupportMessengerMeta(messengerType.value),
|
||||
)
|
||||
|
||||
const messengerLink = computed(() =>
|
||||
primaryMessengerEntry.value?.url
|
||||
|| resolveSupportMessengerLink(
|
||||
supportMessengerSettings.value.messenger,
|
||||
supportMessengerSettings.value.messengerId,
|
||||
legacySupportLink.value,
|
||||
),
|
||||
)
|
||||
|
||||
async function openMessengerEntry(entry: ResolvedSupportMessengerEntry, text?: string) {
|
||||
// فقط وقتی از مودال واریز آمدهایم پیشنویس میگذاریم؛ منوی شناور همیشه خالی
|
||||
const messageText =
|
||||
text !== undefined
|
||||
? text.trim()
|
||||
: supportPickerIntent.value === 'deposit'
|
||||
? depositSupportMessage.value.trim()
|
||||
: ''
|
||||
const opened = await openSupportMessengerEntry(entry, messageText, legacySupportLink.value)
|
||||
if (!opened) return false
|
||||
|
||||
if (messageText && messengerNeedsClipboardCopy(entry.messenger)) {
|
||||
message.success('متن پیام کپی شد — در پیامرسان paste کنید')
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
let supportPickerOpenedAt = 0
|
||||
|
||||
async function openSupportPicker(
|
||||
intent: SupportPickerIntent,
|
||||
anchorEl?: HTMLElement | null,
|
||||
) {
|
||||
supportPickerIntent.value = intent
|
||||
if (anchorEl !== undefined) {
|
||||
supportMessengerPickerAnchor.value = anchorEl
|
||||
}
|
||||
|
||||
const draft =
|
||||
intent === 'deposit' ? depositSupportMessage.value.trim() : ''
|
||||
const entries = supportMessengerEntries.value
|
||||
|
||||
if (entries.length === 0) {
|
||||
return openSupportMessengerWithMessage(
|
||||
supportMessengerSettings.value.messenger,
|
||||
supportMessengerSettings.value.messengerId,
|
||||
draft,
|
||||
legacySupportLink.value,
|
||||
)
|
||||
}
|
||||
|
||||
if (entries.length === 1) {
|
||||
return openMessengerEntry(entries[0], draft)
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
if (supportPickerOpen.value) {
|
||||
if (now - supportPickerOpenedAt < 450) return true
|
||||
supportPickerOpen.value = false
|
||||
return true
|
||||
}
|
||||
|
||||
supportPickerOpen.value = true
|
||||
supportPickerOpenedAt = now
|
||||
return true
|
||||
}
|
||||
|
||||
/** منوی شناور / صفحات درباره ما — بدون پیشنویس پیام */
|
||||
async function openSupportMessenger(anchorEl?: HTMLElement | null) {
|
||||
return openSupportPicker('plain', anchorEl)
|
||||
}
|
||||
|
||||
/** مودال راهنمای واریز — با متن deposit_support_message_text */
|
||||
async function openDepositSupportMessenger(anchorEl?: HTMLElement | null) {
|
||||
return openSupportPicker('deposit', anchorEl)
|
||||
}
|
||||
|
||||
function handleSupportMessengerClick(event?: Event) {
|
||||
const target = event?.currentTarget
|
||||
const anchor = target instanceof HTMLElement ? target : null
|
||||
void openSupportMessenger(anchor)
|
||||
}
|
||||
|
||||
const depositSmsLink = computed(() =>
|
||||
buildDepositSmsUrl(
|
||||
supportMessengerSettings.value.depositSmsSupportNumber,
|
||||
depositSupportMessage.value,
|
||||
),
|
||||
)
|
||||
|
||||
const supportPhoneLink = computed(() => {
|
||||
const fromSettings = buildSupportPhoneUrl(
|
||||
supportMessengerSettings.value.depositSmsSupportNumber,
|
||||
)
|
||||
if (fromSettings) return fromSettings
|
||||
|
||||
const legacyPhone = getProjectSupportPhoneLink()
|
||||
if (legacyPhone && legacyPhone !== 'tel:') return legacyPhone
|
||||
|
||||
const legacy = legacySupportLink.value
|
||||
if (legacy.startsWith('tel:') && legacy.length > 4) return legacy
|
||||
|
||||
return ''
|
||||
})
|
||||
|
||||
const supportMessengerText = computed(() => resolveDepositGuideText())
|
||||
|
||||
const depositCardNumberRaw = computed(() => {
|
||||
void settingsStore.settings
|
||||
const fromMessenger = supportMessengerSettings.value.depositCardNumber?.trim()
|
||||
if (fromMessenger) return fromMessenger
|
||||
return String(getDepositGuideVarsFromSettings().cardNumber ?? '').trim()
|
||||
})
|
||||
|
||||
const depositShebaRaw = computed(() => {
|
||||
void settingsStore.settings
|
||||
const fromMessenger = supportMessengerSettings.value.depositSheba?.trim()
|
||||
if (fromMessenger) return fromMessenger
|
||||
return String(getDepositGuideVarsFromSettings().sheba ?? '').trim()
|
||||
})
|
||||
|
||||
const depositCardNumber = computed(() => displayDepositCardNumber(depositCardNumberRaw.value))
|
||||
const depositSheba = computed(() => displayDepositSheba(depositShebaRaw.value))
|
||||
|
||||
const depositCardLabel = computed(() => {
|
||||
void settingsStore.settings
|
||||
return getDepositSettingLabel('deposit_card_number', 'شماره کارت واریز')
|
||||
})
|
||||
|
||||
const depositShebaLabel = computed(() => {
|
||||
void settingsStore.settings
|
||||
return getDepositSettingLabel('deposit_sheba', 'شبا واریز')
|
||||
})
|
||||
|
||||
const hasDepositCardValue = computed(() => hasDepositFieldValue(depositCardNumberRaw.value))
|
||||
const hasDepositShebaValue = computed(() => hasDepositFieldValue(depositShebaRaw.value))
|
||||
|
||||
async function copyDepositCardNumber() {
|
||||
await copyDepositFieldValue(
|
||||
depositCardNumberRaw.value,
|
||||
'card',
|
||||
'شماره کارت ثبت نشده است',
|
||||
)
|
||||
}
|
||||
|
||||
async function copyDepositShebaNumber() {
|
||||
await copyDepositFieldValue(
|
||||
depositShebaRaw.value,
|
||||
'sheba',
|
||||
'شماره شبا ثبت نشده است',
|
||||
)
|
||||
}
|
||||
|
||||
const hasMessengerLink = computed(() => supportMessengerEntries.value.length > 0 || !!messengerLink.value)
|
||||
const hasMultipleMessengers = computed(() => supportMessengerEntries.value.length > 1)
|
||||
const hasSupportPhoneLink = computed(() => !!supportPhoneLink.value)
|
||||
const hasSupportActions = computed(() => hasSupportPhoneLink.value || hasMessengerLink.value)
|
||||
const opensInNewTab = computed(() => /^https?:\/\//i.test(messengerLink.value))
|
||||
|
||||
return {
|
||||
supportPickerOpen,
|
||||
supportPickerAnchor: supportMessengerPickerAnchor,
|
||||
supportMessengerEntries,
|
||||
messengerType,
|
||||
messengerMeta,
|
||||
messengerLink,
|
||||
supportPhoneLink,
|
||||
depositSmsLink,
|
||||
supportMessengerText,
|
||||
depositSupportMessage,
|
||||
depositCardNumber,
|
||||
depositSheba,
|
||||
depositCardNumberRaw,
|
||||
depositShebaRaw,
|
||||
depositCardLabel,
|
||||
depositShebaLabel,
|
||||
hasDepositCardValue,
|
||||
hasDepositShebaValue,
|
||||
copyDepositCardNumber,
|
||||
copyDepositShebaNumber,
|
||||
openSupportMessenger,
|
||||
openDepositSupportMessenger,
|
||||
openMessengerEntry,
|
||||
handleSupportMessengerClick,
|
||||
hasMessengerLink,
|
||||
hasMultipleMessengers,
|
||||
hasSupportPhoneLink,
|
||||
hasSupportActions,
|
||||
opensInNewTab,
|
||||
loadSupportMessengerFromSettings,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user