Port modular price, product, and PWA fixes into boursecu

Sync live quote handling, SSE product images, store hours, file URL normalization, PWA icon cache, TV monitor, about software, SuperAdmin menu gates, price alerts, and related UX from modular while preserving boursecu branding and config constraints.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-02 08:26:52 -04:00
co-authored by Cursor
parent e9012e26fb
commit 9356a2ab5e
112 changed files with 6044 additions and 583 deletions
+12
View File
@@ -0,0 +1,12 @@
import { ref } from 'vue'
/** باز/بسته بودن مدال محاسبه‌گر طلا — مشترک بین منوی کاربر و همبرگر */
export const goldDayCalculatorVisible = ref(false)
export function openGoldDayCalculator() {
goldDayCalculatorVisible.value = true
}
export function closeGoldDayCalculator() {
goldDayCalculatorVisible.value = false
}
+39 -2
View File
@@ -1,6 +1,6 @@
import { computed, ref } from 'vue'
import { message } from 'ant-design-vue'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import { useConfigStore } from '@/store/configStore'
import {
getProjectBaleContactLink,
@@ -26,6 +26,7 @@ import {
} from '@/utils/supportMessenger'
import {
copyDepositFieldValue,
displayDepositAccountNumber,
displayDepositCardNumber,
displayDepositSheba,
getDepositGuideVarsFromSettings,
@@ -51,10 +52,15 @@ export function useSupportMessenger() {
const config = useConfigStore()
const settingsStore = useSettingsStore()
const router = useRouter()
const route = useRoute()
const supportPickerOpen = supportMessengerPickerOpen
const supportPickerIntent = ref<SupportPickerIntent>('plain')
const isChatEnabled = computed(() => isUserSupportChatEnabled())
/** چت فقط بعد از لاگین — روی صفحه ورود در picker نیاید */
const isChatEnabled = computed(() => {
void route.name
return isUserSupportChatEnabled()
})
const legacySupportLink = computed(() => {
if (config.config?.name === 'garoosi' || isBazretalaProject()) {
@@ -223,6 +229,13 @@ export function useSupportMessenger() {
return String(getDepositGuideVarsFromSettings().cardNumber ?? '').trim()
})
const depositAccountNumberRaw = computed(() => {
void settingsStore.settings
const fromMessenger = supportMessengerSettings.value.depositAccountNumber?.trim()
if (fromMessenger) return fromMessenger
return String(getDepositGuideVarsFromSettings().accountNumber ?? '').trim()
})
const depositShebaRaw = computed(() => {
void settingsStore.settings
const fromMessenger = supportMessengerSettings.value.depositSheba?.trim()
@@ -231,6 +244,9 @@ export function useSupportMessenger() {
})
const depositCardNumber = computed(() => displayDepositCardNumber(depositCardNumberRaw.value))
const depositAccountNumber = computed(() =>
displayDepositAccountNumber(depositAccountNumberRaw.value),
)
const depositSheba = computed(() => displayDepositSheba(depositShebaRaw.value))
const depositCardLabel = computed(() => {
@@ -238,12 +254,20 @@ export function useSupportMessenger() {
return getDepositSettingLabel('deposit_card_number', 'شماره کارت واریز')
})
const depositAccountNumberLabel = computed(() => {
void settingsStore.settings
return getDepositSettingLabel('deposit_account_number', 'شماره حساب واریز')
})
const depositShebaLabel = computed(() => {
void settingsStore.settings
return getDepositSettingLabel('deposit_sheba', 'شبا واریز')
})
const hasDepositCardValue = computed(() => hasDepositFieldValue(depositCardNumberRaw.value))
const hasDepositAccountNumberValue = computed(() =>
hasDepositFieldValue(depositAccountNumberRaw.value),
)
const hasDepositShebaValue = computed(() => hasDepositFieldValue(depositShebaRaw.value))
async function copyDepositCardNumber() {
@@ -254,6 +278,14 @@ export function useSupportMessenger() {
)
}
async function copyDepositAccountNumber() {
await copyDepositFieldValue(
depositAccountNumberRaw.value,
'account',
'شماره حساب ثبت نشده است',
)
}
async function copyDepositShebaNumber() {
await copyDepositFieldValue(
depositShebaRaw.value,
@@ -283,14 +315,19 @@ export function useSupportMessenger() {
supportMessengerText,
depositSupportMessage,
depositCardNumber,
depositAccountNumber,
depositSheba,
depositCardNumberRaw,
depositAccountNumberRaw,
depositShebaRaw,
depositCardLabel,
depositAccountNumberLabel,
depositShebaLabel,
hasDepositCardValue,
hasDepositAccountNumberValue,
hasDepositShebaValue,
copyDepositCardNumber,
copyDepositAccountNumber,
copyDepositShebaNumber,
openSupportMessenger,
openDepositSupportMessenger,
@@ -0,0 +1,21 @@
import { onMounted, ref } from 'vue'
import { fetchTrackingSettings, isTrackingSystemsEnabled } from '@/utils/trackingSystemsSettings'
export function useTrackingSystemsFeature() {
const trackingSystemsEnabled = ref(false)
const trackingSystemsReady = ref(false)
onMounted(async () => {
try {
const settings = await fetchTrackingSettings()
trackingSystemsEnabled.value = isTrackingSystemsEnabled(settings)
} finally {
trackingSystemsReady.value = true
}
})
return {
trackingSystemsEnabled,
trackingSystemsReady,
}
}