Make boursecu branch boursecu-only and simplify app loading.
Remove multi-tenant branches and default views, show logo-only boot and splash screens, and polish boursecu transactions tab styling. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+35
-71
@@ -17,8 +17,8 @@
|
|||||||
<!---->
|
<!---->
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--boot-bg: #ffffff;
|
--boot-bg: #133050;
|
||||||
--boot-bg-soft: #f8fafc;
|
--boot-bg-soft: #133050;
|
||||||
--boot-card: rgba(255, 255, 255, 0.88);
|
--boot-card: rgba(255, 255, 255, 0.88);
|
||||||
--boot-border: rgba(15, 23, 42, 0.08);
|
--boot-border: rgba(15, 23, 42, 0.08);
|
||||||
--boot-text: #111827;
|
--boot-text: #111827;
|
||||||
@@ -52,75 +52,26 @@
|
|||||||
BlinkMacSystemFont,
|
BlinkMacSystemFont,
|
||||||
"Segoe UI",
|
"Segoe UI",
|
||||||
sans-serif;
|
sans-serif;
|
||||||
background:
|
background: var(--boot-bg);
|
||||||
radial-gradient(circle at top, var(--boot-orb), transparent 38%),
|
|
||||||
linear-gradient(
|
|
||||||
135deg,
|
|
||||||
var(--boot-bg) 0%,
|
|
||||||
var(--boot-bg-soft) 100%
|
|
||||||
);
|
|
||||||
color: var(--boot-text);
|
color: var(--boot-text);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.boot-loader__card {
|
.boot-loader__logo {
|
||||||
position: relative;
|
width: min(72vw, 280px);
|
||||||
width: min(340px, calc(100vw - 48px));
|
height: auto;
|
||||||
padding: 30px 22px 28px;
|
object-fit: contain;
|
||||||
border-radius: 24px;
|
animation: boot-logo-fade-in 0.45s ease-out both;
|
||||||
text-align: center;
|
|
||||||
background: var(--boot-card);
|
|
||||||
border: 1px solid var(--boot-border);
|
|
||||||
box-shadow: 0 18px 48px var(--boot-shadow);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.boot-loader__orb {
|
@keyframes boot-logo-fade-in {
|
||||||
position: absolute;
|
from {
|
||||||
top: -72px;
|
opacity: 0;
|
||||||
left: 50%;
|
transform: scale(0.96);
|
||||||
width: 150px;
|
}
|
||||||
height: 150px;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
border-radius: 999px;
|
|
||||||
background: var(--boot-orb);
|
|
||||||
filter: blur(8px);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boot-loader__spinner {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
width: 56px;
|
|
||||||
height: 56px;
|
|
||||||
margin: 0 auto 20px;
|
|
||||||
border-radius: 999px;
|
|
||||||
border: 4px solid var(--boot-spinner-track);
|
|
||||||
border-top-color: var(--boot-accent);
|
|
||||||
animation: boot-spin 0.9s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boot-loader__title {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 19px;
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: -0.02em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boot-loader__text {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
margin: 10px 0 0;
|
|
||||||
color: var(--boot-muted);
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes boot-spin {
|
|
||||||
to {
|
to {
|
||||||
transform: rotate(360deg);
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,6 +274,20 @@
|
|||||||
setVar('--App-background-color', tenantBackground)
|
setVar('--App-background-color', tenantBackground)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var logoEl = document.getElementById('boot-logo')
|
||||||
|
if (logoEl) {
|
||||||
|
if (user.name === 'boursecu') {
|
||||||
|
logoEl.src = '/boursecu-splash.png'
|
||||||
|
} else if (user.avatar) {
|
||||||
|
logoEl.src = user.avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.name === 'boursecu') {
|
||||||
|
setVar('--boot-bg', '#133050')
|
||||||
|
setVar('--boot-bg-soft', '#133050')
|
||||||
|
}
|
||||||
|
|
||||||
document.title = user.name_fa || user.name || 'در حال بارگذاری...'
|
document.title = user.name_fa || user.name || 'در حال بارگذاری...'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,13 +299,12 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<div class="boot-loader">
|
<div class="boot-loader">
|
||||||
<div class="boot-loader__card">
|
<img
|
||||||
<div class="boot-loader__orb"></div>
|
id="boot-logo"
|
||||||
<div class="boot-loader__spinner"></div>
|
class="boot-loader__logo"
|
||||||
|
src="/boursecu-splash.png"
|
||||||
<h1 class="boot-loader__title">در حال هدایت به سامانه</h1>
|
alt=""
|
||||||
<p class="boot-loader__text">لطفاً چند لحظه صبر کنید...</p>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
+3
-51
@@ -11,42 +11,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<AConfigProvider :theme="antTheme ?? undefined" direction="rtl">
|
<AConfigProvider :theme="antTheme ?? undefined" direction="rtl">
|
||||||
<div v-if="showSplash" class="app-splash-screen flex justify-center" :style="{ backgroundColor: getProjectSplashBackground() }">
|
<div v-if="showSplash" class="app-splash-screen flex justify-center" :style="{ backgroundColor: getProjectSplashBackground() }">
|
||||||
<template v-if="!isBoursecuProject()">
|
|
||||||
<div class="app-splash-screen__gradient app-splash-screen__gradient--top h-1/3 flex">
|
|
||||||
<img :src="img_topGradiant" alt="" class="absolute z-10 w-full h-full object-cover"/>
|
|
||||||
<img :src="img_pattern" alt="" class="absolute w-full h-full object-none"/>
|
|
||||||
</div>
|
|
||||||
<div class="app-splash-screen__gradient app-splash-screen__gradient--bottom h-1/3">
|
|
||||||
<img
|
|
||||||
:src="img_bottomGradiant"
|
|
||||||
alt=""
|
|
||||||
class="absolute z-10 w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
<img :src="img_pattern" alt="" class="absolute w-full h-full object-none"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="self-center splash_appear_fade_in">
|
<div class="self-center splash_appear_fade_in">
|
||||||
<img
|
<img
|
||||||
:src="getProjectSplashLogo(config?.config?.avatar)"
|
:src="getProjectSplashLogo(config?.config?.avatar)"
|
||||||
:class="isBoursecuProject()
|
class="w-[min(72vw,280px)] h-auto object-contain"
|
||||||
? 'w-[min(72vw,280px)] h-auto object-contain'
|
|
||||||
: hasCustomLoginLogoLayout()
|
|
||||||
? 'w-[80vw] max-w-[320px] h-auto object-contain'
|
|
||||||
: 'h-[20vh] object-contain'"
|
|
||||||
alt=""
|
alt=""
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="fixed w-full bottom-5 home_appear_fade_in_up">
|
|
||||||
<div
|
|
||||||
class="text-center text-xs"
|
|
||||||
:class="isBoursecuProject() ? 'text-white' : ''"
|
|
||||||
>
|
|
||||||
نسخه: {{ displayVersion }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="absolute bottom-10">
|
|
||||||
<a-spin :indicator="splashIndicator" size="small"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else class="app-main">
|
<div v-else class="app-main">
|
||||||
@@ -90,16 +61,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import pkg from '../package.json'
|
import {computed, defineAsyncComponent, onMounted, ref, watch} from 'vue'
|
||||||
import { getDisplayAppVersion } from '@/config/config-cache'
|
|
||||||
import {computed, defineAsyncComponent, h, onMounted, ref, watch} from 'vue'
|
|
||||||
import img_topGradiant from '@/views/login/assets/img/gr_top_white.svg'
|
|
||||||
import img_pattern from '@/views/login/assets/img/pattern.svg'
|
|
||||||
import {LoadingOutlined} from '@ant-design/icons-vue'
|
|
||||||
import img_bottomGradiant from '@/views/login/assets/img/gr_bottom_white.svg'
|
|
||||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||||
import {useConfigStore} from "@/store/configStore";
|
import {useConfigStore} from "@/store/configStore";
|
||||||
import {getProjectFontFamily, getProjectSplashBackground, getProjectSplashLogo, getProjectBrandRed, getProjectPrimaryColor, hasCustomLoginLogoLayout, isBoursecuProject, resetAppSurfaceBackground} from "@/utils/config";
|
import {getProjectFontFamily, getProjectSplashBackground, getProjectSplashLogo, getProjectBrandRed, getProjectPrimaryColor, resetAppSurfaceBackground} from "@/utils/config";
|
||||||
import {ConfigProvider as AConfigProvider} from 'ant-design-vue'
|
import {ConfigProvider as AConfigProvider} from 'ant-design-vue'
|
||||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||||
import { useApplyDesktopLayoutClass, useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
import { useApplyDesktopLayoutClass, useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
||||||
@@ -126,24 +91,11 @@ const showDesktopFloatingCredit = computed(() => {
|
|||||||
return route.name === 'login' || !!route.meta.hideMenu
|
return route.name === 'login' || !!route.meta.hideMenu
|
||||||
})
|
})
|
||||||
|
|
||||||
const displayVersion = getDisplayAppVersion(pkg.version)
|
|
||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
const splashIndicator = computed(() => h(LoadingOutlined, {
|
|
||||||
style: {
|
|
||||||
fontSize: '24px',
|
|
||||||
color: isBoursecuProject() ? '#ffffff' : undefined,
|
|
||||||
},
|
|
||||||
spin: true
|
|
||||||
}))
|
|
||||||
const showSplash = ref(true)
|
const showSplash = ref(true)
|
||||||
const popVisible = ref(false)
|
const popVisible = ref(false)
|
||||||
|
|
||||||
// const GAROOSI_SUPPORT_URL = 'https://ble.ir/garoosigallery'
|
|
||||||
|
|
||||||
const supportLink = computed(() => {
|
const supportLink = computed(() => {
|
||||||
// if (config.config?.name === 'garoosi') {
|
|
||||||
// return GAROOSI_SUPPORT_URL
|
|
||||||
// }
|
|
||||||
return buildSupportMessengerUrl(
|
return buildSupportMessengerUrl(
|
||||||
supportMessengerSettings.value.messenger,
|
supportMessengerSettings.value.messenger,
|
||||||
supportMessengerSettings.value.messengerId
|
supportMessengerSettings.value.messengerId
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { useUserStore } from '@/store/userStore'
|
|||||||
import { useFundUserStore } from '@/store/fundStore'
|
import { useFundUserStore } from '@/store/fundStore'
|
||||||
import type { NavigationGuardNext } from 'vue-router'
|
import type { NavigationGuardNext } from 'vue-router'
|
||||||
import { useAuthStore } from '@/store/useAuthStore'
|
import { useAuthStore } from '@/store/useAuthStore'
|
||||||
import { getConfigApp } from '@/utils/config'
|
|
||||||
import { recoverMobileViewportAfterAuth } from '@/layouts/composables/useMobileScrollReset'
|
import { recoverMobileViewportAfterAuth } from '@/layouts/composables/useMobileScrollReset'
|
||||||
|
|
||||||
const PUBLIC_ROUTE_NAMES = ['login', '404', 'educate', 'aboutUs'] as const
|
const PUBLIC_ROUTE_NAMES = ['login', '404', 'educate', 'aboutUs'] as const
|
||||||
@@ -68,10 +67,6 @@ export function setupRouterGuards() {
|
|||||||
clearTimeout(timeoutId)
|
clearTimeout(timeoutId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to.name === 'giftCard' && getConfigApp('name') !== 'garoosi') {
|
|
||||||
return next({ name: (from.name as string) || 'home' })
|
|
||||||
}
|
|
||||||
|
|
||||||
const authenticated = await resolveSession()
|
const authenticated = await resolveSession()
|
||||||
|
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
getBoursecuActionIconSrc,
|
getBoursecuActionIconSrc,
|
||||||
getBoursecuTransactionsIcon,
|
getBoursecuTransactionsIcon,
|
||||||
isBoursecuProject,
|
|
||||||
} from '@/utils/config'
|
} from '@/utils/config'
|
||||||
import type { AppNavItem } from '../types'
|
import type { AppNavItem } from '../types'
|
||||||
|
|
||||||
@@ -43,21 +42,12 @@ const BOURSECU_PRIMARY_NAV: AppNavItem[] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const DEFAULT_PRIMARY_NAV: AppNavItem[] = [
|
|
||||||
{ id: 'home', routeName: 'home', label: 'صفحه اصلی', icon: 'vuesax-linear:home' },
|
|
||||||
{ id: 'transactions', routeName: 'transactions', label: 'تراکنشها', icon: 'vuesax-linear:receipt-item' },
|
|
||||||
{ id: 'buyProduct', routeName: 'buyProduct', label: 'محصولات', icon: 'vuesax-linear:coin' },
|
|
||||||
{ id: 'wallet', routeName: 'wallet', label: 'کیف پول', icon: 'vuesax-linear:wallet-1' },
|
|
||||||
{ id: 'user', routeName: 'user', label: 'تنظیمات', icon: 'vuesax-linear:setting-2' },
|
|
||||||
]
|
|
||||||
|
|
||||||
export const SECONDARY_NAV: AppNavItem[] = [
|
export const SECONDARY_NAV: AppNavItem[] = [
|
||||||
{ id: 'notifyTrigger', routeName: 'notifyTrigger', label: 'هشدار قیمت', icon: 'vuesax-linear:bill' },
|
{ id: 'notifyTrigger', routeName: 'notifyTrigger', label: 'هشدار قیمت', icon: 'vuesax-linear:bill' },
|
||||||
{ id: 'about', routeName: 'about', label: 'درباره ما', icon: 'vuesax-linear:info-circle' },
|
{ id: 'about', routeName: 'about', label: 'درباره ما', icon: 'vuesax-linear:info-circle' },
|
||||||
{ id: 'rules', routeName: 'rules', label: 'قوانین و مقررات', icon: 'vuesax-linear:task' },
|
{ id: 'rules', routeName: 'rules', label: 'قوانین و مقررات', icon: 'vuesax-linear:task' },
|
||||||
{ id: 'giftCard', routeName: 'giftCard', label: 'ثبت کارت هدیه', icon: 'vuesax-linear:gift' },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export function getPrimaryNavItems(): AppNavItem[] {
|
export function getPrimaryNavItems(): AppNavItem[] {
|
||||||
return isBoursecuProject() ? BOURSECU_PRIMARY_NAV : DEFAULT_PRIMARY_NAV
|
return BOURSECU_PRIMARY_NAV
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<aside
|
<aside class="desktop-sidebar desktop-sidebar--boursecu">
|
||||||
class="desktop-sidebar"
|
|
||||||
:class="{ 'desktop-sidebar--boursecu': isBoursecu }"
|
|
||||||
>
|
|
||||||
<div class="desktop-sidebar__brand">
|
<div class="desktop-sidebar__brand">
|
||||||
<img
|
<img
|
||||||
:src="navLogo"
|
:src="navLogo"
|
||||||
@@ -46,14 +43,13 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
import { useConfigStore } from '@/store/configStore'
|
||||||
import { getProjectSplashLogo, isBoursecuProject } from '@/utils/config'
|
import { getProjectSplashLogo } from '@/utils/config'
|
||||||
import { getPrimaryNavItems, SECONDARY_NAV } from '../config/navigation'
|
import { getPrimaryNavItems, SECONDARY_NAV } from '../config/navigation'
|
||||||
import { useAppNavigation } from '../composables/useAppNavigation'
|
import { useAppNavigation } from '../composables/useAppNavigation'
|
||||||
import DesktopNavItem from './DesktopNavItem.vue'
|
import DesktopNavItem from './DesktopNavItem.vue'
|
||||||
import AppCreditLink from '@/components/AppCreditLink.vue'
|
import AppCreditLink from '@/components/AppCreditLink.vue'
|
||||||
|
|
||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
const navLogo = computed(() => getProjectSplashLogo(config.config?.avatar))
|
const navLogo = computed(() => getProjectSplashLogo(config.config?.avatar))
|
||||||
const primaryItems = getPrimaryNavItems()
|
const primaryItems = getPrimaryNavItems()
|
||||||
const secondaryItems = SECONDARY_NAV
|
const secondaryItems = SECONDARY_NAV
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
<MobileBottomNav
|
<MobileBottomNav
|
||||||
v-if="!hideMenu"
|
v-if="!hideMenu"
|
||||||
:is-boursecu="isBoursecu"
|
|
||||||
:nav-logo="navLogo"
|
|
||||||
:nav-item-class="navItemClass"
|
:nav-item-class="navItemClass"
|
||||||
@navigate="navigateTo"
|
@navigate="navigateTo"
|
||||||
/>
|
/>
|
||||||
@@ -19,18 +17,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, watch } from 'vue'
|
import { onMounted, watch } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
|
||||||
import { getProjectMobileNavLogo, isBoursecuProject } from '@/utils/config'
|
|
||||||
import { useAppNavigation } from '../composables/useAppNavigation'
|
import { useAppNavigation } from '../composables/useAppNavigation'
|
||||||
import { recoverMobileViewportAfterAuth, resetMobileAppScroll } from '../composables/useMobileScrollReset'
|
import { recoverMobileViewportAfterAuth, resetMobileAppScroll } from '../composables/useMobileScrollReset'
|
||||||
import MobileBottomNav from './MobileBottomNav.vue'
|
import MobileBottomNav from './MobileBottomNav.vue'
|
||||||
|
|
||||||
const config = useConfigStore()
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
const navLogo = computed(() => getProjectMobileNavLogo(config.config?.avatar))
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
hideMenu,
|
hideMenu,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
<div class="bottom-appbar w-auto mx-auto bg-white">
|
<div class="bottom-appbar w-auto mx-auto bg-white">
|
||||||
<div class="tabs bottom-0">
|
<div class="tabs bottom-0">
|
||||||
<div
|
<div
|
||||||
v-if="isBoursecu"
|
|
||||||
:class="navItemClass('buyProduct')"
|
:class="navItemClass('buyProduct')"
|
||||||
class="tab"
|
class="tab"
|
||||||
@click="$emit('navigate', 'buyProduct')"
|
@click="$emit('navigate', 'buyProduct')"
|
||||||
@@ -16,17 +15,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-xs mt-1 font-bold">خرید و فروش</div>
|
<div class="text-xs mt-1 font-bold">خرید و فروش</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
:class="navItemClass('home')"
|
|
||||||
class="tab"
|
|
||||||
@click="$emit('navigate', 'home')"
|
|
||||||
>
|
|
||||||
<div class="tab__icon">
|
|
||||||
<Icon icon="vuesax-linear:home" size="24" />
|
|
||||||
</div>
|
|
||||||
<div class="text-xs mt-1 font-bold">صفحه اصلی</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:class="navItemClass('transactions')"
|
:class="navItemClass('transactions')"
|
||||||
@@ -35,18 +23,15 @@
|
|||||||
>
|
>
|
||||||
<div class="tab__icon">
|
<div class="tab__icon">
|
||||||
<img
|
<img
|
||||||
v-if="isBoursecu"
|
|
||||||
:src="boursecuTransactionsIcon"
|
:src="boursecuTransactionsIcon"
|
||||||
alt=""
|
alt=""
|
||||||
class="tab__icon-image"
|
class="tab__icon-image"
|
||||||
/>
|
/>
|
||||||
<Icon v-else icon="vuesax-linear:receipt-item" size="24" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs mt-1 font-bold">تراکنش ها</div>
|
<div class="text-xs mt-1 font-bold">تراکنش ها</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="isBoursecu"
|
|
||||||
:class="navItemClass('home')"
|
:class="navItemClass('home')"
|
||||||
class="tab"
|
class="tab"
|
||||||
@click="$emit('navigate', 'home')"
|
@click="$emit('navigate', 'home')"
|
||||||
@@ -60,28 +45,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-xs mt-1 font-bold">صفحه اصلی</div>
|
<div class="text-xs mt-1 font-bold">صفحه اصلی</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="main_in" @click="$emit('navigate', 'buyProduct')">
|
|
||||||
<div
|
|
||||||
class="circle_in"
|
|
||||||
:class="isWhiteNavLogo ? 'is-white-nav-logo' : 'text-white'"
|
|
||||||
>
|
|
||||||
<div class="circle_into">
|
|
||||||
<div
|
|
||||||
v-if="projectName === 'garoosi'"
|
|
||||||
class="p-2 text-tertiary flex flex-col justify-center items-center"
|
|
||||||
>
|
|
||||||
<Icon icon="vuesax-linear:coin" />
|
|
||||||
<div class="text-[9px] font-bold">محصولات</div>
|
|
||||||
</div>
|
|
||||||
<img
|
|
||||||
v-else
|
|
||||||
class="p-2"
|
|
||||||
:src="navLogo"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:class="navItemClass('wallet')"
|
:class="navItemClass('wallet')"
|
||||||
@@ -90,47 +53,36 @@
|
|||||||
>
|
>
|
||||||
<div class="tab__icon">
|
<div class="tab__icon">
|
||||||
<img
|
<img
|
||||||
v-if="isBoursecu"
|
|
||||||
:src="boursecuWalletIcon"
|
:src="boursecuWalletIcon"
|
||||||
alt=""
|
alt=""
|
||||||
class="tab__icon-image"
|
class="tab__icon-image"
|
||||||
/>
|
/>
|
||||||
<Icon v-else icon="vuesax-linear:wallet-1" size="24" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs mt-1 font-bold">کیف پول</div>
|
<div class="text-xs mt-1 font-bold">کیف پول</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:class="navItemClass(userNavItem.routeName)"
|
:class="navItemClass('user')"
|
||||||
class="tab"
|
class="tab"
|
||||||
@click="$emit('navigate', userNavItem.routeName)"
|
@click="$emit('navigate', 'user')"
|
||||||
>
|
>
|
||||||
<div class="tab__icon">
|
<div class="tab__icon">
|
||||||
<img
|
<img
|
||||||
v-if="isBoursecu && userNavItem.routeName === 'user'"
|
|
||||||
:src="boursecuSettingsIcon"
|
:src="boursecuSettingsIcon"
|
||||||
alt=""
|
alt=""
|
||||||
class="tab__icon-image"
|
class="tab__icon-image"
|
||||||
/>
|
/>
|
||||||
<Icon v-else :icon="userNavItem.icon" size="24" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs mt-1 font-bold">{{ userNavItem.label }}</div>
|
<div class="text-xs mt-1 font-bold">تنظیمات</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!isBoursecu" class="main">
|
|
||||||
<div class="circle" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { getBoursecuActionIconSrc } from '@/utils/config'
|
||||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
|
||||||
import { getBoursecuActionIconSrc, getConfigApp } from '@/utils/config'
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
isBoursecu: boolean
|
|
||||||
navLogo: string
|
|
||||||
navItemClass: (routeName: string) => string
|
navItemClass: (routeName: string) => string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -138,19 +90,11 @@ defineEmits<{
|
|||||||
navigate: [routeName: string]
|
navigate: [routeName: string]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const projectName = getConfigApp('name')
|
|
||||||
const userNavItem = computed(() =>
|
|
||||||
projectName === 'abshodehrahimi'
|
|
||||||
? { routeName: 'notifyTrigger', label: 'هشدار قیمت', icon: 'vuesax-linear:bill' }
|
|
||||||
: { routeName: 'user', label: 'تنظیمات', icon: 'vuesax-linear:setting-2' },
|
|
||||||
)
|
|
||||||
const boursecuBuySellIcon = getBoursecuActionIconSrc('buySell') ?? ''
|
const boursecuBuySellIcon = getBoursecuActionIconSrc('buySell') ?? ''
|
||||||
const boursecuTransactionsIcon = getBoursecuActionIconSrc('transactions') ?? ''
|
const boursecuTransactionsIcon = getBoursecuActionIconSrc('transactions') ?? ''
|
||||||
const boursecuWalletIcon = getBoursecuActionIconSrc('wallet') ?? ''
|
const boursecuWalletIcon = getBoursecuActionIconSrc('wallet') ?? ''
|
||||||
const boursecuHomeIcon = getBoursecuActionIconSrc('home') ?? ''
|
const boursecuHomeIcon = getBoursecuActionIconSrc('home') ?? ''
|
||||||
const boursecuSettingsIcon = getBoursecuActionIconSrc('settings') ?? ''
|
const boursecuSettingsIcon = getBoursecuActionIconSrc('settings') ?? ''
|
||||||
const whiteNavLogoProjects = ['goldenramin']
|
|
||||||
const isWhiteNavLogo = computed(() => whiteNavLogoProjects.includes(projectName))
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -32,13 +32,8 @@ const KATOD_DEVIATION_FACTOR = 200
|
|||||||
|
|
||||||
/** نمودار boursecu وقتی metal_type = کاتد مس */
|
/** نمودار boursecu وقتی metal_type = کاتد مس */
|
||||||
export function shouldAmplifyKatodMesChart(options: {
|
export function shouldAmplifyKatodMesChart(options: {
|
||||||
isBoursecu: boolean
|
|
||||||
metalTypeSetting?: string | number | null
|
metalTypeSetting?: string | number | null
|
||||||
}): boolean {
|
}): boolean {
|
||||||
if (!options.isBoursecu) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const metal = String(options.metalTypeSetting ?? '').trim()
|
const metal = String(options.metalTypeSetting ?? '').trim()
|
||||||
return metal === 'کاتد مس'
|
return metal === 'کاتد مس'
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-123
@@ -9,14 +9,9 @@ import boursecuBuySellIcon from '@/assets/img/boursecu-buy-sell-icon.png'
|
|||||||
import boursecuAssetsIcon from '@/assets/img/boursecu-assets-icon.png'
|
import boursecuAssetsIcon from '@/assets/img/boursecu-assets-icon.png'
|
||||||
import boursecuHomeIcon from '@/assets/img/boursecu-home-icon.png'
|
import boursecuHomeIcon from '@/assets/img/boursecu-home-icon.png'
|
||||||
import boursecuSettingsIcon from '@/assets/img/boursecu-settings-icon.png'
|
import boursecuSettingsIcon from '@/assets/img/boursecu-settings-icon.png'
|
||||||
import bazretalaLoginLogo from '@/assets/img/bazretala-login-logo.png'
|
|
||||||
import bazretalaNavLogo from '@/assets/img/bazretala-nav-logo.png'
|
|
||||||
import bazretalaFundBg from '@/assets/img/bazretala-fund-bg.png'
|
|
||||||
import bazretalaEmptyFund from '@/assets/img/bazretala-empty-fund.png'
|
|
||||||
import soroushgoldLoginLogo from '@/assets/img/soroushgold-login-logo.png'
|
|
||||||
|
|
||||||
export function getConfigApp(key: string) {
|
export function getConfigApp(key: string) {
|
||||||
const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user:{}
|
const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user : {}
|
||||||
|
|
||||||
if (config) {
|
if (config) {
|
||||||
return config[key]
|
return config[key]
|
||||||
@@ -24,32 +19,15 @@ export function getConfigApp(key: string) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** boursecu-only branch */
|
||||||
export function isBoursecuProject() {
|
export function isBoursecuProject() {
|
||||||
return getConfigApp('name') === 'boursecu'
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isBazretalaProject() {
|
const WALLET_DEPOSIT_QUICK_AMOUNTS_RIAL = [10_000_000, 50_000_000, 100_000_000] as const
|
||||||
return getConfigApp('name') === 'bazretala'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isSoroushgoldProject() {
|
|
||||||
return getConfigApp('name') === 'soroushgold'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isNiazitalaProject() {
|
|
||||||
return getConfigApp('name') === 'niazitala'
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_WALLET_DEPOSIT_QUICK_AMOUNTS_RIAL = [10_000_000, 50_000_000, 100_000_000] as const
|
|
||||||
|
|
||||||
/** niazitala: 5 / 10 / 15 میلیون تومان — ذخیره و نمایش به ریال */
|
|
||||||
const NIAZITALA_WALLET_DEPOSIT_QUICK_AMOUNTS_RIAL = [50_000_000, 100_000_000, 150_000_000] as const
|
|
||||||
|
|
||||||
export function getWalletDepositQuickAmountsRial(): readonly number[] {
|
export function getWalletDepositQuickAmountsRial(): readonly number[] {
|
||||||
if (isNiazitalaProject()) {
|
return WALLET_DEPOSIT_QUICK_AMOUNTS_RIAL
|
||||||
return NIAZITALA_WALLET_DEPOSIT_QUICK_AMOUNTS_RIAL
|
|
||||||
}
|
|
||||||
return DEFAULT_WALLET_DEPOSIT_QUICK_AMOUNTS_RIAL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBoursecuTransactionsIcon() {
|
export function getBoursecuTransactionsIcon() {
|
||||||
@@ -100,7 +78,7 @@ export function getBoursecuActionIconSrc(actionId: string): string | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function hasCustomLoginLogoLayout() {
|
export function hasCustomLoginLogoLayout() {
|
||||||
return isBoursecuProject() || isBazretalaProject()
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BOURSECU_BRAND_RED = '#bc3c3b'
|
export const BOURSECU_BRAND_RED = '#bc3c3b'
|
||||||
@@ -111,22 +89,21 @@ export const BOURSECU_COPPER_BG_LIGHT = '#fdf0e6'
|
|||||||
export const BOURSECU_COPPER_BG_GRADIENT = 'linear-gradient(135deg, #c98a4a 0%, #a86528 100%)'
|
export const BOURSECU_COPPER_BG_GRADIENT = 'linear-gradient(135deg, #c98a4a 0%, #a86528 100%)'
|
||||||
|
|
||||||
export function getProjectBrandRed() {
|
export function getProjectBrandRed() {
|
||||||
return isBoursecuProject() ? BOURSECU_BRAND_RED : null
|
return BOURSECU_BRAND_RED
|
||||||
}
|
}
|
||||||
|
|
||||||
/** رنگ accent تم از تنظیمات tenant — بدون override پروژهای */
|
/** رنگ accent تم از تنظیمات tenant */
|
||||||
export function getProjectPrimaryColor() {
|
export function getProjectPrimaryColor() {
|
||||||
const color = getConfigApp('color')
|
const color = getConfigApp('color')
|
||||||
return color != null ? String(color) : undefined
|
return color != null ? String(color) : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
/** فقط رنگ خط/ناحیه نمودار قیمت در بورس مس */
|
|
||||||
export function getBoursecuChartColor() {
|
export function getBoursecuChartColor() {
|
||||||
return BOURSECU_BRAND_BLUE
|
return BOURSECU_BRAND_BLUE
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveProjectColor(color?: string | null) {
|
export function resolveProjectColor(color?: string | null) {
|
||||||
if (!color || !isBoursecuProject()) {
|
if (!color) {
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,131 +114,66 @@ export function resolveProjectColor(color?: string | null) {
|
|||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
|
|
||||||
/** لوگوی پنل برند لاگین دسکتاپ — فقط soroushgold لوگوی اختصاصی دارد */
|
export function getProjectDesktopLoginBrandLogo(_avatar?: string | null) {
|
||||||
export function getProjectDesktopLoginBrandLogo(avatar?: string | null) {
|
return getProjectSplashLogo()
|
||||||
if (isSoroushgoldProject()) {
|
|
||||||
return soroushgoldLoginLogo
|
|
||||||
}
|
|
||||||
return getProjectSplashLogo(avatar)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectLoginLogo(avatar?: string | null) {
|
export function getProjectLoginLogo(_avatar?: string | null) {
|
||||||
if (isBoursecuProject()) {
|
return boursecuLoginLogo
|
||||||
return boursecuLoginLogo
|
|
||||||
}
|
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return bazretalaLoginLogo
|
|
||||||
}
|
|
||||||
return avatar ?? getConfigApp('avatar')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** لوگوی صفحه لودینگ اولیه — جدا از لوگوی لاگین/ناوبری */
|
export function getProjectSplashLogo(_avatar?: string | null) {
|
||||||
export function getProjectSplashLogo(avatar?: string | null) {
|
return boursecuSplashLogo
|
||||||
if (isBoursecuProject()) {
|
|
||||||
return boursecuSplashLogo
|
|
||||||
}
|
|
||||||
return getProjectLoginLogo(avatar)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectNavLogo(avatar?: string | null) {
|
export function getProjectNavLogo(_avatar?: string | null) {
|
||||||
if (isBazretalaProject()) {
|
return boursecuLogo
|
||||||
return bazretalaNavLogo
|
|
||||||
}
|
|
||||||
if (isBoursecuProject()) {
|
|
||||||
return boursecuLogo
|
|
||||||
}
|
|
||||||
return avatar ?? getConfigApp('avatar')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** لوگوی ناوبری موبایل — boursecu همان لوگوی لاگین (پسزمینه سفید) */
|
export function getProjectMobileNavLogo(_avatar?: string | null) {
|
||||||
export function getProjectMobileNavLogo(avatar?: string | null) {
|
return boursecuLoginLogo
|
||||||
if (isBoursecuProject()) {
|
|
||||||
return boursecuLoginLogo
|
|
||||||
}
|
|
||||||
if (isSoroushgoldProject()) {
|
|
||||||
return soroushgoldLoginLogo
|
|
||||||
}
|
|
||||||
return getProjectNavLogo(avatar)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BAZRETALA_SUPPORT_PHONE = '09121784258'
|
|
||||||
|
|
||||||
export function getProjectSupportPhone() {
|
export function getProjectSupportPhone() {
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return BAZRETALA_SUPPORT_PHONE
|
|
||||||
}
|
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectSupportPhoneLink() {
|
export function getProjectSupportPhoneLink() {
|
||||||
const phone = getProjectSupportPhone()
|
return 'tel:'
|
||||||
return phone ? `tel:${phone}` : 'tel:'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BAZRETALA_BALE_ID = 'bazretala'
|
|
||||||
|
|
||||||
export function getProjectBaleLink() {
|
export function getProjectBaleLink() {
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return `https://ble.ir/${BAZRETALA_BALE_ID}`
|
|
||||||
}
|
|
||||||
return 'https://ble.ir/'
|
return 'https://ble.ir/'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectBaleContactLink() {
|
export function getProjectBaleContactLink() {
|
||||||
if (getConfigApp('name') === 'garoosi') {
|
|
||||||
return 'https://ble.ir/garoosiadmin'
|
|
||||||
}
|
|
||||||
return getProjectBaleLink()
|
return getProjectBaleLink()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** لینک دکمه «تماس با پشتیبانی» — bazretala به بله، garoosi تماس، بقیه تلفن پشتیبانی */
|
|
||||||
export function getProjectSupportContactLink() {
|
export function getProjectSupportContactLink() {
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return getProjectBaleLink()
|
|
||||||
}
|
|
||||||
if (getConfigApp('name') === 'garoosi') {
|
|
||||||
return 'tel:09031265925'
|
|
||||||
}
|
|
||||||
return getProjectSupportPhoneLink()
|
return getProjectSupportPhoneLink()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectFundHeaderBackground(defaultBackground: string) {
|
export function getProjectFundHeaderBackground(defaultBackground: string) {
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return bazretalaFundBg
|
|
||||||
}
|
|
||||||
return defaultBackground
|
return defaultBackground
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectFundEmptyImage(defaultImage: string) {
|
export function getProjectFundEmptyImage(defaultImage: string) {
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return bazretalaEmptyFund
|
|
||||||
}
|
|
||||||
return defaultImage
|
return defaultImage
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectFundEmptyText() {
|
export function getProjectFundEmptyText() {
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return 'یک بذر جدید بکار!'
|
|
||||||
}
|
|
||||||
return 'یک گنج جدید بساز!'
|
return 'یک گنج جدید بساز!'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectLoginTaglineLines() {
|
export function getProjectLoginTaglineLines() {
|
||||||
if (!isBoursecuProject()) {
|
return ['مرجع هوشمند معاملات', ' و سرمایهگذاری در صنعت مس']
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'مرجع هوشمند معاملات',
|
|
||||||
' و سرمایهگذاری در صنعت مس',
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectSplashBackground() {
|
export function getProjectSplashBackground() {
|
||||||
return isBoursecuProject() ? BOURSECU_BRAND_NAV : '#ffffff'
|
return BOURSECU_BRAND_NAV
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reset splash-time inline backgrounds so mobile overscroll shows white again. */
|
|
||||||
export function resetAppSurfaceBackground() {
|
export function resetAppSurfaceBackground() {
|
||||||
const background = '#ffffff'
|
const background = '#ffffff'
|
||||||
document.documentElement.style.backgroundColor = background
|
document.documentElement.style.backgroundColor = background
|
||||||
@@ -274,30 +186,25 @@ export function resetAppSurfaceBackground() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getProjectFontFamily() {
|
export function getProjectFontFamily() {
|
||||||
return getConfigApp('name') === 'boursecu' ? "'dana', sans-serif" : "'iran-sans', sans-serif"
|
return "'dana', sans-serif"
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyProjectFont() {
|
export function applyProjectFont() {
|
||||||
document.documentElement.style.setProperty('--App-font-family', getProjectFontFamily())
|
document.documentElement.style.setProperty('--App-font-family', getProjectFontFamily())
|
||||||
if (getConfigApp('name') === 'boursecu') {
|
document.documentElement.classList.add('font-dana')
|
||||||
document.documentElement.classList.add('font-dana')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTWA() {
|
export function isTWA() {
|
||||||
if (sessionStorage.getItem('appMode') === 'twa') return true;
|
if (sessionStorage.getItem('appMode') === 'twa') return true
|
||||||
if (document.referrer.startsWith('android-app://')) {
|
if (document.referrer.startsWith('android-app://')) {
|
||||||
sessionStorage.setItem('appMode', 'twa');
|
sessionStorage.setItem('appMode', 'twa')
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyProjectTheme() {
|
export function applyProjectTheme() {
|
||||||
applyProjectFont()
|
applyProjectFont()
|
||||||
|
|
||||||
if (!isBoursecuProject()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
document.documentElement.classList.add('project-boursecu')
|
document.documentElement.classList.add('project-boursecu')
|
||||||
document.documentElement.style.setProperty('--App-brand-nav', BOURSECU_BRAND_NAV)
|
document.documentElement.style.setProperty('--App-brand-nav', BOURSECU_BRAND_NAV)
|
||||||
document.documentElement.style.setProperty('--App-brand-red', BOURSECU_BRAND_RED)
|
document.documentElement.style.setProperty('--App-brand-red', BOURSECU_BRAND_RED)
|
||||||
|
|||||||
@@ -76,14 +76,7 @@ export function resolveBoursecuAssetMetalTotals(
|
|||||||
return ordered
|
return ordered
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveMetalAssetsDisplayLabel(
|
export function resolveMetalAssetsDisplayLabel(metal: WalletMetalTotal): string {
|
||||||
metal: WalletMetalTotal,
|
|
||||||
isBoursecuLayout: boolean
|
|
||||||
): string {
|
|
||||||
if (!isBoursecuLayout) {
|
|
||||||
return metal.label
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (metal.metal_id) {
|
switch (metal.metal_id) {
|
||||||
case METAL_COPPER:
|
case METAL_COPPER:
|
||||||
return 'دارایی مس'
|
return 'دارایی مس'
|
||||||
@@ -121,7 +114,7 @@ export function formatBoursecuMetalModalText(metal: WalletMetalTotal): string {
|
|||||||
case METAL_SILVER:
|
case METAL_SILVER:
|
||||||
return 'دارایی نقره = موجودی نقره'
|
return 'دارایی نقره = موجودی نقره'
|
||||||
default:
|
default:
|
||||||
return `${resolveMetalAssetsDisplayLabel(metal, true)} = موجودی ${metal.label}`
|
return `${resolveMetalAssetsDisplayLabel(metal)} = موجودی ${metal.label}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { SelectItem } from '@/models/SelectItem'
|
import type { SelectItem } from '@/models/SelectItem'
|
||||||
import type { Product } from '@/models/products'
|
import type { Product } from '@/models/products'
|
||||||
import type { WalletInventoryCard } from '@/models/walletAssets'
|
import type { WalletInventoryCard } from '@/models/walletAssets'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { useSettingsStore } from '@/store/settingsStore'
|
import { useSettingsStore } from '@/store/settingsStore'
|
||||||
import {
|
import {
|
||||||
isLegacyMaftolGroup,
|
isLegacyMaftolGroup,
|
||||||
@@ -25,10 +24,6 @@ export const BOURSECU_GROUP_MAFTOL = LEGACY_GROUP_MAFTOL
|
|||||||
export const BOURSECU_WALLET_LABEL_GENERIC = 'موجودی کیف'
|
export const BOURSECU_WALLET_LABEL_GENERIC = 'موجودی کیف'
|
||||||
|
|
||||||
export function isBoursecuDealProductGroup(groupType?: string | null) {
|
export function isBoursecuDealProductGroup(groupType?: string | null) {
|
||||||
if (!isBoursecuProject()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const group = normalizeProductGroupType(groupType)
|
const group = normalizeProductGroupType(groupType)
|
||||||
return group === BOURSECU_GROUP_MAFTOL
|
return group === BOURSECU_GROUP_MAFTOL
|
||||||
|| group === BOURSECU_GROUP_KATOD
|
|| group === BOURSECU_GROUP_KATOD
|
||||||
@@ -38,7 +33,7 @@ export function isBoursecuDealProductGroup(groupType?: string | null) {
|
|||||||
|
|
||||||
export function isMaftolMesGroup(groupType?: string | null) {
|
export function isMaftolMesGroup(groupType?: string | null) {
|
||||||
const group = normalizeProductGroupType(groupType)
|
const group = normalizeProductGroupType(groupType)
|
||||||
return group === BOURSECU_GROUP_MAFTOL || (isBoursecuProject() && group === 'مس')
|
return group === BOURSECU_GROUP_MAFTOL || group === 'مس'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isKatodMesGroup(groupType?: string | null) {
|
export function isKatodMesGroup(groupType?: string | null) {
|
||||||
@@ -46,10 +41,6 @@ export function isKatodMesGroup(groupType?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isShamshMesGroup(groupType?: string | null, title?: string | null) {
|
export function isShamshMesGroup(groupType?: string | null, title?: string | null) {
|
||||||
if (!isBoursecuProject()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const group = normalizeProductGroupType(groupType)
|
const group = normalizeProductGroupType(groupType)
|
||||||
if (group === 'شمش') {
|
if (group === 'شمش') {
|
||||||
return true
|
return true
|
||||||
@@ -115,11 +106,9 @@ export function getProductWeightUnit(product?: ProductUnitSource | null) {
|
|||||||
return unit
|
return unit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBoursecuProject()) {
|
const group = normalizeProductGroupType(product?.group_type)
|
||||||
const group = normalizeProductGroupType(product?.group_type)
|
if (group === BOURSECU_GROUP_MAFTOL || group === BOURSECU_GROUP_KATOD || group === BOURSECU_GROUP_ABSHODE || group === 'مس' || isMeltedTradeGroup(group)) {
|
||||||
if (group === BOURSECU_GROUP_MAFTOL || group === BOURSECU_GROUP_KATOD || group === BOURSECU_GROUP_ABSHODE || group === 'مس' || isMeltedTradeGroup(group)) {
|
return getWeightUnit()
|
||||||
return getWeightUnit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCountBasedProduct(product) || isMeltedTradeGroup(product?.group_type)) {
|
if (!isCountBasedProduct(product) || isMeltedTradeGroup(product?.group_type)) {
|
||||||
@@ -209,7 +198,7 @@ export function isCountBasedProduct(product?: ProductUnitSource | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const group = normalizeProductGroupType(product.group_type)
|
const group = normalizeProductGroupType(product.group_type)
|
||||||
if (group === BOURSECU_GROUP_MAFTOL || isLegacyMaftolGroup(group) || (isBoursecuProject() && group === 'مس')) {
|
if (group === BOURSECU_GROUP_MAFTOL || isLegacyMaftolGroup(group) || group === 'مس') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,10 +396,6 @@ export function getProductDealMethodOptions(
|
|||||||
): SelectItem[] {
|
): SelectItem[] {
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
|
|
||||||
if (!isBoursecuProject()) {
|
|
||||||
return getDefaultTypeDealOptions(context, isBuy)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMaftolMesGroup(groupType)) {
|
if (isMaftolMesGroup(groupType)) {
|
||||||
if (isBuy) {
|
if (isBuy) {
|
||||||
return [
|
return [
|
||||||
@@ -518,10 +503,6 @@ export function getBoursecuMetalWalletLabel(groupType?: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getGoldWalletLabel(groupType?: string | null) {
|
export function getGoldWalletLabel(groupType?: string | null) {
|
||||||
if (!isBoursecuProject()) {
|
|
||||||
return getMainMetalWalletLabel()
|
|
||||||
}
|
|
||||||
|
|
||||||
const group = normalizeProductGroupType(groupType)
|
const group = normalizeProductGroupType(groupType)
|
||||||
if (group === BOURSECU_GROUP_MAFTOL
|
if (group === BOURSECU_GROUP_MAFTOL
|
||||||
|| group === BOURSECU_GROUP_KATOD
|
|| group === BOURSECU_GROUP_KATOD
|
||||||
@@ -575,7 +556,7 @@ export function formatCashWalletBalanceText(cashFormatted: string | number, grou
|
|||||||
|
|
||||||
/** برچسب کیف فلزی متناسب با نحوه پرداخت (مثلاً کاتد مس برای خرید مفتول با کیف کاتد) */
|
/** برچسب کیف فلزی متناسب با نحوه پرداخت (مثلاً کاتد مس برای خرید مفتول با کیف کاتد) */
|
||||||
export function getMetalWalletLabelForDealMethod(method?: string | null, groupType?: string | null) {
|
export function getMetalWalletLabelForDealMethod(method?: string | null, groupType?: string | null) {
|
||||||
if (!isBoursecuProject() || method === 'katod') {
|
if (method === 'katod') {
|
||||||
return getMainMetalWalletLabel()
|
return getMainMetalWalletLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,8 @@
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
variant === 'desktop'
|
variant === 'desktop'
|
||||||
? (isBoursecu ? 'dabout-content--boursecu' : 'dabout-content--default')
|
? 'dabout-content--boursecu'
|
||||||
: (isBoursecuProject()
|
: 'border-solid border-2 border-primary text-primary rounded-[12px] p-4 text-xs leading-5 mobile-content-box',
|
||||||
? 'border-solid border-2 border-primary text-primary rounded-[12px] p-4 text-xs leading-5 mobile-content-box'
|
|
||||||
: 'bg-primary text-white rounded-[12px] p-4 text-xs leading-5 mobile-content-box'),
|
|
||||||
'dabout-content',
|
'dabout-content',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
@@ -63,9 +61,5 @@ withDefaults(
|
|||||||
{ variant: 'mobile' },
|
{ variant: 'mobile' },
|
||||||
)
|
)
|
||||||
|
|
||||||
const {
|
const { aboutSections } = useAboutPageContext()
|
||||||
aboutSections,
|
|
||||||
isBoursecu,
|
|
||||||
isBoursecuProject,
|
|
||||||
} = useAboutPageContext()
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,15 +3,12 @@ import { useConfigStore } from '@/store/configStore'
|
|||||||
import {
|
import {
|
||||||
getProjectBaleLink,
|
getProjectBaleLink,
|
||||||
getProjectSupportPhoneLink,
|
getProjectSupportPhoneLink,
|
||||||
isBoursecuProject,
|
|
||||||
} from '@/utils/config'
|
} from '@/utils/config'
|
||||||
import { getAboutSections, type AboutSection } from '../aboutContent'
|
import { getAboutSections, type AboutSection } from '../aboutContent'
|
||||||
|
|
||||||
export interface AboutPageContext {
|
export interface AboutPageContext {
|
||||||
config: ReturnType<typeof useConfigStore>
|
config: ReturnType<typeof useConfigStore>
|
||||||
aboutSections: ComputedRef<AboutSection[]>
|
aboutSections: ComputedRef<AboutSection[]>
|
||||||
isBoursecu: ComputedRef<boolean>
|
|
||||||
isBoursecuProject: typeof isBoursecuProject
|
|
||||||
getProjectSupportPhoneLink: typeof getProjectSupportPhoneLink
|
getProjectSupportPhoneLink: typeof getProjectSupportPhoneLink
|
||||||
getProjectBaleLink: typeof getProjectBaleLink
|
getProjectBaleLink: typeof getProjectBaleLink
|
||||||
}
|
}
|
||||||
@@ -22,15 +19,11 @@ export function useAboutPage() {
|
|||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
const nameProject = config.config.name_fa
|
const nameProject = config.config.name_fa
|
||||||
|
|
||||||
const isBoursecu = computed(() => isBoursecuProject())
|
const aboutSections = computed(() => getAboutSections(nameProject, true))
|
||||||
|
|
||||||
const aboutSections = computed(() => getAboutSections(nameProject, isBoursecu.value))
|
|
||||||
|
|
||||||
const context: AboutPageContext = {
|
const context: AboutPageContext = {
|
||||||
config,
|
config,
|
||||||
aboutSections,
|
aboutSections,
|
||||||
isBoursecu,
|
|
||||||
isBoursecuProject,
|
|
||||||
getProjectSupportPhoneLink,
|
getProjectSupportPhoneLink,
|
||||||
getProjectBaleLink,
|
getProjectBaleLink,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { createAddress, getCity, updateAddress } from '@/api/address'
|
|||||||
import type { Address } from '@/models/address'
|
import type { Address } from '@/models/address'
|
||||||
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
||||||
import { loading, loadingMore } from '@/utils'
|
import { loading, loadingMore } from '@/utils'
|
||||||
import { isBazretalaProject } from '@/utils/config'
|
|
||||||
import {
|
import {
|
||||||
addressItems,
|
addressItems,
|
||||||
addressProvinceList,
|
addressProvinceList,
|
||||||
@@ -23,7 +22,6 @@ export interface AddressPageContext {
|
|||||||
formRef: Ref<FormInstance | undefined>
|
formRef: Ref<FormInstance | undefined>
|
||||||
loading: typeof loading
|
loading: typeof loading
|
||||||
loadingMore: typeof loadingMore
|
loadingMore: typeof loadingMore
|
||||||
isBazretalaProject: typeof isBazretalaProject
|
|
||||||
resetFields: () => void
|
resetFields: () => void
|
||||||
openAdd: () => void
|
openAdd: () => void
|
||||||
openEdit: (val: Address) => void
|
openEdit: (val: Address) => void
|
||||||
@@ -120,7 +118,6 @@ export function useAddressPage() {
|
|||||||
formRef,
|
formRef,
|
||||||
loading,
|
loading,
|
||||||
loadingMore,
|
loadingMore,
|
||||||
isBazretalaProject,
|
|
||||||
resetFields,
|
resetFields,
|
||||||
openAdd,
|
openAdd,
|
||||||
openEdit,
|
openEdit,
|
||||||
|
|||||||
@@ -7,13 +7,6 @@
|
|||||||
<p class="daddr-topbar__subtitle">آدرسهای تحویل سفارش خود را مدیریت کنید</p>
|
<p class="daddr-topbar__subtitle">آدرسهای تحویل سفارش خود را مدیریت کنید</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div
|
|
||||||
v-if="isBazretalaProject()"
|
|
||||||
class="daddr-notice"
|
|
||||||
>
|
|
||||||
جهت تحویل فیزیکی محصول در تهران و قم ازطریق معرف اقدام فرمائید یا با شماره امورمالی و حسابداری 09925202099 درارتباط باشید.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="daddr-grid">
|
<div class="daddr-grid">
|
||||||
<section class="daddr-surface daddr-form">
|
<section class="daddr-surface daddr-form">
|
||||||
<div class="daddr-form__header">
|
<div class="daddr-form__header">
|
||||||
@@ -78,7 +71,6 @@ const {
|
|||||||
items,
|
items,
|
||||||
loading,
|
loading,
|
||||||
editId,
|
editId,
|
||||||
isBazretalaProject,
|
|
||||||
openAdd,
|
openAdd,
|
||||||
openEdit,
|
openEdit,
|
||||||
initItems,
|
initItems,
|
||||||
|
|||||||
@@ -9,13 +9,6 @@
|
|||||||
:class="loading ? 'h-screen' : ''"
|
:class="loading ? 'h-screen' : ''"
|
||||||
class="relative z-1 px-3 mpage-content pb-2 overflow-y-scroll mpage-scroll"
|
class="relative z-1 px-3 mpage-content pb-2 overflow-y-scroll mpage-scroll"
|
||||||
>
|
>
|
||||||
<div
|
|
||||||
v-if="isBazretalaProject()"
|
|
||||||
class="text-justify text-sm text-primary mb-4 px-1 leading-7"
|
|
||||||
>
|
|
||||||
جهت تحویل فیزیکی محصول در تهران و قم ازطریق معرف اقدام فرمائید یا با شماره امورمالی و حسابداری 09925202099 درارتباط باشید.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!loading"
|
v-if="!loading"
|
||||||
class="pb-[calc(var(--app-bottom-chrome-height)+var(--app-add-card-height)+1rem)]"
|
class="pb-[calc(var(--app-bottom-chrome-height)+var(--app-add-card-height)+1rem)]"
|
||||||
@@ -58,7 +51,6 @@ const {
|
|||||||
items,
|
items,
|
||||||
loading,
|
loading,
|
||||||
addAddressVisible,
|
addAddressVisible,
|
||||||
isBazretalaProject,
|
|
||||||
openAdd,
|
openAdd,
|
||||||
openEdit,
|
openEdit,
|
||||||
initItems,
|
initItems,
|
||||||
|
|||||||
@@ -36,8 +36,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||||
import { getProjectBaleContactLink, getProjectSupportContactLink, isBazretalaProject } from '@/utils/config'
|
import { getProjectBaleContactLink, getProjectSupportContactLink } from '@/utils/config'
|
||||||
import { useEducatePageContext } from '../composables/useEducatePage'
|
|
||||||
|
|
||||||
withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@@ -46,11 +45,7 @@ withDefaults(
|
|||||||
{ variant: 'mobile' },
|
{ variant: 'mobile' },
|
||||||
)
|
)
|
||||||
|
|
||||||
const { config } = useEducatePageContext()
|
const showBaleSupport = computed(() => false)
|
||||||
|
|
||||||
const showBaleSupport = computed(
|
|
||||||
() => config.config.name === 'garoosi' || isBazretalaProject(),
|
|
||||||
)
|
|
||||||
const supportHref = computed(() => getProjectSupportContactLink())
|
const supportHref = computed(() => getProjectSupportContactLink())
|
||||||
const baleHref = computed(() => getProjectBaleContactLink())
|
const baleHref = computed(() => getProjectBaleContactLink())
|
||||||
const opensSupportInNewTab = computed(() => supportHref.value.startsWith('http'))
|
const opensSupportInNewTab = computed(() => supportHref.value.startsWith('http'))
|
||||||
|
|||||||
@@ -6,13 +6,11 @@ import { useConfigStore } from '@/store/configStore'
|
|||||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
import type { WalletMetalTotal } from '@/models/walletAssets'
|
||||||
import { resolveSummaryMetalWeight, fundPageInventoryCards } from '@/utils/productAssets'
|
import { resolveSummaryMetalWeight, fundPageInventoryCards } from '@/utils/productAssets'
|
||||||
import { useWalletStore } from '@/store/walletStore'
|
|
||||||
import { getLastPrices } from '@/utils/price'
|
import { getLastPrices } from '@/utils/price'
|
||||||
import {
|
import {
|
||||||
getProjectFundEmptyImage,
|
getProjectFundEmptyImage,
|
||||||
getProjectFundEmptyText,
|
getProjectFundEmptyText,
|
||||||
getProjectFundHeaderBackground,
|
getProjectFundHeaderBackground,
|
||||||
isBazretalaProject,
|
|
||||||
} from '@/utils/config'
|
} from '@/utils/config'
|
||||||
import img from '@/assets/img/user_ly1.svg'
|
import img from '@/assets/img/user_ly1.svg'
|
||||||
import empty from '@/assets/img/cash_empty.svg'
|
import empty from '@/assets/img/cash_empty.svg'
|
||||||
@@ -30,7 +28,6 @@ export interface FundPageContext {
|
|||||||
fundHeaderBackground: string
|
fundHeaderBackground: string
|
||||||
fundEmptyImage: string
|
fundEmptyImage: string
|
||||||
fundEmptyText: string
|
fundEmptyText: string
|
||||||
isBazretalaProject: typeof isBazretalaProject
|
|
||||||
formatMetalTotal: (metal: WalletMetalTotal) => string
|
formatMetalTotal: (metal: WalletMetalTotal) => string
|
||||||
openFundInfo: (productId: number) => void
|
openFundInfo: (productId: number) => void
|
||||||
goBack: () => void
|
goBack: () => void
|
||||||
@@ -41,7 +38,6 @@ export const FUND_PAGE_KEY: InjectionKey<FundPageContext> = Symbol('fundPage')
|
|||||||
export function useFundPage(isDesktop: Ref<boolean>) {
|
export function useFundPage(isDesktop: Ref<boolean>) {
|
||||||
const nameProject = useConfigStore().config.name
|
const nameProject = useConfigStore().config.name
|
||||||
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
||||||
const walletStore = useWalletStore()
|
|
||||||
const fundHeaderBackground = getProjectFundHeaderBackground(img)
|
const fundHeaderBackground = getProjectFundHeaderBackground(img)
|
||||||
const fundEmptyImage = getProjectFundEmptyImage(empty)
|
const fundEmptyImage = getProjectFundEmptyImage(empty)
|
||||||
const fundEmptyText = getProjectFundEmptyText()
|
const fundEmptyText = getProjectFundEmptyText()
|
||||||
@@ -77,9 +73,6 @@ export function useFundPage(isDesktop: Ref<boolean>) {
|
|||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const tasks = [loadWalletAssets(true), getLastPrices()]
|
const tasks = [loadWalletAssets(true), getLastPrices()]
|
||||||
if (isBazretalaProject()) {
|
|
||||||
tasks.push(walletStore.getMyWallet())
|
|
||||||
}
|
|
||||||
await Promise.all(tasks)
|
await Promise.all(tasks)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -101,7 +94,6 @@ export function useFundPage(isDesktop: Ref<boolean>) {
|
|||||||
fundHeaderBackground,
|
fundHeaderBackground,
|
||||||
fundEmptyImage,
|
fundEmptyImage,
|
||||||
fundEmptyText,
|
fundEmptyText,
|
||||||
isBazretalaProject,
|
|
||||||
formatMetalTotal,
|
formatMetalTotal,
|
||||||
openFundInfo,
|
openFundInfo,
|
||||||
goBack,
|
goBack,
|
||||||
|
|||||||
@@ -13,15 +13,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section
|
<section class="dfund-summary">
|
||||||
class="dfund-summary"
|
|
||||||
:class="{ 'dfund-summary--bazretala': isBazretalaProject() }"
|
|
||||||
>
|
|
||||||
<img
|
<img
|
||||||
:src="fundHeaderBackground"
|
:src="fundHeaderBackground"
|
||||||
alt=""
|
alt=""
|
||||||
class="dfund-summary__bg"
|
class="dfund-summary__bg"
|
||||||
:class="{ 'dfund-summary__bg--cover': isBazretalaProject() }"
|
|
||||||
/>
|
/>
|
||||||
<div class="dfund-summary__content">
|
<div class="dfund-summary__content">
|
||||||
<h2 class="dfund-summary__title">موجودی داراییها</h2>
|
<h2 class="dfund-summary__title">موجودی داراییها</h2>
|
||||||
@@ -31,17 +27,7 @@
|
|||||||
<strong>{{ countBasedInventory }} عدد</strong>
|
<strong>{{ countBasedInventory }} عدد</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="isBazretalaProject()">
|
<template v-if="meta?.single_metal && primaryMetalTotal">
|
||||||
<div class="dfund-summary__row">
|
|
||||||
<span>دارایی نقره</span>
|
|
||||||
<strong>{{ walletStore.walletInfo?.count_silver ?? 0 }} گرم</strong>
|
|
||||||
</div>
|
|
||||||
<div class="dfund-summary__row">
|
|
||||||
<span>دارایی طلایی</span>
|
|
||||||
<strong>{{ walletStore.walletInfo?.count_gold_wallet ?? 0 }} گرم</strong>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="meta?.single_metal && primaryMetalTotal">
|
|
||||||
<div class="dfund-summary__row">
|
<div class="dfund-summary__row">
|
||||||
<span>{{ primaryMetalTotal.label }}</span>
|
<span>{{ primaryMetalTotal.label }}</span>
|
||||||
<strong>{{ formatMetalTotal(primaryMetalTotal) }}</strong>
|
<strong>{{ formatMetalTotal(primaryMetalTotal) }}</strong>
|
||||||
@@ -59,7 +45,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="meta?.has_count_based_products && !isBazretalaProject()"
|
v-if="meta?.has_count_based_products"
|
||||||
class="dfund-summary__row"
|
class="dfund-summary__row"
|
||||||
>
|
>
|
||||||
<span>مجموع موجودی</span>
|
<span>مجموع موجودی</span>
|
||||||
@@ -112,12 +98,9 @@
|
|||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import { loading } from '@/utils'
|
import { loading } from '@/utils'
|
||||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
import { usePriceWithoutType } from '@/utils/usePrice'
|
||||||
import { useWalletStore } from '@/store/walletStore'
|
|
||||||
import Item from '../components/Item.vue'
|
import Item from '../components/Item.vue'
|
||||||
import { useFundPageContext } from '../composables/useFundPage'
|
import { useFundPageContext } from '../composables/useFundPage'
|
||||||
|
|
||||||
const walletStore = useWalletStore()
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
nameProject,
|
nameProject,
|
||||||
meta,
|
meta,
|
||||||
@@ -130,7 +113,6 @@ const {
|
|||||||
fundHeaderBackground,
|
fundHeaderBackground,
|
||||||
fundEmptyImage,
|
fundEmptyImage,
|
||||||
fundEmptyText,
|
fundEmptyText,
|
||||||
isBazretalaProject,
|
|
||||||
formatMetalTotal,
|
formatMetalTotal,
|
||||||
openFundInfo,
|
openFundInfo,
|
||||||
goBack,
|
goBack,
|
||||||
|
|||||||
@@ -9,22 +9,14 @@
|
|||||||
<div class="mr-2">دارایی ها</div>
|
<div class="mr-2">دارایی ها</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="w-screen md:w-full h-[70vh] fixed md:absolute overflow-hidden"
|
class="w-screen md:w-full h-[70vh] fixed md:absolute overflow-hidden text-tertiary bg-primary"
|
||||||
:class="isBazretalaProject() ? 'bazretala-fund-header' : 'text-tertiary bg-primary'"
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="fundHeaderBackground"
|
:src="fundHeaderBackground"
|
||||||
alt=""
|
alt=""
|
||||||
:class="
|
class="pointer-events-none z-0 w-full absolute bottom-0 left-0 opacity-5"
|
||||||
isBazretalaProject()
|
|
||||||
? 'pointer-events-none z-0 absolute inset-0 w-full object-cover object-center'
|
|
||||||
: 'pointer-events-none z-0 w-full absolute bottom-0 left-0 opacity-5'
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
<div
|
<div class="mobile-page-body--pt15 flex flex-col relative z-10 text-tertiary">
|
||||||
class="mobile-page-body--pt15 flex flex-col relative z-10"
|
|
||||||
:class="isBazretalaProject() ? 'text-white' : 'text-tertiary'"
|
|
||||||
>
|
|
||||||
<div class="font-bold mr-5 z-20">موجودی دارایی ها</div>
|
<div class="font-bold mr-5 z-20">موجودی دارایی ها</div>
|
||||||
<div
|
<div
|
||||||
v-if="meta?.has_count_based_products"
|
v-if="meta?.has_count_based_products"
|
||||||
@@ -33,21 +25,7 @@
|
|||||||
محصولات:
|
محصولات:
|
||||||
<div class="text-l mr-4 font-bold">{{ countBasedInventory }} عدد</div>
|
<div class="text-l mr-4 font-bold">{{ countBasedInventory }} عدد</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="isBazretalaProject()">
|
<template v-if="meta?.single_metal && primaryMetalTotal">
|
||||||
<div class="flex justify-center mt-2 w-full z-20">
|
|
||||||
دارایی نقره:
|
|
||||||
<div class="text-l mr-4 font-bold">
|
|
||||||
{{ walletStore.walletInfo?.count_silver ?? 0 }}گرم
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-center mt-2 w-full z-20">
|
|
||||||
دارایی طلایی:
|
|
||||||
<div class="text-l mr-4 font-bold">
|
|
||||||
{{ walletStore.walletInfo?.count_gold_wallet ?? 0 }}گرم
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="meta?.single_metal && primaryMetalTotal">
|
|
||||||
<div class="flex justify-center mt-2 w-full z-20">
|
<div class="flex justify-center mt-2 w-full z-20">
|
||||||
{{ primaryMetalTotal.label }}:
|
{{ primaryMetalTotal.label }}:
|
||||||
<div class="text-l mr-4 font-bold">{{ formatMetalTotal(primaryMetalTotal) }}</div>
|
<div class="text-l mr-4 font-bold">{{ formatMetalTotal(primaryMetalTotal) }}</div>
|
||||||
@@ -64,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
v-if="meta?.has_count_based_products && !isBazretalaProject()"
|
v-if="meta?.has_count_based_products"
|
||||||
class="flex justify-center mt-2 w-full z-20"
|
class="flex justify-center mt-2 w-full z-20"
|
||||||
>
|
>
|
||||||
مجموع موجودی:
|
مجموع موجودی:
|
||||||
@@ -93,7 +71,7 @@
|
|||||||
<img
|
<img
|
||||||
:src="fundEmptyImage"
|
:src="fundEmptyImage"
|
||||||
alt=""
|
alt=""
|
||||||
:class="isBazretalaProject() ? 'w-48 max-w-[11rem]' : 'w-70'"
|
class="w-70"
|
||||||
/>
|
/>
|
||||||
<div v-if="nameProject !== 'abaeigold'" class="text-center text-lg">
|
<div v-if="nameProject !== 'abaeigold'" class="text-center text-lg">
|
||||||
{{ fundEmptyText }}
|
{{ fundEmptyText }}
|
||||||
@@ -120,12 +98,9 @@
|
|||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import { loading } from '@/utils'
|
import { loading } from '@/utils'
|
||||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
import { usePriceWithoutType } from '@/utils/usePrice'
|
||||||
import { useWalletStore } from '@/store/walletStore'
|
|
||||||
import Item from '../components/Item.vue'
|
import Item from '../components/Item.vue'
|
||||||
import { useFundPageContext } from '../composables/useFundPage'
|
import { useFundPageContext } from '../composables/useFundPage'
|
||||||
|
|
||||||
const walletStore = useWalletStore()
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
nameProject,
|
nameProject,
|
||||||
meta,
|
meta,
|
||||||
@@ -138,24 +113,8 @@ const {
|
|||||||
fundHeaderBackground,
|
fundHeaderBackground,
|
||||||
fundEmptyImage,
|
fundEmptyImage,
|
||||||
fundEmptyText,
|
fundEmptyText,
|
||||||
isBazretalaProject,
|
|
||||||
formatMetalTotal,
|
formatMetalTotal,
|
||||||
openFundInfo,
|
openFundInfo,
|
||||||
goBack,
|
goBack,
|
||||||
} = useFundPageContext()
|
} = useFundPageContext()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.bazretala-fund-header {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bazretala-fund-header::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: 1;
|
|
||||||
background: rgba(0, 0, 0, 0.45);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -5,21 +5,12 @@
|
|||||||
:class="{ 'app-header--scrolled': isHeaderScrolled }"
|
:class="{ 'app-header--scrolled': isHeaderScrolled }"
|
||||||
>
|
>
|
||||||
<div class="flex justify-between my-2 items-center">
|
<div class="flex justify-between my-2 items-center">
|
||||||
<div v-if="isBoursecuProject()" class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<img :src="projectLogo" alt="" class="h-10 w-auto max-w-[9rem] object-contain" />
|
<img :src="projectLogo" alt="" class="h-10 w-auto max-w-[9rem] object-contain" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex items-center gap-2" @click.stop="router.push({ name: 'user' })">
|
|
||||||
<div class="z-100000 rounded-full border-1 text-primary border-primary">
|
|
||||||
<Icon icon="vuesax-linear:user" size="20" />
|
|
||||||
</div>
|
|
||||||
<div class="text-primary color-transition font-bold">
|
|
||||||
{{ userStore.userInfo?.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
v-if="isBoursecuProject()"
|
|
||||||
type="button"
|
type="button"
|
||||||
class="mhome-header-btn"
|
class="mhome-header-btn"
|
||||||
@click="router.push({ name: 'user' })"
|
@click="router.push({ name: 'user' })"
|
||||||
@@ -42,16 +33,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onActivated, onMounted, onUnmounted, ref, watch } from 'vue'
|
import { computed, nextTick, onActivated, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useUserStore } from '@/store/userStore'
|
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import { getProjectMobileNavLogo, isBoursecuProject } from '@/utils/config'
|
import { getProjectMobileNavLogo } from '@/utils/config'
|
||||||
|
|
||||||
const headerRef = ref<HTMLElement | null>(null)
|
const headerRef = ref<HTMLElement | null>(null)
|
||||||
const isHeaderScrolled = ref(false)
|
const isHeaderScrolled = ref(false)
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const projectLogo = computed(() => getProjectMobileNavLogo())
|
const projectLogo = computed(() => getProjectMobileNavLogo())
|
||||||
|
|
||||||
let intersectionObserver: IntersectionObserver | null = null
|
let intersectionObserver: IntersectionObserver | null = null
|
||||||
|
|||||||
@@ -1,127 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="rootClass">
|
<div class="assets-section assets-section--boursecu rounded-lg px-3 py-3 mt-2">
|
||||||
<div
|
|
||||||
v-if="!boursecuLayout && meta?.has_count_based_products"
|
|
||||||
:class="rowClass"
|
|
||||||
class="flex justify-center w-full z-20 mb-2"
|
|
||||||
>
|
|
||||||
محصولات:
|
|
||||||
<div class="text-l mr-2 font-bold">{{ usePriceWithoutType(countBasedInventory, false) }} عدد</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<BoursecuAssetsSummary
|
<BoursecuAssetsSummary
|
||||||
v-if="boursecuLayout"
|
|
||||||
variant="mobile"
|
variant="mobile"
|
||||||
icon-color="primary"
|
icon-color="primary"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-else-if="meta?.single_metal && primaryMetalTotal">
|
|
||||||
<div :class="[rowClass, meta?.has_count_based_products ? 'mt-2' : '']" class="flex justify-center w-full z-20">
|
|
||||||
{{ primaryMetalTotal.label }}:
|
|
||||||
<div class="text-l mr-2 font-bold">{{ formatMetalTotal(primaryMetalTotal) }}</div>
|
|
||||||
<BasicIcon
|
|
||||||
icon="vuesax-linear:info-circle"
|
|
||||||
size="18"
|
|
||||||
:color="iconColor"
|
|
||||||
@click="$emit('openGoldModal', primaryMetalTotal)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PortfolioProfitInsight variant="mobile" />
|
|
||||||
|
|
||||||
<div :class="[rowClass, 'mt-2']" class="flex justify-center w-full z-20">
|
|
||||||
دارایی ریالی:
|
|
||||||
<div class="text-l mr-2 font-bold">{{ usePriceWithoutType(cashWallet) }} ریال</div>
|
|
||||||
<BasicIcon
|
|
||||||
icon="vuesax-linear:info-circle"
|
|
||||||
size="18"
|
|
||||||
:color="iconColor"
|
|
||||||
@click="$emit('openRialModal')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else-if="!boursecuLayout">
|
|
||||||
<div
|
|
||||||
v-for="(metal, index) in metalTotals"
|
|
||||||
:key="metal.metal_id"
|
|
||||||
:class="[rowClass, index > 0 || meta?.has_count_based_products ? 'mt-2' : '']"
|
|
||||||
class="flex justify-center w-full z-20"
|
|
||||||
>
|
|
||||||
{{ metal.label }}:
|
|
||||||
<div class="text-l mr-2 font-bold">{{ formatMetalTotal(metal) }}</div>
|
|
||||||
<BasicIcon
|
|
||||||
v-if="metal.metal_id === metalTotals[0]?.metal_id"
|
|
||||||
icon="vuesax-linear:info-circle"
|
|
||||||
size="18"
|
|
||||||
:color="iconColor"
|
|
||||||
@click="$emit('openGoldModal', metal)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PortfolioProfitInsight variant="mobile" />
|
|
||||||
|
|
||||||
<div :class="[rowClass, 'mt-2']" class="flex justify-center w-full z-20">
|
|
||||||
دارایی ریالی:
|
|
||||||
<div class="text-l mr-2 font-bold">{{ usePriceWithoutType(cashWallet) }} ریال</div>
|
|
||||||
<BasicIcon
|
|
||||||
icon="vuesax-linear:info-circle"
|
|
||||||
size="18"
|
|
||||||
:color="iconColor"
|
|
||||||
@click="$emit('openRialModal')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
|
||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
|
||||||
import BoursecuAssetsSummary from './BoursecuAssetsSummary.vue'
|
import BoursecuAssetsSummary from './BoursecuAssetsSummary.vue'
|
||||||
import PortfolioProfitInsight from './PortfolioProfitInsight.vue'
|
|
||||||
import { formatWeightAmount, usePriceWithoutType } from '@/utils/usePrice'
|
|
||||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
|
||||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
import type { WalletMetalTotal } from '@/models/walletAssets'
|
||||||
import { resolveSummaryMetalWeight } from '@/utils/productAssets'
|
|
||||||
|
|
||||||
const props = withDefaults(
|
|
||||||
defineProps<{
|
|
||||||
plain?: boolean
|
|
||||||
boursecuLayout?: boolean
|
|
||||||
}>(),
|
|
||||||
{ plain: false, boursecuLayout: false }
|
|
||||||
)
|
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
openGoldModal: [metal: WalletMetalTotal, modalText?: string, modalTitle?: string, modalContent?: string]
|
openGoldModal: [metal: WalletMetalTotal, modalText?: string, modalTitle?: string, modalContent?: string]
|
||||||
openRialModal: []
|
openRialModal: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { assetsSummary } = useWalletAssets()
|
|
||||||
|
|
||||||
const rowClass = computed(() => (props.plain ? 'text-primary' : 'text-tertiary'))
|
|
||||||
const iconColor = computed(() => (props.plain ? 'primary' : 'tertiary'))
|
|
||||||
|
|
||||||
const rootClass = computed(() => {
|
|
||||||
if (props.boursecuLayout) {
|
|
||||||
return 'assets-section assets-section--boursecu rounded-lg px-3 py-3 mt-2'
|
|
||||||
}
|
|
||||||
if (props.plain) {
|
|
||||||
return 'py-2'
|
|
||||||
}
|
|
||||||
return 'bg-primary rounded-lg p-2 py-3 mt-2'
|
|
||||||
})
|
|
||||||
|
|
||||||
const meta = computed(() => assetsSummary.value?.meta)
|
|
||||||
const metalTotals = computed(() => assetsSummary.value?.metal_totals ?? [])
|
|
||||||
const primaryMetalTotal = computed(() => metalTotals.value[0])
|
|
||||||
const cashWallet = computed(() => assetsSummary.value?.cash_wallet ?? 0)
|
|
||||||
const inventoryCards = computed(() => assetsSummary.value?.inventory_cards ?? [])
|
|
||||||
const countBasedInventory = computed(() =>
|
|
||||||
(assetsSummary.value?.count_products ?? []).reduce((sum, item) => sum + Number(item.quantity ?? 0), 0)
|
|
||||||
)
|
|
||||||
function formatMetalTotal(metal: WalletMetalTotal) {
|
|
||||||
return `${formatWeightAmount(resolveSummaryMetalWeight(metal, inventoryCards.value))}${metal.unit}`
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
:class="containerClass"
|
:class="containerClass"
|
||||||
>
|
>
|
||||||
<template v-if="displayState !== 'open'">
|
<template v-if="displayState !== 'open'">
|
||||||
<div class="status-box" :class="isBoursecu ? 'status-box--boursecu' : 'status-box--default'">
|
<div class="status-box status-box--boursecu">
|
||||||
<div class="status-box__icon-wrap">
|
<div class="status-box__icon-wrap">
|
||||||
<Icon
|
<Icon
|
||||||
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
||||||
size="22"
|
size="22"
|
||||||
:color="isBoursecu ? '#ffffff' : '#64748b'"
|
color="#ffffff"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-box__title">{{ statusTitle }}</div>
|
<div class="status-box__title">{{ statusTitle }}</div>
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="price-label" :class="isBoursecu ? 'price-label--boursecu' : 'text-gray-600 text-[12px] ml-2 w-full text-center'">
|
<div class="price-label price-label--boursecu">
|
||||||
{{ priceLabel }}
|
قیمت لحظهای کاتد مس
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full items-center flex justify-center">
|
<div class="w-full items-center flex justify-center">
|
||||||
<div v-if="price" class="flex gap-1 text-xs items-center">
|
<div v-if="price" class="flex gap-1 text-xs items-center">
|
||||||
@@ -38,11 +38,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<Vue3Odometer
|
<Vue3Odometer
|
||||||
:value="displayGoldVal"
|
:value="displayGoldVal"
|
||||||
class="o-text !text-xl font-bold"
|
class="o-text !text-xl font-bold price-odometer--boursecu"
|
||||||
:class="isBoursecu ? 'price-odometer--boursecu' : ''"
|
|
||||||
style="direction: ltr"
|
style="direction: ltr"
|
||||||
/>
|
/>
|
||||||
<span :class="isBoursecu ? 'price-unit--boursecu' : ''">ریال</span>
|
<span class="price-unit--boursecu">ریال</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -52,9 +51,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
|
||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { getTradeBuyPrice, lastPrice, percentPriceChanged, price } from '@/utils/price'
|
import { getTradeBuyPrice, lastPrice, percentPriceChanged, price } from '@/utils/price'
|
||||||
import {
|
import {
|
||||||
NO_QUOTE_MESSAGE,
|
NO_QUOTE_MESSAGE,
|
||||||
@@ -65,13 +62,7 @@ import Vue3Odometer from 'vue3-odometer'
|
|||||||
import 'odometer/themes/odometer-theme-default.css'
|
import 'odometer/themes/odometer-theme-default.css'
|
||||||
import { formatSignedPercentChange } from '@/utils/usePrice'
|
import { formatSignedPercentChange } from '@/utils/usePrice'
|
||||||
|
|
||||||
const config = useConfigStore()
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
|
|
||||||
const priceLabel = computed(() =>
|
|
||||||
isBoursecu ? 'قیمت لحظهای کاتد مس' : `قیمت خرید از ${config.config.name_fa}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const displayState = computed(() => getPriceDisplayState())
|
const displayState = computed(() => getPriceDisplayState())
|
||||||
|
|
||||||
@@ -91,9 +82,6 @@ const statusHint = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const containerClass = computed(() => {
|
const containerClass = computed(() => {
|
||||||
if (!isBoursecu) {
|
|
||||||
return 'border-gray-200 border-1'
|
|
||||||
}
|
|
||||||
if (displayState.value !== 'open') {
|
if (displayState.value !== 'open') {
|
||||||
return 'boursecu-price-box boursecu-price-box--closed'
|
return 'boursecu-price-box boursecu-price-box--closed'
|
||||||
}
|
}
|
||||||
@@ -190,18 +178,6 @@ void price
|
|||||||
color: rgba(255, 255, 255, 0.78);
|
color: rgba(255, 255, 255, 0.78);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-box--default .status-box__icon-wrap {
|
|
||||||
background: #f1f5f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-box--default .status-box__title {
|
|
||||||
color: #334155;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-box--default .status-box__hint {
|
|
||||||
color: #64748b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.price-change-badge {
|
.price-change-badge {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import type { HomeQuickActionItem } from '../layouts/types'
|
import type { HomeQuickActionItem } from '../layouts/types'
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@@ -10,15 +9,12 @@ defineProps<{
|
|||||||
defineEmits<{
|
defineEmits<{
|
||||||
click: []
|
click: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="home-quick-action-box flex flex-col items-center justify-center gap-2 rounded-xl border-2 p-1 min-h-[96px] w-full"
|
class="home-quick-action-box home-quick-action-box--boursecu flex flex-col items-center justify-center gap-2 rounded-xl border-2 p-1 min-h-[96px] w-full"
|
||||||
:class="{ 'home-quick-action-box--boursecu': isBoursecu }"
|
|
||||||
@click="$emit('click')"
|
@click="$emit('click')"
|
||||||
>
|
>
|
||||||
<div class="flex h-12 w-12 shrink-0 items-center justify-center">
|
<div class="flex h-12 w-12 shrink-0 items-center justify-center">
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ const { width: chartWidth } = useElementSize(chartContainerRef)
|
|||||||
const seriesLength = computed(() => props.priceChartSeries?.[0]?.data?.length ?? 0)
|
const seriesLength = computed(() => props.priceChartSeries?.[0]?.data?.length ?? 0)
|
||||||
const amplifyKatodChart = computed(() =>
|
const amplifyKatodChart = computed(() =>
|
||||||
shouldAmplifyKatodMesChart({
|
shouldAmplifyKatodMesChart({
|
||||||
isBoursecu: props.layout === 'boursecu',
|
|
||||||
metalTypeSetting: settingsStore.metalTypeSettingValue,
|
metalTypeSetting: settingsStore.metalTypeSettingValue,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -141,7 +140,6 @@ const katodDayRange = computed(() => {
|
|||||||
return resolveMetalDayRangePrices({
|
return resolveMetalDayRangePrices({
|
||||||
price: price.value,
|
price: price.value,
|
||||||
metal: props.selectedMetal,
|
metal: props.selectedMetal,
|
||||||
isBoursecuLayout: true,
|
|
||||||
metalRatio: selectedMetalChartRatio.value,
|
metalRatio: selectedMetalChartRatio.value,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div
|
<div
|
||||||
class="w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in"
|
class="w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in"
|
||||||
:class="[
|
:class="[
|
||||||
isBoursecuLayout ? 'mt-8 pt-2' : 'mt-6',
|
'mt-8 pt-2',
|
||||||
variant === 'mobile' ? 'pb-20' : 'mt-0 pb-0',
|
variant === 'mobile' ? 'pb-20' : 'mt-0 pb-0',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { usePriceWithoutType } from '../../../../utils/usePrice'
|
import { usePriceWithoutType } from '../../../../utils/usePrice'
|
||||||
import { price } from '@/utils/price'
|
import { price } from '@/utils/price'
|
||||||
import { getHomeLayoutId } from '../layouts/registry'
|
|
||||||
import { resolveMetalDayRangePrices, usePriceChart } from '../composables/usePriceChart'
|
import { resolveMetalDayRangePrices, usePriceChart } from '../composables/usePriceChart'
|
||||||
|
|
||||||
withDefaults(
|
withDefaults(
|
||||||
@@ -47,13 +46,11 @@ withDefaults(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const { selectedChartMetal, selectedMetalChartRatio } = usePriceChart()
|
const { selectedChartMetal, selectedMetalChartRatio } = usePriceChart()
|
||||||
const isBoursecuLayout = computed(() => getHomeLayoutId() === 'boursecu')
|
|
||||||
|
|
||||||
const rangePrices = computed(() =>
|
const rangePrices = computed(() =>
|
||||||
resolveMetalDayRangePrices({
|
resolveMetalDayRangePrices({
|
||||||
price: price.value,
|
price: price.value,
|
||||||
metal: selectedChartMetal.value,
|
metal: selectedChartMetal.value,
|
||||||
isBoursecuLayout: isBoursecuLayout.value,
|
|
||||||
metalRatio: selectedMetalChartRatio.value,
|
metalRatio: selectedMetalChartRatio.value,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,20 +7,16 @@ import { useWalletAssets } from '@/composables/useWalletAssets'
|
|||||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
import type { WalletMetalTotal } from '@/models/walletAssets'
|
||||||
import {
|
import {
|
||||||
formatBoursecuMetalModalText,
|
formatBoursecuMetalModalText,
|
||||||
formatMetalAssetsInfoText,
|
|
||||||
formatRialAssetsInfoText,
|
formatRialAssetsInfoText,
|
||||||
resolveAssetsRialValue,
|
resolveAssetsRialValue,
|
||||||
} from '@/utils/productAssets'
|
} from '@/utils/productAssets'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
|
||||||
import { useSettingsStore } from '@/store/settingsStore'
|
import { useSettingsStore } from '@/store/settingsStore'
|
||||||
import { getTradeBuyPrice, lastPrice, stopLastPricePolling } from '@/utils/price'
|
import { getTradeBuyPrice, lastPrice, stopLastPricePolling } from '@/utils/price'
|
||||||
import { getStoreClosedMessage, isStoreClosed } from '@/utils/storeHours'
|
import { getStoreClosedMessage, isStoreClosed } from '@/utils/storeHours'
|
||||||
import { message, Modal } from 'ant-design-vue'
|
import { message, Modal } from 'ant-design-vue'
|
||||||
import { getReferralShareText, getReferralShareTitle, shareReferralText } from '@/utils/referralShare'
|
|
||||||
import { useBanners } from './useBanners'
|
import { useBanners } from './useBanners'
|
||||||
import { usePriceChart, type ChartMetalType } from './usePriceChart'
|
import { usePriceChart, type ChartMetalType } from './usePriceChart'
|
||||||
import type { HomeActionItem } from '../layouts/types'
|
import type { HomeActionItem } from '../layouts/types'
|
||||||
import { getHomeLayoutId } from '../layouts/registry'
|
|
||||||
import { initHomePageData, resetHomePageData, useHomePageLoading } from './useHomePageData'
|
import { initHomePageData, resetHomePageData, useHomePageLoading } from './useHomePageData'
|
||||||
import { ensureAuthenticatedRoute } from '@/app/setupRouter'
|
import { ensureAuthenticatedRoute } from '@/app/setupRouter'
|
||||||
import { resetWalletPageData } from '../../wallet/composables/useWalletPageData'
|
import { resetWalletPageData } from '../../wallet/composables/useWalletPageData'
|
||||||
@@ -30,7 +26,6 @@ import { resetProductsPageData } from '../../products/composables/useProductsPag
|
|||||||
|
|
||||||
export interface HomePageContext {
|
export interface HomePageContext {
|
||||||
homePageLoading: ReturnType<typeof useHomePageLoading>['homePageLoading']
|
homePageLoading: ReturnType<typeof useHomePageLoading>['homePageLoading']
|
||||||
isGaroosi: ReturnType<typeof computed<boolean>>
|
|
||||||
bannerEnabled: ReturnType<typeof computed<boolean>>
|
bannerEnabled: ReturnType<typeof computed<boolean>>
|
||||||
showClosedMessage: ReturnType<typeof computed<boolean>>
|
showClosedMessage: ReturnType<typeof computed<boolean>>
|
||||||
closedMessage: ReturnType<typeof computed>
|
closedMessage: ReturnType<typeof computed>
|
||||||
@@ -41,7 +36,6 @@ export interface HomePageContext {
|
|||||||
updateChartData: ReturnType<typeof usePriceChart>['updateChartData']
|
updateChartData: ReturnType<typeof usePriceChart>['updateChartData']
|
||||||
selectedChartMetal: ReturnType<typeof usePriceChart>['selectedChartMetal']
|
selectedChartMetal: ReturnType<typeof usePriceChart>['selectedChartMetal']
|
||||||
setChartMetal: (metal: ChartMetalType) => void
|
setChartMetal: (metal: ChartMetalType) => void
|
||||||
isBoursecuHomeLayout: ReturnType<typeof computed<boolean>>
|
|
||||||
handleBannerClick: (banner: { typeClick?: string; modalText?: string; link?: string }) => void
|
handleBannerClick: (banner: { typeClick?: string; modalText?: string; link?: string }) => void
|
||||||
openGoldModal: (
|
openGoldModal: (
|
||||||
metal: WalletMetalTotal,
|
metal: WalletMetalTotal,
|
||||||
@@ -57,7 +51,6 @@ export const HOME_PAGE_CONTEXT_KEY: InjectionKey<HomePageContext> = Symbol('home
|
|||||||
export function useHomePage() {
|
export function useHomePage() {
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const walletStore = useWalletStore()
|
const walletStore = useWalletStore()
|
||||||
const configStore = useConfigStore()
|
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
const { assetsSummary, clearWalletAssets } = useWalletAssets()
|
const { assetsSummary, clearWalletAssets } = useWalletAssets()
|
||||||
|
|
||||||
@@ -76,9 +69,7 @@ export function useHomePage() {
|
|||||||
selectedChartMetal,
|
selectedChartMetal,
|
||||||
setChartMetal,
|
setChartMetal,
|
||||||
} = usePriceChart()
|
} = usePriceChart()
|
||||||
const isBoursecuHomeLayout = computed(() => getHomeLayoutId() === 'boursecu')
|
|
||||||
|
|
||||||
const isGaroosi = computed(() => configStore.config?.name === 'garoosi')
|
|
||||||
const bannerEnabled = computed(() => settingsStore.isSettingTruthy('banner_enabled'))
|
const bannerEnabled = computed(() => settingsStore.isSettingTruthy('banner_enabled'))
|
||||||
const closedMessage = computed(() => userStore.getValueByKey('closed_message'))
|
const closedMessage = computed(() => userStore.getValueByKey('closed_message'))
|
||||||
const marketClosedText = computed(() => {
|
const marketClosedText = computed(() => {
|
||||||
@@ -100,7 +91,7 @@ export function useHomePage() {
|
|||||||
{
|
{
|
||||||
name: 'deposit',
|
name: 'deposit',
|
||||||
icon: 'vuesax-linear:card-add',
|
icon: 'vuesax-linear:card-add',
|
||||||
label: isGaroosi.value ? 'واریز و برداشت' : 'واریز نقدی',
|
label: 'واریز نقدی',
|
||||||
handler: () => router.push({ name: 'wallet', query: { state: 'deposit' } }),
|
handler: () => router.push({ name: 'wallet', query: { state: 'deposit' } }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -114,21 +105,11 @@ export function useHomePage() {
|
|||||||
{
|
{
|
||||||
name: 'assets',
|
name: 'assets',
|
||||||
icon: 'vuesax-linear:cup',
|
icon: 'vuesax-linear:cup',
|
||||||
label: isGaroosi.value ? 'دعوت از دوستان' : 'دارایی ها',
|
label: 'دارایی ها',
|
||||||
handler: () => (isGaroosi.value ? shareCode() : router.push({ name: 'fund' })),
|
handler: () => router.push({ name: 'fund' }),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
async function shareCode() {
|
|
||||||
const text = getReferralShareText({
|
|
||||||
userName: userStore.userInfo?.name,
|
|
||||||
projectName: configStore.config.name,
|
|
||||||
referralId: userStore.userInfo?.referral_id,
|
|
||||||
})
|
|
||||||
|
|
||||||
await shareReferralText(text, getReferralShareTitle(configStore.config.name))
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyCode() {
|
function copyCode() {
|
||||||
const code = userStore.userInfo?.referral_id
|
const code = userStore.userInfo?.referral_id
|
||||||
if (code) {
|
if (code) {
|
||||||
@@ -178,9 +159,7 @@ export function useHomePage() {
|
|||||||
const title =
|
const title =
|
||||||
modalTitle ??
|
modalTitle ??
|
||||||
modalText ??
|
modalText ??
|
||||||
(isBoursecuHomeLayout.value
|
formatBoursecuMetalModalText(metal)
|
||||||
? formatBoursecuMetalModalText(metal)
|
|
||||||
: formatMetalAssetsInfoText(metal))
|
|
||||||
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title,
|
title,
|
||||||
@@ -230,7 +209,6 @@ export function useHomePage() {
|
|||||||
|
|
||||||
const context: HomePageContext = {
|
const context: HomePageContext = {
|
||||||
homePageLoading,
|
homePageLoading,
|
||||||
isGaroosi,
|
|
||||||
bannerEnabled,
|
bannerEnabled,
|
||||||
showClosedMessage,
|
showClosedMessage,
|
||||||
closedMessage: marketClosedText,
|
closedMessage: marketClosedText,
|
||||||
@@ -241,7 +219,6 @@ export function useHomePage() {
|
|||||||
updateChartData,
|
updateChartData,
|
||||||
selectedChartMetal,
|
selectedChartMetal,
|
||||||
setChartMetal,
|
setChartMetal,
|
||||||
isBoursecuHomeLayout,
|
|
||||||
handleBannerClick,
|
handleBannerClick,
|
||||||
openGoldModal,
|
openGoldModal,
|
||||||
openRialModal,
|
openRialModal,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { ref } from 'vue'
|
|||||||
import { getLastPrices, startLastPricePolling, stopLastPricePolling } from '@/utils/price'
|
import { getLastPrices, startLastPricePolling, stopLastPricePolling } from '@/utils/price'
|
||||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||||
import { clearProductsCatalog } from '@/composables/useProductsCatalog'
|
import { clearProductsCatalog } from '@/composables/useProductsCatalog'
|
||||||
import { getHomeLayoutId } from '../layouts/registry'
|
|
||||||
import { fetchHomeChartPrices, loadHomeMaftolOffset, resetHomePriceChart } from './usePriceChart'
|
import { fetchHomeChartPrices, loadHomeMaftolOffset, resetHomePriceChart } from './usePriceChart'
|
||||||
import { loadHomeBanners, resetHomeBanners } from './useBanners'
|
import { loadHomeBanners, resetHomeBanners } from './useBanners'
|
||||||
import { loadHomeFunds, resetHomeFunds } from './useUserFunds'
|
import { loadHomeFunds, resetHomeFunds } from './useUserFunds'
|
||||||
@@ -24,10 +23,7 @@ export function isHomePageDataInitialized() {
|
|||||||
export async function initHomePageData(force = false) {
|
export async function initHomePageData(force = false) {
|
||||||
if (!force && initialized.value) {
|
if (!force && initialized.value) {
|
||||||
startLastPricePolling()
|
startLastPricePolling()
|
||||||
|
void loadHomeMaftolOffset(false)
|
||||||
if (getHomeLayoutId() === 'boursecu') {
|
|
||||||
void loadHomeMaftolOffset(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -49,9 +45,7 @@ export async function initHomePageData(force = false) {
|
|||||||
loadHomeBanners(force),
|
loadHomeBanners(force),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (getHomeLayoutId() === 'boursecu') {
|
await loadHomeMaftolOffset(force)
|
||||||
await loadHomeMaftolOffset(force)
|
|
||||||
}
|
|
||||||
|
|
||||||
initialized.value = true
|
initialized.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { computed, ref, watch } from 'vue'
|
|||||||
import { getAllPrices } from '@/api/home'
|
import { getAllPrices } from '@/api/home'
|
||||||
import type { Product } from '@/models/products'
|
import type { Product } from '@/models/products'
|
||||||
import { getProductsCatalog, getProductsCatalogRef } from '@/composables/useProductsCatalog'
|
import { getProductsCatalog, getProductsCatalogRef } from '@/composables/useProductsCatalog'
|
||||||
import { getHomeLayoutId } from '../layouts/registry'
|
|
||||||
import { getProductBuyPrice, resolvePriceOffsetRatio } from '@/utils/productPrice'
|
import { getProductBuyPrice, resolvePriceOffsetRatio } from '@/utils/productPrice'
|
||||||
import { isKatodMesGroup, isMaftolMesGroup, isShamshMesGroup } from '@/utils/productDealMethod'
|
import { isKatodMesGroup, isMaftolMesGroup, isShamshMesGroup } from '@/utils/productDealMethod'
|
||||||
import { getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@/utils/price'
|
import { getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@/utils/price'
|
||||||
@@ -31,10 +30,6 @@ function resolveChartProducts(products: Product[]) {
|
|||||||
|
|
||||||
/** نسبت مفتول به کاتد — reactive به قیمت لحظهای و کاتالوگ محصولات */
|
/** نسبت مفتول به کاتد — reactive به قیمت لحظهای و کاتالوگ محصولات */
|
||||||
const maftolChartRatio = computed(() => {
|
const maftolChartRatio = computed(() => {
|
||||||
if (getHomeLayoutId() !== 'boursecu') {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
void lastPrice.value?.price_last
|
void lastPrice.value?.price_last
|
||||||
|
|
||||||
const { katod, maftol } = resolveChartProducts(catalogProducts.value)
|
const { katod, maftol } = resolveChartProducts(catalogProducts.value)
|
||||||
@@ -43,10 +38,6 @@ const maftolChartRatio = computed(() => {
|
|||||||
|
|
||||||
/** نسبت شمش مس به کاتد */
|
/** نسبت شمش مس به کاتد */
|
||||||
const shamshChartRatio = computed(() => {
|
const shamshChartRatio = computed(() => {
|
||||||
if (getHomeLayoutId() !== 'boursecu') {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
void lastPrice.value?.price_last
|
void lastPrice.value?.price_last
|
||||||
|
|
||||||
const { katod, shamsh } = resolveChartProducts(catalogProducts.value)
|
const { katod, shamsh } = resolveChartProducts(catalogProducts.value)
|
||||||
@@ -100,13 +91,12 @@ function applyChartRatio(basePrice: number, ratio: number) {
|
|||||||
export function resolveMetalDayRangePrices(options: {
|
export function resolveMetalDayRangePrices(options: {
|
||||||
price: { up?: { buy?: number; sell?: number }; buy?: number; sell?: number; price_last?: number } | null | undefined
|
price: { up?: { buy?: number; sell?: number }; buy?: number; sell?: number; price_last?: number } | null | undefined
|
||||||
metal: ChartMetalType
|
metal: ChartMetalType
|
||||||
isBoursecuLayout: boolean
|
|
||||||
metalRatio: number
|
metalRatio: number
|
||||||
}) {
|
}) {
|
||||||
const baseHigh = options.price?.up?.buy ?? getTradeBuyPrice(options.price as Parameters<typeof getTradeBuyPrice>[0])
|
const baseHigh = options.price?.up?.buy ?? getTradeBuyPrice(options.price as Parameters<typeof getTradeBuyPrice>[0])
|
||||||
const baseLow = options.price?.up?.sell ?? getTradeSellPrice(options.price as Parameters<typeof getTradeSellPrice>[0])
|
const baseLow = options.price?.up?.sell ?? getTradeSellPrice(options.price as Parameters<typeof getTradeSellPrice>[0])
|
||||||
|
|
||||||
if (!options.isBoursecuLayout || options.metal === 'katod') {
|
if (options.metal === 'katod') {
|
||||||
return { high: baseHigh, low: baseLow }
|
return { high: baseHigh, low: baseLow }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +166,7 @@ function buildChartPoints(items: Array<{ timestamp: number; value: number }>): C
|
|||||||
function syncChartSeries() {
|
function syncChartSeries() {
|
||||||
const ratio = selectedMetalChartRatio.value
|
const ratio = selectedMetalChartRatio.value
|
||||||
const data =
|
const data =
|
||||||
getHomeLayoutId() === 'boursecu' && selectedChartMetal.value !== 'katod'
|
selectedChartMetal.value !== 'katod'
|
||||||
? rawChartPoints.value.map(
|
? rawChartPoints.value.map(
|
||||||
([timestamp, value]) =>
|
([timestamp, value]) =>
|
||||||
[timestamp, applyChartRatio(value, ratio)] as ChartPoint
|
[timestamp, applyChartRatio(value, ratio)] as ChartPoint
|
||||||
@@ -221,11 +211,6 @@ async function fetchPrices(force = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function loadMetalChartOffsets(force = false) {
|
async function loadMetalChartOffsets(force = false) {
|
||||||
if (getHomeLayoutId() !== 'boursecu') {
|
|
||||||
syncChartSeries()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!force && metalOffsetLoaded && catalogProducts.value.length > 0) {
|
if (!force && metalOffsetLoaded && catalogProducts.value.length > 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -258,7 +243,7 @@ function updateChartData(timeline: string) {
|
|||||||
function setChartMetal(metal: ChartMetalType) {
|
function setChartMetal(metal: ChartMetalType) {
|
||||||
selectedChartMetal.value = metal
|
selectedChartMetal.value = metal
|
||||||
|
|
||||||
if (metal !== 'katod' && getHomeLayoutId() === 'boursecu' && !catalogProducts.value.length) {
|
if (metal !== 'katod' && !catalogProducts.value.length) {
|
||||||
void loadMetalChartOffsets(true)
|
void loadMetalChartOffsets(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<BoursecuDesktopHome v-if="layoutId === 'boursecu'" @logout="$emit('logout')" />
|
<BoursecuDesktopHome @logout="$emit('logout')" />
|
||||||
<DefaultDesktopHome v-else @logout="$emit('logout')" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
|
||||||
import { getHomeLayoutId } from '../layouts/registry'
|
|
||||||
import BoursecuDesktopHome from './layouts/BoursecuDesktopHome.vue'
|
import BoursecuDesktopHome from './layouts/BoursecuDesktopHome.vue'
|
||||||
import DefaultDesktopHome from './layouts/DefaultDesktopHome.vue'
|
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
logout: []
|
logout: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const layoutId = computed(() => getHomeLayoutId())
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ defineEmits<{
|
|||||||
<DesktopHomeCard title="داراییهای من">
|
<DesktopHomeCard title="داراییهای من">
|
||||||
<AssetsSection
|
<AssetsSection
|
||||||
plain
|
plain
|
||||||
|
boursecu-layout
|
||||||
class="home-desktop-assets"
|
class="home-desktop-assets"
|
||||||
@open-gold-modal="$emit('openGoldModal', $event)"
|
@open-gold-modal="$emit('openGoldModal', $event)"
|
||||||
@open-rial-modal="$emit('openRialModal')"
|
@open-rial-modal="$emit('openRialModal')"
|
||||||
|
|||||||
@@ -1,126 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
|
||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
|
||||||
import BoursecuAssetsSummary from '../../components/BoursecuAssetsSummary.vue'
|
import BoursecuAssetsSummary from '../../components/BoursecuAssetsSummary.vue'
|
||||||
import PortfolioProfitInsight from '../../components/PortfolioProfitInsight.vue'
|
|
||||||
import { formatWeightAmount, usePriceWithoutType } from '@/utils/usePrice'
|
|
||||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
|
||||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
|
||||||
import { resolveSummaryMetalWeight } from '@/utils/productAssets'
|
|
||||||
import { useHomePageContext } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
openGoldModal: [metal: WalletMetalTotal, modalText?: string, modalTitle?: string, modalContent?: string]
|
|
||||||
openRialModal: []
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const { assetsSummary } = useWalletAssets()
|
|
||||||
const ctx = useHomePageContext()
|
|
||||||
const isBoursecuLayout = computed(() => ctx.isBoursecuHomeLayout.value)
|
|
||||||
|
|
||||||
const meta = computed(() => assetsSummary.value?.meta)
|
|
||||||
const metalTotals = computed(() => assetsSummary.value?.metal_totals ?? [])
|
|
||||||
const inventoryCards = computed(() => assetsSummary.value?.inventory_cards ?? [])
|
|
||||||
const cashWallet = computed(() => assetsSummary.value?.cash_wallet ?? 0)
|
|
||||||
const countBasedInventory = computed(() =>
|
|
||||||
(assetsSummary.value?.count_products ?? []).reduce((sum, item) => sum + Number(item.quantity ?? 0), 0),
|
|
||||||
)
|
|
||||||
|
|
||||||
type MetricItem = {
|
|
||||||
id: string
|
|
||||||
label: string
|
|
||||||
value: string
|
|
||||||
metal?: WalletMetalTotal
|
|
||||||
showInfo?: boolean
|
|
||||||
onInfo?: 'gold' | 'rial'
|
|
||||||
}
|
|
||||||
|
|
||||||
const metrics = computed<MetricItem[]>(() => {
|
|
||||||
const items: MetricItem[] = []
|
|
||||||
|
|
||||||
if (meta.value?.has_count_based_products) {
|
|
||||||
items.push({
|
|
||||||
id: 'products',
|
|
||||||
label: 'محصولات',
|
|
||||||
value: `${usePriceWithoutType(countBasedInventory.value, false)} عدد`,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta.value?.single_metal && metalTotals.value[0]) {
|
|
||||||
const metal = metalTotals.value[0]
|
|
||||||
items.push({
|
|
||||||
id: `metal-${metal.metal_id}`,
|
|
||||||
label: metal.label,
|
|
||||||
value: formatMetalTotal(metal),
|
|
||||||
metal,
|
|
||||||
showInfo: true,
|
|
||||||
onInfo: 'gold',
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
metalTotals.value.forEach((metal, index) => {
|
|
||||||
items.push({
|
|
||||||
id: `metal-${metal.metal_id}`,
|
|
||||||
label: metal.label,
|
|
||||||
value: formatMetalTotal(metal),
|
|
||||||
metal,
|
|
||||||
showInfo: index === 0,
|
|
||||||
onInfo: 'gold',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
items.push({
|
|
||||||
id: 'rial',
|
|
||||||
label: 'دارایی ریالی',
|
|
||||||
value: `${usePriceWithoutType(cashWallet.value)} ریال`,
|
|
||||||
showInfo: true,
|
|
||||||
onInfo: 'rial',
|
|
||||||
})
|
|
||||||
|
|
||||||
return items
|
|
||||||
})
|
|
||||||
|
|
||||||
function formatMetalTotal(metal: WalletMetalTotal) {
|
|
||||||
return `${formatWeightAmount(resolveSummaryMetalWeight(metal, inventoryCards.value))}${metal.unit}`
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInfo(metric: MetricItem) {
|
|
||||||
if (metric.onInfo === 'rial') {
|
|
||||||
emit('openRialModal')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (metric.metal) {
|
|
||||||
emit('openGoldModal', metric.metal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BoursecuAssetsSummary
|
<BoursecuAssetsSummary
|
||||||
v-if="isBoursecuLayout"
|
|
||||||
variant="desktop"
|
variant="desktop"
|
||||||
icon-color="tertiary"
|
icon-color="tertiary"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-else>
|
|
||||||
<PortfolioProfitInsight variant="desktop" />
|
|
||||||
|
|
||||||
<div class="dhome-metrics">
|
|
||||||
<article v-for="metric in metrics" :key="metric.id" class="dhome-metric-tile">
|
|
||||||
<div class="dhome-metric-tile__head">
|
|
||||||
<span class="dhome-metric-tile__label">{{ metric.label }}</span>
|
|
||||||
<button
|
|
||||||
v-if="metric.showInfo"
|
|
||||||
type="button"
|
|
||||||
class="dhome-metric-tile__info"
|
|
||||||
aria-label="اطلاعات بیشتر"
|
|
||||||
@click="handleInfo(metric)"
|
|
||||||
>
|
|
||||||
<BasicIcon icon="vuesax-linear:info-circle" size="14" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p class="dhome-metric-tile__value">{{ metric.value }}</p>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import DesktopHomeCard from '../components/DesktopHomeCard.vue'
|
|||||||
|
|
||||||
const ctx = useHomePageContext()
|
const ctx = useHomePageContext()
|
||||||
|
|
||||||
const chartLayout = computed(() => (toValue(ctx.isBoursecuHomeLayout) ? 'boursecu' : 'default'))
|
const chartLayout = 'boursecu' as const
|
||||||
const priceChartSeries = computed(() => toValue(ctx.priceChartSeries))
|
const priceChartSeries = computed(() => toValue(ctx.priceChartSeries))
|
||||||
const chartSelection = computed(() => toValue(ctx.chartSelection))
|
const chartSelection = computed(() => toValue(ctx.chartSelection))
|
||||||
const selectedChartMetal = computed(() => toValue(ctx.selectedChartMetal))
|
const selectedChartMetal = computed(() => toValue(ctx.selectedChartMetal))
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const props = withDefaults(
|
|||||||
|
|
||||||
const ctx = useHomePageContext()
|
const ctx = useHomePageContext()
|
||||||
|
|
||||||
const chartLayout = computed(() => (toValue(ctx.isBoursecuHomeLayout) ? 'boursecu' : 'default'))
|
const chartLayout = 'boursecu' as const
|
||||||
const priceChartSeries = computed(() => toValue(ctx.priceChartSeries))
|
const priceChartSeries = computed(() => toValue(ctx.priceChartSeries))
|
||||||
const chartSelection = computed(() => toValue(ctx.chartSelection))
|
const chartSelection = computed(() => toValue(ctx.chartSelection))
|
||||||
const selectedChartMetal = computed(() => toValue(ctx.selectedChartMetal))
|
const selectedChartMetal = computed(() => toValue(ctx.selectedChartMetal))
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import { useUserStore } from '@/store/userStore'
|
|
||||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
|
||||||
import DesktopHomeSection from './DesktopHomeSection.vue'
|
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
|
||||||
const userStore = useUserStore()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<DesktopHomeSection v-if="ctx.isGaroosi.value" title="داراییها">
|
|
||||||
<div class="dhome-garoosi-assets">
|
|
||||||
<div class="dhome-garoosi-assets__item">
|
|
||||||
<span class="dhome-garoosi-assets__label">دارایی طلایی</span>
|
|
||||||
<span class="dhome-garoosi-assets__value">
|
|
||||||
{{ (userStore?.userInfo?.wallet?.count_gold ?? 0).toFixed(3) }} گرم
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="dhome-garoosi-assets__divider" />
|
|
||||||
<div class="dhome-garoosi-assets__item">
|
|
||||||
<span class="dhome-garoosi-assets__label">دارایی ریالی</span>
|
|
||||||
<span class="dhome-garoosi-assets__value">
|
|
||||||
{{ usePriceWithoutType(userStore?.userInfo?.wallet?.count_cash ?? 0) }} ریال
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DesktopHomeSection>
|
|
||||||
</template>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div v-if="!isBoursecu && ctx.showClosedMessage.value" class="dhome-alerts">
|
|
||||||
<div
|
|
||||||
class="dhome-alert dhome-alert--info"
|
|
||||||
v-html="ctx.closedMessage.value"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,15 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dhome" :class="{ 'dhome--boursecu': isBoursecu }">
|
<div class="dhome dhome--boursecu">
|
||||||
<div class="dhome__container">
|
<div class="dhome__container">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
|
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" src="../styles/desktop-home.less"></style>
|
<style lang="less" src="../styles/desktop-home.less"></style>
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
<div
|
<div
|
||||||
class="dhome-surface dhome-hero-price"
|
class="dhome-surface dhome-hero-price"
|
||||||
:class="{
|
:class="{
|
||||||
'dhome-hero-price--boursecu-open': isBoursecu && displayState === 'open',
|
'dhome-hero-price--boursecu-open': displayState === 'open',
|
||||||
'dhome-hero-price--boursecu-closed': isBoursecu && displayState !== 'open',
|
'dhome-hero-price--boursecu-closed': displayState !== 'open',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template v-if="displayState !== 'open'">
|
<template v-if="displayState !== 'open'">
|
||||||
<div class="dhome-hero-price__closed" :class="{ 'dhome-hero-price__closed--default': !isBoursecu }">
|
<div class="dhome-hero-price__closed">
|
||||||
<div class="dhome-hero-price__closed-icon">
|
<div class="dhome-hero-price__closed-icon">
|
||||||
<BasicIcon
|
<BasicIcon
|
||||||
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
||||||
size="22"
|
size="22"
|
||||||
:color="isBoursecu ? '#ffffff' : '#64748b'"
|
color="#ffffff"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p class="dhome-hero-price__closed-title">{{ statusTitle }}</p>
|
<p class="dhome-hero-price__closed-title">{{ statusTitle }}</p>
|
||||||
@@ -21,10 +21,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<span class="dhome-label" :class="{ 'dhome-label--boursecu': isBoursecu }">
|
<span class="dhome-label dhome-label--boursecu">
|
||||||
{{ isBoursecu ? 'قیمت لحظهای کاتد مس' : 'قیمت لحظهای' }}
|
قیمت لحظهای کاتد مس
|
||||||
</span>
|
</span>
|
||||||
<p v-if="!isBoursecu" class="dhome-hero-price__brand">{{ config.config?.name_fa }}</p>
|
|
||||||
<div class="dhome-hero-price__value-row">
|
<div class="dhome-hero-price__value-row">
|
||||||
<span
|
<span
|
||||||
v-if="percentChange !== 0"
|
v-if="percentChange !== 0"
|
||||||
@@ -39,10 +38,9 @@
|
|||||||
</span>
|
</span>
|
||||||
<Vue3Odometer
|
<Vue3Odometer
|
||||||
:value="displayGoldVal"
|
:value="displayGoldVal"
|
||||||
class="dhome-hero-price__odometer o-text"
|
class="dhome-hero-price__odometer o-text dhome-hero-price__odometer--boursecu"
|
||||||
:class="{ 'dhome-hero-price__odometer--boursecu': isBoursecu }"
|
|
||||||
/>
|
/>
|
||||||
<span class="dhome-hero-price__unit" :class="{ 'dhome-hero-price__unit--boursecu': isBoursecu }">ریال</span>
|
<span class="dhome-hero-price__unit dhome-hero-price__unit--boursecu">ریال</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,9 +51,7 @@ import { computed } from 'vue'
|
|||||||
import Vue3Odometer from 'vue3-odometer'
|
import Vue3Odometer from 'vue3-odometer'
|
||||||
import 'odometer/themes/odometer-theme-default.css'
|
import 'odometer/themes/odometer-theme-default.css'
|
||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
|
||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { getTradeBuyPrice, lastPrice, percentPriceChanged } from '@/utils/price'
|
import { getTradeBuyPrice, lastPrice, percentPriceChanged } from '@/utils/price'
|
||||||
import {
|
import {
|
||||||
NO_QUOTE_MESSAGE,
|
NO_QUOTE_MESSAGE,
|
||||||
@@ -64,9 +60,7 @@ import {
|
|||||||
} from '@/utils/storeHours'
|
} from '@/utils/storeHours'
|
||||||
import { formatSignedPercentChange } from '@/utils/usePrice'
|
import { formatSignedPercentChange } from '@/utils/usePrice'
|
||||||
|
|
||||||
const config = useConfigStore()
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
|
|
||||||
const displayState = computed(() => getPriceDisplayState())
|
const displayState = computed(() => getPriceDisplayState())
|
||||||
|
|
||||||
@@ -152,18 +146,4 @@ const percentChange = computed(() => {
|
|||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
color: rgba(255, 255, 255, 0.78);
|
color: rgba(255, 255, 255, 0.78);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dhome-hero-price__closed--default {
|
|
||||||
.dhome-hero-price__closed-icon {
|
|
||||||
background: #f1f5f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhome-hero-price__closed-title {
|
|
||||||
color: #334155;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhome-hero-price__closed-hint {
|
|
||||||
color: #64748b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,17 +2,14 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { price } from '@/utils/price'
|
import { price } from '@/utils/price'
|
||||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
import { usePriceWithoutType } from '@/utils/usePrice'
|
||||||
import { getHomeLayoutId } from '../../layouts/registry'
|
|
||||||
import { resolveMetalDayRangePrices, usePriceChart } from '../../composables/usePriceChart'
|
import { resolveMetalDayRangePrices, usePriceChart } from '../../composables/usePriceChart'
|
||||||
|
|
||||||
const { selectedChartMetal, selectedMetalChartRatio } = usePriceChart()
|
const { selectedChartMetal, selectedMetalChartRatio } = usePriceChart()
|
||||||
const isBoursecuLayout = computed(() => getHomeLayoutId() === 'boursecu')
|
|
||||||
|
|
||||||
const rangePrices = computed(() =>
|
const rangePrices = computed(() =>
|
||||||
resolveMetalDayRangePrices({
|
resolveMetalDayRangePrices({
|
||||||
price: price.value,
|
price: price.value,
|
||||||
metal: selectedChartMetal.value,
|
metal: selectedChartMetal.value,
|
||||||
isBoursecuLayout: isBoursecuLayout.value,
|
|
||||||
metalRatio: selectedMetalChartRatio.value,
|
metalRatio: selectedMetalChartRatio.value,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import DesktopHomeSection from './DesktopHomeSection.vue'
|
|
||||||
import ReferralSection from '../../components/ReferralSection.vue'
|
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<DesktopHomeSection v-if="ctx.isGaroosi.value" title="دعوت از دوستان">
|
|
||||||
<ReferralSection />
|
|
||||||
</DesktopHomeSection>
|
|
||||||
</template>
|
|
||||||
@@ -7,7 +7,6 @@ import { useHomePageContext } from '../../composables/useHomePage'
|
|||||||
import HomeSkeleton from '../../components/HomeSkeleton.vue'
|
import HomeSkeleton from '../../components/HomeSkeleton.vue'
|
||||||
import DesktopHomeShell from '../components/DesktopHomeShell.vue'
|
import DesktopHomeShell from '../components/DesktopHomeShell.vue'
|
||||||
import DesktopHomeTopbar from '../components/DesktopHomeTopbar.vue'
|
import DesktopHomeTopbar from '../components/DesktopHomeTopbar.vue'
|
||||||
import DesktopHomeAlerts from '../components/DesktopHomeAlerts.vue'
|
|
||||||
import DesktopLivePrice from '../components/DesktopLivePrice.vue'
|
import DesktopLivePrice from '../components/DesktopLivePrice.vue'
|
||||||
import DesktopPriceRange from '../components/DesktopPriceRange.vue'
|
import DesktopPriceRange from '../components/DesktopPriceRange.vue'
|
||||||
import DesktopAssetsMetrics from '../components/DesktopAssetsMetrics.vue'
|
import DesktopAssetsMetrics from '../components/DesktopAssetsMetrics.vue'
|
||||||
@@ -29,7 +28,6 @@ const showSkeleton = computed(() => Boolean(getToken()) && !userInfo.value)
|
|||||||
<template>
|
<template>
|
||||||
<DesktopHomeShell>
|
<DesktopHomeShell>
|
||||||
<DesktopHomeTopbar @logout="$emit('logout')" />
|
<DesktopHomeTopbar @logout="$emit('logout')" />
|
||||||
<DesktopHomeAlerts />
|
|
||||||
|
|
||||||
<HomeSkeleton v-if="showSkeleton" />
|
<HomeSkeleton v-if="showSkeleton" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue'
|
|
||||||
import { storeToRefs } from 'pinia'
|
|
||||||
import { useUserStore } from '@/store/userStore'
|
|
||||||
import { getToken } from '@/utils'
|
|
||||||
import { useHomePageContext } from '../../composables/useHomePage'
|
|
||||||
import HomeSkeleton from '../../components/HomeSkeleton.vue'
|
|
||||||
import DesktopHomeShell from '../components/DesktopHomeShell.vue'
|
|
||||||
import DesktopHomeTopbar from '../components/DesktopHomeTopbar.vue'
|
|
||||||
import DesktopHomeAlerts from '../components/DesktopHomeAlerts.vue'
|
|
||||||
import DesktopLivePrice from '../components/DesktopLivePrice.vue'
|
|
||||||
import DesktopPriceRange from '../components/DesktopPriceRange.vue'
|
|
||||||
import DesktopAssetsMetrics from '../components/DesktopAssetsMetrics.vue'
|
|
||||||
import DesktopChartSection from '../components/DesktopChartSection.vue'
|
|
||||||
import DesktopDefaultActions from '../components/DesktopDefaultActions.vue'
|
|
||||||
import DesktopGaroosiAssets from '../components/DesktopGaroosiAssets.vue'
|
|
||||||
import DesktopReferralPanel from '../components/DesktopReferralPanel.vue'
|
|
||||||
import DesktopBannersPanel from '../components/DesktopBannersPanel.vue'
|
|
||||||
|
|
||||||
defineEmits<{
|
|
||||||
logout: []
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const { userInfo } = storeToRefs(userStore)
|
|
||||||
const ctx = useHomePageContext()
|
|
||||||
|
|
||||||
const showContent = computed(() => Boolean(userInfo.value))
|
|
||||||
const showSkeleton = computed(() => Boolean(getToken()) && !userInfo.value)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<DesktopHomeShell>
|
|
||||||
<DesktopHomeTopbar @logout="$emit('logout')" />
|
|
||||||
<DesktopHomeAlerts />
|
|
||||||
|
|
||||||
<HomeSkeleton v-if="showSkeleton" />
|
|
||||||
|
|
||||||
<template v-if="showContent">
|
|
||||||
<section v-if="ctx.isGaroosi.value" class="dhome-hero-row">
|
|
||||||
<DesktopLivePrice />
|
|
||||||
<DesktopPriceRange />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div v-if="ctx.isGaroosi.value" class="dhome-default-grid">
|
|
||||||
<div class="dhome-default-grid__main">
|
|
||||||
<DesktopDefaultActions />
|
|
||||||
<section
|
|
||||||
v-if="ctx.bannerEnabled.value && ctx.banners.value?.length"
|
|
||||||
class="dhome-surface dhome-chart-banner-combined"
|
|
||||||
>
|
|
||||||
<header class="dhome-section__header">
|
|
||||||
<h2 class="dhome-section__title">نمودار قیمت</h2>
|
|
||||||
</header>
|
|
||||||
<div class="dhome-chart-banner-combined__grid">
|
|
||||||
<DesktopChartSection embedded />
|
|
||||||
<DesktopBannersPanel embedded />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<DesktopChartSection v-else />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<aside class="dhome-default-grid__side">
|
|
||||||
<DesktopGaroosiAssets />
|
|
||||||
<DesktopReferralPanel />
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-else>
|
|
||||||
<DesktopDefaultActions />
|
|
||||||
|
|
||||||
<DesktopAssetsMetrics
|
|
||||||
@open-gold-modal="ctx.openGoldModal"
|
|
||||||
@open-rial-modal="ctx.openRialModal"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<section class="dhome-hero-row">
|
|
||||||
<DesktopLivePrice />
|
|
||||||
<DesktopPriceRange />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section
|
|
||||||
v-if="ctx.bannerEnabled.value && ctx.banners.value?.length"
|
|
||||||
class="dhome-surface dhome-chart-banner-combined"
|
|
||||||
>
|
|
||||||
<header class="dhome-section__header">
|
|
||||||
<h2 class="dhome-section__title">نمودار قیمت</h2>
|
|
||||||
</header>
|
|
||||||
<div class="dhome-chart-banner-combined__grid">
|
|
||||||
<DesktopChartSection embedded />
|
|
||||||
<DesktopBannersPanel embedded />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<DesktopChartSection v-else />
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</DesktopHomeShell>
|
|
||||||
</template>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,5 @@
|
|||||||
import type { HomeLayoutConfig } from '../types'
|
import type { HomeLayoutConfig } from '../types'
|
||||||
|
|
||||||
/**
|
|
||||||
* چیدمان اختصاصی boursecu — فقط وقتی home_layout=boursecu یا پروژه boursecu باشد.
|
|
||||||
* شامل: دارایی بدون بکگراند، گرید ۶ باکس، نمودار کاتد/مفتول، و ...
|
|
||||||
*/
|
|
||||||
export const boursecuHomeLayoutConfig: HomeLayoutConfig = {
|
export const boursecuHomeLayoutConfig: HomeLayoutConfig = {
|
||||||
id: 'boursecu',
|
id: 'boursecu',
|
||||||
wrapperClass: 'rounded-lg mt-5',
|
wrapperClass: 'rounded-lg mt-5',
|
||||||
@@ -13,7 +9,6 @@ export const boursecuHomeLayoutConfig: HomeLayoutConfig = {
|
|||||||
{ id: 'boursecuQuickActions' },
|
{ id: 'boursecuQuickActions' },
|
||||||
],
|
],
|
||||||
sections: [
|
sections: [
|
||||||
{ id: 'marketClosed' },
|
|
||||||
{ id: 'priceChart' },
|
{ id: 'priceChart' },
|
||||||
{ id: 'priceStats' },
|
{ id: 'priceStats' },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import type { HomeLayoutConfig } from '../types'
|
|
||||||
|
|
||||||
/** چیدمان پیشفرض — همه پروژهها بهجز boursecu */
|
|
||||||
export const defaultHomeLayoutConfig: HomeLayoutConfig = {
|
|
||||||
id: 'default',
|
|
||||||
wrapperClass: 'p-1 shadow-lg from-primary rounded-lg p-px to-transparent mt-5',
|
|
||||||
sections: [
|
|
||||||
{ id: 'garoosiAssets' },
|
|
||||||
{ id: 'mainActions' },
|
|
||||||
{ id: 'referral' },
|
|
||||||
{ id: 'assets' },
|
|
||||||
],
|
|
||||||
tailSections: [
|
|
||||||
{ id: 'marketClosed' },
|
|
||||||
{ id: 'currentPrice' },
|
|
||||||
{ id: 'banners' },
|
|
||||||
{ id: 'priceChart' },
|
|
||||||
{ id: 'priceStats' },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
import { defineAsyncComponent, type Component } from 'vue'
|
import { defineAsyncComponent, type Component } from 'vue'
|
||||||
import { getConfigApp, isBoursecuProject } from '@/utils/config'
|
|
||||||
import type { HomeLayoutConfig, HomeLayoutId } from './types'
|
import type { HomeLayoutConfig, HomeLayoutId } from './types'
|
||||||
import { defaultHomeLayoutConfig } from './configs/default'
|
|
||||||
import { boursecuHomeLayoutConfig } from './configs/boursecu'
|
import { boursecuHomeLayoutConfig } from './configs/boursecu'
|
||||||
|
|
||||||
export const DEFAULT_HOME_LAYOUT_ID: HomeLayoutId = 'default'
|
export const DEFAULT_HOME_LAYOUT_ID: HomeLayoutId = 'boursecu'
|
||||||
|
|
||||||
const HOME_LAYOUT_CONFIGS: Record<HomeLayoutId, HomeLayoutConfig> = {
|
const HOME_LAYOUT_CONFIGS: Record<HomeLayoutId, HomeLayoutConfig> = {
|
||||||
default: defaultHomeLayoutConfig,
|
|
||||||
boursecu: boursecuHomeLayoutConfig,
|
boursecu: boursecuHomeLayoutConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,20 +23,11 @@ export function isHomeLayoutId(value: unknown): value is HomeLayoutId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getHomeLayoutId(): HomeLayoutId {
|
export function getHomeLayoutId(): HomeLayoutId {
|
||||||
const adminLayout = getConfigApp('home_layout')
|
return 'boursecu'
|
||||||
if (isHomeLayoutId(adminLayout)) {
|
|
||||||
return adminLayout
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isBoursecuProject()) {
|
|
||||||
return 'boursecu'
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEFAULT_HOME_LAYOUT_ID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHomeLayoutConfig(layoutId = getHomeLayoutId()): HomeLayoutConfig {
|
export function getHomeLayoutConfig(layoutId = getHomeLayoutId()): HomeLayoutConfig {
|
||||||
return HOME_LAYOUT_CONFIGS[layoutId] ?? HOME_LAYOUT_CONFIGS[DEFAULT_HOME_LAYOUT_ID]
|
return HOME_LAYOUT_CONFIGS[layoutId] ?? boursecuHomeLayoutConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveHomeLayoutComponent(_layoutId = getHomeLayoutId()): Component {
|
export function resolveHomeLayoutComponent(_layoutId = getHomeLayoutId()): Component {
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, inject } from 'vue'
|
import { inject } from 'vue'
|
||||||
import AssetsSection from '../../components/AssetsSection.vue'
|
import AssetsSection from '../../components/AssetsSection.vue'
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
||||||
const isPlainAssets = computed(() => ctx.isBoursecuHomeLayout.value)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<AssetsSection
|
<AssetsSection
|
||||||
v-if="!ctx.isGaroosi.value"
|
plain
|
||||||
:plain="isPlainAssets"
|
boursecu-layout
|
||||||
:boursecu-layout="isPlainAssets"
|
|
||||||
@open-gold-modal="ctx.openGoldModal"
|
@open-gold-modal="ctx.openGoldModal"
|
||||||
@open-rial-modal="ctx.openRialModal"
|
@open-rial-modal="ctx.openRialModal"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import { useUserStore } from '@/store/userStore'
|
|
||||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
|
||||||
import AssetItem from '../../components/AssetItem.vue'
|
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
|
||||||
const userStore = useUserStore()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div v-if="ctx.isGaroosi.value" class="flex justify-between px-2 mb-2">
|
|
||||||
<AssetItem
|
|
||||||
label="دارایی طلایی:"
|
|
||||||
:value="`${(userStore?.userInfo?.wallet?.count_gold ?? 0).toFixed(3)} گرم`"
|
|
||||||
/>
|
|
||||||
<AssetItem
|
|
||||||
label="دارایی ریالی:"
|
|
||||||
:value="`${usePriceWithoutType(userStore?.userInfo?.wallet?.count_cash ?? 0)} ریال`"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import MarketClosedMessage from '../../components/MarketClosedMessage.vue'
|
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<MarketClosedMessage
|
|
||||||
v-if="!isBoursecuProject() && ctx.showClosedMessage.value"
|
|
||||||
:message="ctx.closedMessage.value as string"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
@@ -4,7 +4,7 @@ import PriceChart from '../../components/PriceChart.vue'
|
|||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
||||||
const layout = computed(() => (toValue(ctx.isBoursecuHomeLayout) ? 'boursecu' : 'default'))
|
const layout = 'boursecu' as const
|
||||||
const priceChartSeries = computed(() => toValue(ctx.priceChartSeries))
|
const priceChartSeries = computed(() => toValue(ctx.priceChartSeries))
|
||||||
const chartSelection = computed(() => toValue(ctx.chartSelection))
|
const chartSelection = computed(() => toValue(ctx.chartSelection))
|
||||||
const selectedChartMetal = computed(() => toValue(ctx.selectedChartMetal))
|
const selectedChartMetal = computed(() => toValue(ctx.selectedChartMetal))
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import ReferralSection from '../../components/ReferralSection.vue'
|
|
||||||
import { HOME_PAGE_CONTEXT_KEY } from '../../composables/useHomePage'
|
|
||||||
|
|
||||||
const ctx = inject(HOME_PAGE_CONTEXT_KEY)!
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<ReferralSection v-if="ctx.isGaroosi.value" />
|
|
||||||
</template>
|
|
||||||
@@ -1,23 +1,17 @@
|
|||||||
import type { Component } from 'vue'
|
import type { Component } from 'vue'
|
||||||
import type { HomeSectionId } from '../types'
|
import type { HomeSectionId } from '../types'
|
||||||
import GaroosiAssetsSection from './GaroosiAssetsSection.vue'
|
|
||||||
import MainActionsSection from './MainActionsSection.vue'
|
import MainActionsSection from './MainActionsSection.vue'
|
||||||
import BoursecuQuickActionsSection from './BoursecuQuickActionsSection.vue'
|
import BoursecuQuickActionsSection from './BoursecuQuickActionsSection.vue'
|
||||||
import ReferralSectionBlock from './ReferralSectionBlock.vue'
|
|
||||||
import AssetsSectionBlock from './AssetsSectionBlock.vue'
|
import AssetsSectionBlock from './AssetsSectionBlock.vue'
|
||||||
import MarketClosedSection from './MarketClosedSection.vue'
|
|
||||||
import CurrentPriceSection from './CurrentPriceSection.vue'
|
import CurrentPriceSection from './CurrentPriceSection.vue'
|
||||||
import BannersSection from './BannersSection.vue'
|
import BannersSection from './BannersSection.vue'
|
||||||
import PriceChartSection from './PriceChartSection.vue'
|
import PriceChartSection from './PriceChartSection.vue'
|
||||||
import PriceStatsSection from './PriceStatsSection.vue'
|
import PriceStatsSection from './PriceStatsSection.vue'
|
||||||
|
|
||||||
export const HOME_SECTION_COMPONENTS: Record<HomeSectionId, Component> = {
|
export const HOME_SECTION_COMPONENTS: Record<HomeSectionId, Component> = {
|
||||||
garoosiAssets: GaroosiAssetsSection,
|
|
||||||
mainActions: MainActionsSection,
|
mainActions: MainActionsSection,
|
||||||
boursecuQuickActions: BoursecuQuickActionsSection,
|
boursecuQuickActions: BoursecuQuickActionsSection,
|
||||||
referral: ReferralSectionBlock,
|
|
||||||
assets: AssetsSectionBlock,
|
assets: AssetsSectionBlock,
|
||||||
marketClosed: MarketClosedSection,
|
|
||||||
currentPrice: CurrentPriceSection,
|
currentPrice: CurrentPriceSection,
|
||||||
banners: BannersSection,
|
banners: BannersSection,
|
||||||
priceChart: PriceChartSection,
|
priceChart: PriceChartSection,
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
/** چیدمانهای صفحه اصلی — هر پروژه/ادمین میتواند یکی را انتخاب کند */
|
/** چیدمان صفحه اصلی boursecu */
|
||||||
export type HomeLayoutId = 'default' | 'boursecu'
|
export type HomeLayoutId = 'boursecu'
|
||||||
|
|
||||||
export type HomeSectionId =
|
export type HomeSectionId =
|
||||||
| 'garoosiAssets'
|
|
||||||
| 'mainActions'
|
| 'mainActions'
|
||||||
| 'boursecuQuickActions'
|
| 'boursecuQuickActions'
|
||||||
| 'referral'
|
|
||||||
| 'assets'
|
| 'assets'
|
||||||
| 'marketClosed'
|
|
||||||
| 'currentPrice'
|
| 'currentPrice'
|
||||||
| 'banners'
|
| 'banners'
|
||||||
| 'priceChart'
|
| 'priceChart'
|
||||||
@@ -31,7 +28,6 @@ export interface HomeLayoutConfig {
|
|||||||
wrapperClass?: string
|
wrapperClass?: string
|
||||||
outerSections?: HomeLayoutSectionConfig[]
|
outerSections?: HomeLayoutSectionConfig[]
|
||||||
sections: HomeLayoutSectionConfig[]
|
sections: HomeLayoutSectionConfig[]
|
||||||
/** بعد از wrapper — مثل قیمت و نمودار در UI قدیمی */
|
|
||||||
tailSections?: HomeLayoutSectionConfig[]
|
tailSections?: HomeLayoutSectionConfig[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,6 @@
|
|||||||
v-if="usesQuantityTrade(selectedProduct)"
|
v-if="usesQuantityTrade(selectedProduct)"
|
||||||
:ProductItem="selectedProduct"
|
:ProductItem="selectedProduct"
|
||||||
/>
|
/>
|
||||||
<CopperSilver
|
|
||||||
v-else-if="isMetalCommodityGroup(selectedProduct?.group_type) && !isBoursecuDealProductGroup(selectedProduct?.group_type)"
|
|
||||||
:ProductItem="selectedProduct"
|
|
||||||
/>
|
|
||||||
<DealProduct v-else :ProductItem="selectedProduct" @ordered="onProductOrdered" />
|
<DealProduct v-else :ProductItem="selectedProduct" @ordered="onProductOrdered" />
|
||||||
</div>
|
</div>
|
||||||
</BasicActionSheet>
|
</BasicActionSheet>
|
||||||
@@ -36,10 +32,6 @@
|
|||||||
v-if="usesQuantityTrade(selectedProduct)"
|
v-if="usesQuantityTrade(selectedProduct)"
|
||||||
:ProductItem="selectedProduct"
|
:ProductItem="selectedProduct"
|
||||||
/>
|
/>
|
||||||
<CopperSilver
|
|
||||||
v-else-if="isMetalCommodityGroup(selectedProduct?.group_type) && !isBoursecuDealProductGroup(selectedProduct?.group_type)"
|
|
||||||
:ProductItem="selectedProduct"
|
|
||||||
/>
|
|
||||||
<DealProduct v-else :ProductItem="selectedProduct" @ordered="onProductOrdered" />
|
<DealProduct v-else :ProductItem="selectedProduct" @ordered="onProductOrdered" />
|
||||||
</div>
|
</div>
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
@@ -78,13 +70,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||||
import indexGold from '@/views/base/gold/index.vue'
|
import indexGold from '@/views/base/gold/index.vue'
|
||||||
import CopperSilver from '@/views/base/copper&silver/index.vue'
|
|
||||||
import DealProduct from '@/views/base/products/components/DealProduct.vue'
|
import DealProduct from '@/views/base/products/components/DealProduct.vue'
|
||||||
import BasicModal from '@/components/BasicPacks/BasicModal.vue'
|
import BasicModal from '@/components/BasicPacks/BasicModal.vue'
|
||||||
import ResponsiveViewPair from '@/layouts/components/ResponsiveViewPair.vue'
|
import ResponsiveViewPair from '@/layouts/components/ResponsiveViewPair.vue'
|
||||||
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
||||||
import { isMetalCommodityGroup, usesQuantityTrade } from '@/utils/productCategories'
|
import { usesQuantityTrade } from '@/utils/productCategories'
|
||||||
import { isBoursecuDealProductGroup } from '@/utils/productDealMethod'
|
|
||||||
import { useProductsPageProvider } from './composables/useProductsPage'
|
import { useProductsPageProvider } from './composables/useProductsPage'
|
||||||
import MobileProductsView from './mobile/MobileProductsView.vue'
|
import MobileProductsView from './mobile/MobileProductsView.vue'
|
||||||
import DesktopProductsView from './desktop/DesktopProductsView.vue'
|
import DesktopProductsView from './desktop/DesktopProductsView.vue'
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
import { computed, inject, provide, type ComputedRef, type InjectionKey } from 'vue'
|
import { computed, inject, provide, type InjectionKey } from 'vue'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
import { useConfigStore } from '@/store/configStore'
|
||||||
import {
|
import {
|
||||||
getProjectBaleLink,
|
getProjectBaleLink,
|
||||||
getProjectSupportPhoneLink,
|
getProjectSupportPhoneLink,
|
||||||
isBoursecuProject,
|
|
||||||
} from '@/utils/config'
|
} from '@/utils/config'
|
||||||
import { getRulesBlocks, getRulesTitle, type RulesBlock } from '../rulesContent'
|
import { getRulesBlocks, getRulesTitle, type RulesBlock } from '../rulesContent'
|
||||||
|
|
||||||
export interface RulesPageContext {
|
export interface RulesPageContext {
|
||||||
config: ReturnType<typeof useConfigStore>
|
config: ReturnType<typeof useConfigStore>
|
||||||
nameProject: ComputedRef<string>
|
nameProject: ReturnType<typeof computed<string>>
|
||||||
isBoursecu: ComputedRef<boolean>
|
rulesTitle: ReturnType<typeof computed<string>>
|
||||||
rulesTitle: ComputedRef<string>
|
rulesBlocks: ReturnType<typeof computed<RulesBlock[]>>
|
||||||
rulesBlocks: ComputedRef<RulesBlock[]>
|
|
||||||
getProjectSupportPhoneLink: typeof getProjectSupportPhoneLink
|
getProjectSupportPhoneLink: typeof getProjectSupportPhoneLink
|
||||||
getProjectBaleLink: typeof getProjectBaleLink
|
getProjectBaleLink: typeof getProjectBaleLink
|
||||||
}
|
}
|
||||||
@@ -26,16 +24,13 @@ export function useRulesPage() {
|
|||||||
() => config.config?.name_fa || config.config?.name || 'بورس مس',
|
() => config.config?.name_fa || config.config?.name || 'بورس مس',
|
||||||
)
|
)
|
||||||
|
|
||||||
const isBoursecu = computed(() => isBoursecuProject())
|
const rulesTitle = computed(() => getRulesTitle(nameProject.value, true))
|
||||||
|
|
||||||
const rulesTitle = computed(() => getRulesTitle(nameProject.value, isBoursecu.value))
|
const rulesBlocks = computed(() => getRulesBlocks(nameProject.value, true))
|
||||||
|
|
||||||
const rulesBlocks = computed(() => getRulesBlocks(nameProject.value, isBoursecu.value))
|
|
||||||
|
|
||||||
const context: RulesPageContext = {
|
const context: RulesPageContext = {
|
||||||
config,
|
config,
|
||||||
nameProject,
|
nameProject,
|
||||||
isBoursecu,
|
|
||||||
rulesTitle,
|
rulesTitle,
|
||||||
rulesBlocks,
|
rulesBlocks,
|
||||||
getProjectSupportPhoneLink,
|
getProjectSupportPhoneLink,
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { isBazretalaProject } from '@/utils/config'
|
|
||||||
|
|
||||||
export interface RulesBlock {
|
export interface RulesBlock {
|
||||||
title?: string
|
title?: string
|
||||||
items: string[]
|
items: string[]
|
||||||
@@ -41,40 +39,6 @@ function getDefaultRulesItems(nameProject: string): string[] {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBazretalaRulesBlocks(): RulesBlock[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
items: [
|
|
||||||
'کاربران موظفند قبل از ثبت نام، تمامی مفاد این تعهدنامه را مطالعه نموده و صرفاً در صورت پذیرش آن اقدام به ثبتنام نمایند.',
|
|
||||||
'کاربران بذر طلا میپذیرند که کلیهی فعالیتهای آنها در بذر طلا، در چارچوب قوانین جمهوری اسلامی ایران بوده و هیچ گونه فعالیتی خارج از این چارچوب انجام نخواهد شد.',
|
|
||||||
'احراز هویت برای استفاده از خدمات بذر طلا ضروری بوده و کاربران موظفند اطلاعات صحیح خود را بارگذاری نمایند؛ بدیهی است در صورت وجود هرگونه تخلف در احراز هویت، مسئولیت به عهدهی فرد متخلف بوده و بذر طلا حق توقف ارائه خدمات به کاربر مذکور و ارجاع موارد تخلف به مراجع ذیصلاح را خواهد داشت.',
|
|
||||||
'بذر طلا خود را ملزم به حفظ اطلاعات شخصی کاربران در چارچوب قوانین قضایی کشور میداند.',
|
|
||||||
'کاربران بذر طلا تعهد میدهند که از قرار دادن حساب خود در اختیار دیگران خودداری نمایند. از خدمات سایت، تنها برای حساب شخصی خود استفاده نموده و مسئولیت استفاده از خدمات بذر طلا برای فردی دیگر، به عهده کاربر خواهد بود. شماره حساب اعلام شده به سایت باید متعلق به کاربر بوده و کاربران مجاز به دادن شماره حساب متعلق به اشخاص دیگر نیستند.',
|
|
||||||
'کاربران میپذیرند در صورت تشخیص کارشناسان پشتیبانی، جهت حفظ امنیت دارایی حساب کاربریشان با اطلاع قبلی نسبت به برقراری تماس تصویری با تیم پشتیبان همکاری نمایند.',
|
|
||||||
'هرگونه سهلانگاری کاربران در حفظ اطلاعات شخصی و امنیتی از جمله: رمز عبور کاربر، سرقت گوشی کاربر، سرقت کارت ملی و مدارک شناسایی کاربر، سپردن مدارک شخصی و موبایل به فرد ثالث و ... به عهدهی شخص کاربر بوده و بذر طلا هیچ گونه مسئولیتی در این موارد نخواهد داشت.',
|
|
||||||
'اکیداً توصیه میشود از رمز عبوری پیچیده، امن و همچنین کد شناسایی دو عاملی استفاده شود.',
|
|
||||||
'بذر طلا این اطمینان را میدهد که داراییهای کاربران را نزد خود به امانت و به بهترین شکل و با بالاترین استانداردهای امنیتی ممکن حفظ نماید؛ در صورت بروز هرگونه مشکل امنیتی، بذر طلا متعهد به جبران خسارت خواهد بود.',
|
|
||||||
'به عنوان پلتفرم معاملات برخط فلزات گرانبها، هیچگونه مسئولیتی در قبال تصمیمات اقتصادی فی مابین کاربران و سود و زیان حاصل از آن بر عهده بذر طلا نمیباشد.',
|
|
||||||
'بذر طلا حق اصلاح و تغییر قوانین و مقررات ذکر شده در این صفحه را چه به صورت کلی و چه به صورت جزئی دارد و نسخه نهایی را در این صفحه در معرض دید قرار میدهد. استفاده از خدمات بذر طلا پس از اعمال تغییرات، به معنای پذیرش همه تغییرات میباشد.',
|
|
||||||
'از لحظه خرید کاربران تا زمان تحویل طلا و نقره ی خریداری شده، مسئولیت حفظ و نگهداری اصل طلا و نقره بر عهده بذر طلا میباشد.',
|
|
||||||
'کاربران بذر طلا اذعان میدارند که از ریسکهای اقتصادی مربوط به سرمایهگذاری در حوزه طلا و نقره مطلع بوده و با علم بر این موضوع اقدام به تبادل و سرمایهگذاری میکنند.',
|
|
||||||
'بذر طلا متعهد میشود در حد توان از حریم شخصی شما محافظت کند و در این راستا، تکنولوژی مورد نیاز در سایت و پلتفرم را برای هر چه مطمئنتر و امنتر شدن استفاده شما، توسعه دهد.',
|
|
||||||
'در صورت بروز نوسان شدید در قیمت طلا و نقره هرگونه رویداد برهمزننده نظم حاکم بر بازار طلا و نقره، بذر طلا میتواند برای خرید و فروش طلا و نقره توسط کاربر سقف تعیین کند تا دو طرف متضرر نشوند.',
|
|
||||||
'بذر طلا مجاز است بدون اطلاع قبلی و به صلاحدید شخصی نسبت به توقف سفارشگیری جدید، معاملات (از جمله سفارشهای باز) را متوقف کند؛ بدیهی است که کلیه سفارشهای تکمیلشده قبل از توقف سفارشگیری، پردازش و تحویل داده خواهد شد.',
|
|
||||||
'در صورت بروز هرگونه اختلال در اینترنت و خدمات زیرساخت به دلایل حاکمیتی، هیچگونه مسئولیتی به عهده بذر طلا نمیباشد.',
|
|
||||||
'درخواست برداشت ریال از حساب کاربری در سریعترین زمان ممکن پس از ثبت، بررسی خواهد شد. زمان واریز پول به حساب کاربران بر اساس محدودیتهای انتقال وجه بین بانکی، متفاوت خواهد بود. برای اطلاعات بیشتر، به قوانین انتقال وجه بین بانکی (پایا، ساتنا) مراجعه فرمایید.',
|
|
||||||
'کاربر میپذیرد که به جز در موارد مورد تعهد، حق هیچگونه داعیه، طلب و شکایت از سایت، مدیران، کارمندان و افراد مرتبط با این سایت را نخواهد داشت.',
|
|
||||||
'اگر کاربر تحت هر عنوان اشتباهاً یا من غیر حق، وجوهی را به حساب کاربر منظور یا در محاسبات خود هر نوع اشتباهی نماید، بذر طلا هر زمان مجاز و مختار است راساً و مستقلاً و بدون انجام هیچگونه تشریفات اداری و قضایی و دریافت اجازه کتبی از متعهد (صاحب حساب) در رفع اشتباه و برداشت از حسابهای وی اقدام نماید و تشخیص نسبت به وقوع اشتباه یا پرداخت بدون حق و لزوم برداشت از حساب معتبر خواهد بود و کاربر حق هرگونه اعتراض و ادعایی را در خصوص نحوه عملکرد بذر طلا از هر جهت از خود ساقط مینماید.',
|
|
||||||
'در صورت بروز هرگونه مشکل یا ابهام در هر یک از معاملات (مانند دستکاری قیمت، اختلال در وبسرویسها، انجام معامله خارج از دامنه نوسان و ...)، بذر طلا حق دارد مستقلاً آن معامله را ابطال کرده و داراییهای هر یک از طرفین را به حساب خودشان عودت دهد. بدیهی است در صورتی که اشکال از سمت بذر طلا باشد، شرکت موظف خواهد بود که جبران خسارت نماید و در غیر این صورت، کاربر حق هرگونه اعتراض و ادعایی در خصوص نحوه عملکرد از هر جهت را از خود ساقط مینماید.',
|
|
||||||
'در صورت فوت یا حجر کاربر، بذر طلا پیرو قوانین جمهوری اسلامی ایران میباشد. کاربر با علم و اطلاع از مقررات این بند نسبت به افتتاح حساب کاربری در بذر طلا اقدام نموده و کاربر، اشخاص ثالث، ورثه یا قائممقام قانونی ایشان حق اعتراض و یا ادعایی در آینده در این خصوص نخواهند داشت.',
|
|
||||||
'هزینه خدمات و کارمزد تراکنشهای مالی انجام شده در مطابق با توضیحات ارائه شده در صفحه راهنمای استفاده از بذر طلا میباشد.',
|
|
||||||
'تمامی علائم تجاری، طرحهای گرافیکی، رابط کاربری، رابط بصری، عکس، لوگو، کدهای نرمافزار، ساختار، نحوه بیان، تنظیم مطالب و محتوای موجود در بذر طلا و شبکههای متعلق به بذر طلا و بهطور کلی، سایر حقوق و امتیازات مربوطه منحصراً در مالکیت بذر طلا میباشد و هیچ شخصی حق استفاده از آن را بدون رضایت بذر طلا ندارد.',
|
|
||||||
'اگر هر یک از مفاد این موافقتنامه بر اساس هر قانون لازمالاجرا، نامعتبر یا غیرقابل اجرا تشخیص داده شود، این امر بر اعتبار هیچ ماده دیگری تأثیری نخواهد داشت و بقیه مقررات اجرا میشود.',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBoursecuRulesBlocks(nameProject: string): RulesBlock[] {
|
function getBoursecuRulesBlocks(nameProject: string): RulesBlock[] {
|
||||||
const brand = resolveProjectName(nameProject)
|
const brand = resolveProjectName(nameProject)
|
||||||
|
|
||||||
@@ -141,10 +105,6 @@ export function getRulesTitle(nameProject: string, isBoursecu: boolean) {
|
|||||||
return `قوانین و مقررات معاملات مس در بستر ${brand}`
|
return `قوانین و مقررات معاملات مس در بستر ${brand}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return 'قوانین و مقررات معاملات طلا و نقره در بستر بذر طلا'
|
|
||||||
}
|
|
||||||
|
|
||||||
return `قوانین و مقررات معاملات طلا در بستر ${brand}`
|
return `قوانین و مقررات معاملات طلا در بستر ${brand}`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,10 +113,6 @@ export function getRulesBlocks(nameProject: string, isBoursecu: boolean): RulesB
|
|||||||
return getBoursecuRulesBlocks(nameProject)
|
return getBoursecuRulesBlocks(nameProject)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBazretalaProject()) {
|
|
||||||
return getBazretalaRulesBlocks()
|
|
||||||
}
|
|
||||||
|
|
||||||
return [{ items: getDefaultRulesItems(nameProject) }]
|
return [{ items: getDefaultRulesItems(nameProject) }]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="relative">
|
|
||||||
<div
|
|
||||||
class="mobile-page-bg mobile-page-bg--cover opacity-60"
|
|
||||||
aria-hidden="true"
|
|
||||||
:style="{ backgroundImage: `url(${img})` }"
|
|
||||||
></div>
|
|
||||||
<MobilePageHeader title="تراکنش ها">
|
|
||||||
<template #trailing>
|
|
||||||
<BasicIcon icon="vuesax-linear:filter" @click="showFilter = true" />
|
|
||||||
</template>
|
|
||||||
</MobilePageHeader>
|
|
||||||
|
|
||||||
<!-- <div ref="el" :class="loading ? 'h-screen' : ''" class="px-3 mpage-content pb-10">-->
|
|
||||||
<div ref="el" class="transactions-page-body relative z-1 px-3 mpage-content pb-24">
|
|
||||||
<list-anim v-if="!loading">
|
|
||||||
<Item v-for="item in items" :key="item.id" :item="item" />
|
|
||||||
<div :ref="bindMobileObserver" v-show="!loading" class="w-full opacity-0 relative">
|
|
||||||
در حال بارگذاری
|
|
||||||
</div>
|
|
||||||
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
|
|
||||||
</list-anim>
|
|
||||||
<TransactionSkeleton v-for="i in 13" v-else :key="i" class="mt-1" />
|
|
||||||
<div v-if="items.length <= 0 && !loading" class="flex flex-col items-center justify-center h-80vh">
|
|
||||||
<DotLottieVue
|
|
||||||
class="w-11rem h-11rem"
|
|
||||||
autoplay
|
|
||||||
src="https://lottie.host/51d3315a-cf88-4c18-bb4d-a31511fd4325/KjSBzcMbi6.json"
|
|
||||||
/>
|
|
||||||
<div class="font-bold">{{ emptyText }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<BasicActionSheet v-model:show="showFilter">
|
|
||||||
<div class="font-bold text-lg">فیلتر</div>
|
|
||||||
<div class="pb-10 mt-5">
|
|
||||||
<a-form-item class="w-full gap-2 !flex-col" label="تاریخ" name="password">
|
|
||||||
<BaseDatePicker v-model:value="dateFilter" class="w-full" size="large" />
|
|
||||||
</a-form-item>
|
|
||||||
<BasicButton class="w-full mt-5" type="primary" @click="applyFilter">اعمال فیلتر</BasicButton>
|
|
||||||
<BasicButton class="w-full mt-2" @click="showFilter = false">بازگشت</BasicButton>
|
|
||||||
</div>
|
|
||||||
</BasicActionSheet>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { loading, loadingMore } from '@/utils'
|
|
||||||
import Item from './components/Item.vue'
|
|
||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
|
||||||
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
|
|
||||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
|
||||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
|
||||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
|
|
||||||
import ListAnim from '@/components/ListAnim.vue'
|
|
||||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
|
||||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
|
||||||
import img from '@/assets/img/user_ly1.svg'
|
|
||||||
import { useTransactionsPageContext } from './composables/useTransactionsPage'
|
|
||||||
|
|
||||||
const el = ref<HTMLElement | null>(null)
|
|
||||||
|
|
||||||
const {
|
|
||||||
items,
|
|
||||||
showFilter,
|
|
||||||
dateFilter,
|
|
||||||
emptyText,
|
|
||||||
applyFilter,
|
|
||||||
bindMobileObserver,
|
|
||||||
} = useTransactionsPageContext()
|
|
||||||
</script>
|
|
||||||
@@ -15,9 +15,6 @@
|
|||||||
<p class="dtxn-row__title">{{ props.item.title }}</p>
|
<p class="dtxn-row__title">{{ props.item.title }}</p>
|
||||||
<div class="dtxn-row__meta">
|
<div class="dtxn-row__meta">
|
||||||
<span>{{ toJalaliOutOfUTC(props.item.expire_at) }}</span>
|
<span>{{ toJalaliOutOfUTC(props.item.expire_at) }}</span>
|
||||||
<span v-if="!isBoursecu" :class="goldAmount >= 0 ? 'text-green-600' : 'text-red-600'">
|
|
||||||
{{ formatTransactionGoldAmount(props.item, goldAmount) }} {{ props.item.unit }}
|
|
||||||
</span>
|
|
||||||
<span v-if="isGold">
|
<span v-if="isGold">
|
||||||
قیمت معامله:
|
قیمت معامله:
|
||||||
{{ usePriceWithoutType(tradePrice) }}
|
{{ usePriceWithoutType(tradePrice) }}
|
||||||
@@ -54,15 +51,7 @@
|
|||||||
<div>{{ props.item.title }}</div>
|
<div>{{ props.item.title }}</div>
|
||||||
<div>{{ toJalaliOutOfUTC(props.item.expire_at) }}</div>
|
<div>{{ toJalaliOutOfUTC(props.item.expire_at) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="['flex mt-2', isBoursecu ? 'justify-end' : 'justify-between']">
|
<div class="flex mt-2 justify-end">
|
||||||
<div
|
|
||||||
v-if="!isBoursecu"
|
|
||||||
:class="goldAmount >= 0 ? 'text-green-600' : 'text-red-600'"
|
|
||||||
class="text-gray-500 text-xs number-ltr"
|
|
||||||
>
|
|
||||||
{{ formatTransactionGoldAmount(props.item, goldAmount) }}
|
|
||||||
<div>{{ props.item.unit }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-gray-500 flex gap-1 text-xs items-center number-ltr">
|
<div class="text-gray-500 flex gap-1 text-xs items-center number-ltr">
|
||||||
<div :class="props.item.cash > 0 ? 'text-green-600' : 'text-red-600'" class="text-base">
|
<div :class="props.item.cash > 0 ? 'text-green-600' : 'text-red-600'" class="text-base">
|
||||||
{{ usePriceWithoutType(props.item.cash ?? 0) }}
|
{{ usePriceWithoutType(props.item.cash ?? 0) }}
|
||||||
@@ -116,23 +105,18 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||||
import {
|
import {
|
||||||
getTransactionGoldAmount,
|
|
||||||
getTransactionTradePrice,
|
getTransactionTradePrice,
|
||||||
resolveTransactionStatusLabel,
|
resolveTransactionStatusLabel,
|
||||||
usePriceWithoutType,
|
usePriceWithoutType,
|
||||||
} from '@/utils/usePrice'
|
} from '@/utils/usePrice'
|
||||||
import { formatTransactionGoldAmount } from '@/utils/productDealMethod'
|
|
||||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||||
import BasicModal from '@/components/BasicPacks/BasicModal.vue'
|
import BasicModal from '@/components/BasicPacks/BasicModal.vue'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||||
import type { Transaction } from '@/models/transaction'
|
import type { Transaction } from '@/models/transaction'
|
||||||
import { toJalaliOutOfUTC } from '@/utils/useDateTime'
|
import { toJalaliOutOfUTC } from '@/utils/useDateTime'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import TransactionDetailPanel from './TransactionDetailPanel.vue'
|
import TransactionDetailPanel from './TransactionDetailPanel.vue'
|
||||||
|
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
|
|
||||||
const infoVisible = ref(false)
|
const infoVisible = ref(false)
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
@@ -143,7 +127,6 @@ const props = withDefaults(
|
|||||||
{ variant: 'mobile' },
|
{ variant: 'mobile' },
|
||||||
)
|
)
|
||||||
|
|
||||||
const goldAmount = computed(() => getTransactionGoldAmount(props.item))
|
|
||||||
const tradePrice = computed(() => getTransactionTradePrice(props.item))
|
const tradePrice = computed(() => getTransactionTradePrice(props.item))
|
||||||
const statusLabel = computed(() => resolveTransactionStatusLabel(props.item))
|
const statusLabel = computed(() => resolveTransactionStatusLabel(props.item))
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import {
|
|||||||
transactionProductFilter,
|
transactionProductFilter,
|
||||||
transactionTableOutput,
|
transactionTableOutput,
|
||||||
transactionTradeSide,
|
transactionTradeSide,
|
||||||
transactionsBoursecuMode,
|
|
||||||
} from './useTransactionsPageData'
|
} from './useTransactionsPageData'
|
||||||
|
|
||||||
export interface TransactionsPageContext {
|
export interface TransactionsPageContext {
|
||||||
@@ -64,8 +63,7 @@ export interface TransactionsPageContext {
|
|||||||
export const TRANSACTIONS_PAGE_KEY: InjectionKey<TransactionsPageContext> =
|
export const TRANSACTIONS_PAGE_KEY: InjectionKey<TransactionsPageContext> =
|
||||||
Symbol('transactionsPage')
|
Symbol('transactionsPage')
|
||||||
|
|
||||||
export function useTransactionsPageProvider(options?: { boursecu?: boolean }) {
|
export function useTransactionsPageProvider() {
|
||||||
const isBoursecu = options?.boursecu ?? false
|
|
||||||
const isDesktop = useDesktopBreakpoint()
|
const isDesktop = useDesktopBreakpoint()
|
||||||
const showFilter = ref(false)
|
const showFilter = ref(false)
|
||||||
const mobileObserverEl = ref<HTMLElement | null>(null)
|
const mobileObserverEl = ref<HTMLElement | null>(null)
|
||||||
@@ -93,14 +91,10 @@ export function useTransactionsPageProvider(options?: { boursecu?: boolean }) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const showProductFilter = computed(
|
const showProductFilter = computed(
|
||||||
() => transactionsBoursecuMode.value && boursecuTabSupportsProductFilter(activeTab.value),
|
() => boursecuTabSupportsProductFilter(activeTab.value),
|
||||||
)
|
)
|
||||||
|
|
||||||
const emptyText = computed(() => {
|
const emptyText = computed(() => {
|
||||||
if (!transactionsBoursecuMode.value) {
|
|
||||||
return 'تراکنشی موجود نیست'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeTab.value.id === 'trades' && transactionTradeSide.value === 'sell') {
|
if (activeTab.value.id === 'trades' && transactionTradeSide.value === 'sell') {
|
||||||
return 'معامله فروشی برای شما به ثبت نرسیده است'
|
return 'معامله فروشی برای شما به ثبت نرسیده است'
|
||||||
}
|
}
|
||||||
@@ -183,10 +177,8 @@ export function useTransactionsPageProvider(options?: { boursecu?: boolean }) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (isBoursecu) {
|
await getProductsCatalog()
|
||||||
await getProductsCatalog()
|
await initTransactionsPageData()
|
||||||
}
|
|
||||||
await initTransactionsPageData(isBoursecu)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onActivated(async () => {
|
onActivated(async () => {
|
||||||
@@ -236,6 +228,6 @@ export function useTransactionsPageContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated Use useTransactionsPageProvider in index + useTransactionsPageContext in views. */
|
/** @deprecated Use useTransactionsPageProvider in index + useTransactionsPageContext in views. */
|
||||||
export function useTransactionsPage(options?: { boursecu?: boolean }) {
|
export function useTransactionsPage() {
|
||||||
return useTransactionsPageProvider(options)
|
return useTransactionsPageProvider()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
/** Shared transactions page state — refetched on every page visit (no list cache). */
|
/** Shared transactions page state — refetched on every page visit (no list cache). */
|
||||||
let activeFetchId = 0
|
let activeFetchId = 0
|
||||||
|
|
||||||
export const transactionsBoursecuMode = ref(false)
|
export const transactionsBoursecuMode = ref(true)
|
||||||
export const transactionPagination = ref<TableEngineInput>({ filters: [], limit: 7, page: 0 })
|
export const transactionPagination = ref<TableEngineInput>({ filters: [], limit: 7, page: 0 })
|
||||||
export const transactionItems = ref<Transaction[]>([])
|
export const transactionItems = ref<Transaction[]>([])
|
||||||
export const transactionTableOutput = ref<TableEngineOutput<Transaction> | null>(null)
|
export const transactionTableOutput = ref<TableEngineOutput<Transaction> | null>(null)
|
||||||
@@ -34,37 +34,19 @@ export function getActiveBoursecuTab(): BoursecuTransactionTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function resetTransactionsPagination() {
|
export function resetTransactionsPagination() {
|
||||||
if (transactionsBoursecuMode.value) {
|
transactionPagination.value = buildBoursecuTransactionPagination(
|
||||||
transactionPagination.value = buildBoursecuTransactionPagination(
|
getActiveBoursecuTab(),
|
||||||
getActiveBoursecuTab(),
|
transactionTradeSide.value,
|
||||||
transactionTradeSide.value,
|
transactionDateFromFilter.value,
|
||||||
transactionDateFromFilter.value,
|
transactionDateToFilter.value,
|
||||||
transactionDateToFilter.value,
|
transactionStatusFilter.value,
|
||||||
transactionStatusFilter.value,
|
transactionProductFilter.value,
|
||||||
transactionProductFilter.value,
|
)
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
transactionPagination.value = { filters: [], limit: 7, page: 0 }
|
|
||||||
if (transactionDateFilter.value) {
|
|
||||||
transactionPagination.value.filters = [
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
cr: 'and',
|
|
||||||
type: 'date',
|
|
||||||
op: 'eq',
|
|
||||||
value: transactionDateFilter.value,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveTransactionFetcher() {
|
function resolveTransactionFetcher() {
|
||||||
const activeTab = getActiveBoursecuTab()
|
const activeTab = getActiveBoursecuTab()
|
||||||
return transactionsBoursecuMode.value && activeTab.fetchMode === 'deposit'
|
return activeTab.fetchMode === 'deposit' ? getTransactionTable2 : getTransactionTable
|
||||||
? getTransactionTable2
|
|
||||||
: getTransactionTable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchTransactionsPage(append: boolean): Promise<boolean> {
|
async function fetchTransactionsPage(append: boolean): Promise<boolean> {
|
||||||
@@ -134,8 +116,8 @@ export async function loadMoreTransactions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** هر بار ورود به صفحه تراکنشها */
|
/** هر بار ورود به صفحه تراکنشها */
|
||||||
export async function initTransactionsPageData(boursecu: boolean) {
|
export async function initTransactionsPageData() {
|
||||||
transactionsBoursecuMode.value = boursecu
|
transactionsBoursecuMode.value = true
|
||||||
await reloadTransactionsTable()
|
await reloadTransactionsTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +125,7 @@ export function resetTransactionsPageData() {
|
|||||||
activeFetchId += 1
|
activeFetchId += 1
|
||||||
loading.value = false
|
loading.value = false
|
||||||
loadingMore.value = false
|
loadingMore.value = false
|
||||||
transactionsBoursecuMode.value = false
|
transactionsBoursecuMode.value = true
|
||||||
transactionPagination.value = { filters: [], limit: 7, page: 0 }
|
transactionPagination.value = { filters: [], limit: 7, page: 0 }
|
||||||
transactionItems.value = []
|
transactionItems.value = []
|
||||||
transactionTableOutput.value = null
|
transactionTableOutput.value = null
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="dtxn">
|
|
||||||
<div class="dtxn__container">
|
|
||||||
<DesktopPageTopbar title="تراکنشها" />
|
|
||||||
|
|
||||||
<div class="dtxn-filters">
|
|
||||||
<div class="dtxn-filters__label">
|
|
||||||
<BasicIcon icon="vuesax-linear:filter" size="16" />
|
|
||||||
<span>فیلتر تاریخ:</span>
|
|
||||||
</div>
|
|
||||||
<BaseDatePicker
|
|
||||||
v-model:value="dateFilter"
|
|
||||||
class="dtxn-filters__date"
|
|
||||||
placeholder="تاریخ"
|
|
||||||
size="large"
|
|
||||||
/>
|
|
||||||
<BasicButton type="primary" @click="applyFilter">اعمال فیلتر</BasicButton>
|
|
||||||
<BasicButton v-if="dateFilter" @click="clearFilter">حذف فیلتر</BasicButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div ref="el" :class="loading ? 'min-h-[40vh]' : ''" class="mt-5">
|
|
||||||
<div v-if="!loading" class="dtxn-list">
|
|
||||||
<list-anim>
|
|
||||||
<Item
|
|
||||||
v-for="item in items"
|
|
||||||
:key="item.id"
|
|
||||||
:item="item"
|
|
||||||
variant="desktop"
|
|
||||||
/>
|
|
||||||
</list-anim>
|
|
||||||
<div :ref="bindDesktopObserver" class="w-full opacity-0 relative">
|
|
||||||
در حال بارگذاری
|
|
||||||
</div>
|
|
||||||
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-else>
|
|
||||||
<TransactionSkeleton v-for="i in 8" :key="i" class="mt-1" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div v-if="items.length <= 0 && !loading" class="dtxn-empty">
|
|
||||||
<DotLottieVue
|
|
||||||
class="w-44 h-44"
|
|
||||||
autoplay
|
|
||||||
src="https://lottie.host/51d3315a-cf88-4c18-bb4d-a31511fd4325/KjSBzcMbi6.json"
|
|
||||||
/>
|
|
||||||
<p class="dtxn-empty__text">{{ emptyText }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { loading, loadingMore } from '@/utils'
|
|
||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
|
||||||
import DesktopPageTopbar from '@/layouts/components/DesktopPageTopbar.vue'
|
|
||||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
|
||||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
|
|
||||||
import ListAnim from '@/components/ListAnim.vue'
|
|
||||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
|
||||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
|
||||||
import Item from '../components/Item.vue'
|
|
||||||
import { useTransactionsPageContext } from '../composables/useTransactionsPage'
|
|
||||||
|
|
||||||
const el = ref<HTMLElement | null>(null)
|
|
||||||
|
|
||||||
const {
|
|
||||||
items,
|
|
||||||
dateFilter,
|
|
||||||
emptyText,
|
|
||||||
applyFilter,
|
|
||||||
reloadTable,
|
|
||||||
bindDesktopObserver,
|
|
||||||
} = useTransactionsPageContext()
|
|
||||||
|
|
||||||
async function clearFilter() {
|
|
||||||
dateFilter.value = undefined
|
|
||||||
await reloadTable()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" src="./styles/desktop-transactions.less"></style>
|
|
||||||
@@ -39,11 +39,13 @@
|
|||||||
transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #d1d5db;
|
background: @App-primary-color;
|
||||||
color: #374151;
|
border-color: @App-primary-color;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--active {
|
&--active,
|
||||||
|
&--active:hover {
|
||||||
background: @App-primary-color;
|
background: @App-primary-color;
|
||||||
border-color: @App-primary-color;
|
border-color: @App-primary-color;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="transactions-page-root">
|
<div class="transactions-page-root">
|
||||||
<ResponsiveViewPair v-if="isBoursecu">
|
<ResponsiveViewPair>
|
||||||
<template #mobile>
|
<template #mobile>
|
||||||
<BoursecuTransactionsPage />
|
<BoursecuTransactionsPage />
|
||||||
</template>
|
</template>
|
||||||
@@ -8,29 +8,16 @@
|
|||||||
<DesktopBoursecuTransactionsView />
|
<DesktopBoursecuTransactionsView />
|
||||||
</template>
|
</template>
|
||||||
</ResponsiveViewPair>
|
</ResponsiveViewPair>
|
||||||
<ResponsiveViewPair v-else>
|
|
||||||
<template #mobile>
|
|
||||||
<DefaultTransactionsPage />
|
|
||||||
</template>
|
|
||||||
<template #desktop>
|
|
||||||
<DesktopDefaultTransactionsView />
|
|
||||||
</template>
|
|
||||||
</ResponsiveViewPair>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import ResponsiveViewPair from '@/layouts/components/ResponsiveViewPair.vue'
|
import ResponsiveViewPair from '@/layouts/components/ResponsiveViewPair.vue'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { useTransactionsPageProvider } from './composables/useTransactionsPage'
|
import { useTransactionsPageProvider } from './composables/useTransactionsPage'
|
||||||
import BoursecuTransactionsPage from './BoursecuTransactionsPage.vue'
|
import BoursecuTransactionsPage from './BoursecuTransactionsPage.vue'
|
||||||
import DefaultTransactionsPage from './DefaultTransactionsPage.vue'
|
|
||||||
import DesktopBoursecuTransactionsView from './desktop/DesktopBoursecuTransactionsView.vue'
|
import DesktopBoursecuTransactionsView from './desktop/DesktopBoursecuTransactionsView.vue'
|
||||||
import DesktopDefaultTransactionsView from './desktop/DesktopDefaultTransactionsView.vue'
|
|
||||||
|
|
||||||
const isBoursecu = isBoursecuProject()
|
useTransactionsPageProvider()
|
||||||
|
|
||||||
useTransactionsPageProvider({ boursecu: isBoursecu })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { updateMe, updatePass } from '@/api/me'
|
|||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { getUserAvatarUrl } from '@/utils/file'
|
import { getUserAvatarUrl } from '@/utils/file'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
import { useConfigStore } from '@/store/configStore'
|
||||||
import { getConfigApp, isBoursecuProject, getBoursecuActionIconSrc } from '@/utils/config'
|
import { getBoursecuActionIconSrc } from '@/utils/config'
|
||||||
import { getReferralShareText, getReferralShareTitle, shareReferralText } from '@/utils/referralShare'
|
import { getReferralShareText, getReferralShareTitle, shareReferralText } from '@/utils/referralShare'
|
||||||
import { normalizeAuthFormFields } from '@/utils/persianDigits'
|
import { normalizeAuthFormFields } from '@/utils/persianDigits'
|
||||||
|
|
||||||
@@ -95,13 +95,9 @@ export function useUserPage() {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
const shareButtonLabel = computed(() =>
|
const shareButtonLabel = computed(() => 'اشتراک گذاری')
|
||||||
getConfigApp('name') === 'garoosi' ? 'دعوت از دوستان' : 'اشتراک گذاری',
|
|
||||||
)
|
|
||||||
|
|
||||||
const menuActions = computed<UserMenuAction[]>(() => {
|
const menuActions = computed<UserMenuAction[]>(() => [
|
||||||
const projectName = getConfigApp('name')
|
|
||||||
return [
|
|
||||||
{
|
{
|
||||||
id: 'password',
|
id: 'password',
|
||||||
label: 'تغییر رمز عبور',
|
label: 'تغییر رمز عبور',
|
||||||
@@ -130,20 +126,13 @@ export function useUserPage() {
|
|||||||
onClick: () => router.push({ name: 'about' }),
|
onClick: () => router.push({ name: 'about' }),
|
||||||
visible: true,
|
visible: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'giftCard',
|
|
||||||
label: 'ثبت کارت هدیه',
|
|
||||||
icon: 'vuesax-linear:gift',
|
|
||||||
onClick: () => router.push({ name: 'giftCard' }),
|
|
||||||
visible: projectName === 'garoosi',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'physicalReceive',
|
id: 'physicalReceive',
|
||||||
label: 'تحویل فیزیکی',
|
label: 'تحویل فیزیکی',
|
||||||
icon: 'vuesax-linear:direct-inbox',
|
icon: 'vuesax-linear:direct-inbox',
|
||||||
iconSrc: isBoursecuProject() ? getBoursecuActionIconSrc('physicalReceive') : undefined,
|
iconSrc: getBoursecuActionIconSrc('physicalReceive'),
|
||||||
onClick: () => router.push({ name: 'physicalReceive' }),
|
onClick: () => router.push({ name: 'physicalReceive' }),
|
||||||
visible: projectName !== 'bazretala',
|
visible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rules',
|
id: 'rules',
|
||||||
@@ -152,15 +141,8 @@ export function useUserPage() {
|
|||||||
onClick: () => router.push({ name: 'rules' }),
|
onClick: () => router.push({ name: 'rules' }),
|
||||||
visible: true,
|
visible: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'permissions',
|
|
||||||
label: 'مجوز ها',
|
|
||||||
icon: 'vuesax-linear:archive-book',
|
|
||||||
onClick: () => router.push({ name: 'permissions' }),
|
|
||||||
visible: projectName === 'bazretala',
|
|
||||||
},
|
|
||||||
].filter((action) => action.visible)
|
].filter((action) => action.visible)
|
||||||
})
|
)
|
||||||
|
|
||||||
function setForm() {
|
function setForm() {
|
||||||
userFormState.value = { ...userStore.userInfo } as User
|
userFormState.value = { ...userStore.userInfo } as User
|
||||||
|
|||||||
@@ -13,10 +13,7 @@ import type { Card } from '@/models/wallet'
|
|||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
import { useConfigStore } from '@/store/configStore'
|
||||||
import {
|
import {
|
||||||
getProjectBaleContactLink,
|
|
||||||
getWalletDepositQuickAmountsRial,
|
getWalletDepositQuickAmountsRial,
|
||||||
isBazretalaProject,
|
|
||||||
isBoursecuProject,
|
|
||||||
} from '@/utils/config'
|
} from '@/utils/config'
|
||||||
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
||||||
import {
|
import {
|
||||||
@@ -60,7 +57,6 @@ export interface WalletPageContext {
|
|||||||
depositGuideSupportLink: ReturnType<typeof computed<string>>
|
depositGuideSupportLink: ReturnType<typeof computed<string>>
|
||||||
depositSmsSupportLink: ReturnType<typeof computed<string>>
|
depositSmsSupportLink: ReturnType<typeof computed<string>>
|
||||||
depositQuickAmounts: ReturnType<typeof computed<readonly number[]>>
|
depositQuickAmounts: ReturnType<typeof computed<readonly number[]>>
|
||||||
isBazretalaProject: typeof isBazretalaProject
|
|
||||||
usePriceWithoutType: typeof usePriceWithoutType
|
usePriceWithoutType: typeof usePriceWithoutType
|
||||||
formatCashWalletBalanceText: typeof formatCashWalletBalanceText
|
formatCashWalletBalanceText: typeof formatCashWalletBalanceText
|
||||||
setIsDeposit: (val: boolean) => void
|
setIsDeposit: (val: boolean) => void
|
||||||
@@ -100,16 +96,12 @@ export function useWalletPage() {
|
|||||||
|
|
||||||
const depositQuickAmounts = computed(() => getWalletDepositQuickAmountsRial())
|
const depositQuickAmounts = computed(() => getWalletDepositQuickAmountsRial())
|
||||||
|
|
||||||
const depositGuideSupportLink = computed(() => {
|
const depositGuideSupportLink = computed(() =>
|
||||||
if (config.config?.name === 'garoosi' || isBazretalaProject()) {
|
buildSupportMessengerUrl(
|
||||||
return getProjectBaleContactLink()
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildSupportMessengerUrl(
|
|
||||||
supportMessengerSettings.value.messenger,
|
supportMessengerSettings.value.messenger,
|
||||||
supportMessengerSettings.value.messengerId,
|
supportMessengerSettings.value.messengerId,
|
||||||
)
|
),
|
||||||
})
|
)
|
||||||
|
|
||||||
const depositSmsSupportLink = computed(() =>
|
const depositSmsSupportLink = computed(() =>
|
||||||
buildDepositSmsUrl(supportMessengerSettings.value.depositSmsSupportNumber),
|
buildDepositSmsUrl(supportMessengerSettings.value.depositSmsSupportNumber),
|
||||||
@@ -132,7 +124,7 @@ export function useWalletPage() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const disableButton = computed(() => {
|
const disableButton = computed(() => {
|
||||||
const minWithdrawAmount = isBoursecuProject() ? 200_000 : 1_000_000
|
const minWithdrawAmount = 200_000
|
||||||
const minDepositAmount = 1_000_000
|
const minDepositAmount = 1_000_000
|
||||||
|
|
||||||
if (!loading.value) {
|
if (!loading.value) {
|
||||||
@@ -297,7 +289,6 @@ export function useWalletPage() {
|
|||||||
depositGuideSupportLink,
|
depositGuideSupportLink,
|
||||||
depositSmsSupportLink,
|
depositSmsSupportLink,
|
||||||
depositQuickAmounts,
|
depositQuickAmounts,
|
||||||
isBazretalaProject,
|
|
||||||
usePriceWithoutType,
|
usePriceWithoutType,
|
||||||
formatCashWalletBalanceText,
|
formatCashWalletBalanceText,
|
||||||
setIsDeposit,
|
setIsDeposit,
|
||||||
|
|||||||
@@ -55,9 +55,6 @@
|
|||||||
|
|
||||||
<Transition mode="out-in" name="fade">
|
<Transition mode="out-in" name="fade">
|
||||||
<div v-if="!isDeposit" key="withdraw" class="dwallet-form__extras">
|
<div v-if="!isDeposit" key="withdraw" class="dwallet-form__extras">
|
||||||
<p v-if="!isBoursecu" class="dwallet-form__hint dwallet-form__hint--warn">
|
|
||||||
حداقل مبلغ برداشتی 100 هزار تومان می باشد.
|
|
||||||
</p>
|
|
||||||
<p class="dwallet-form__balance-text">
|
<p class="dwallet-form__balance-text">
|
||||||
{{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }}
|
{{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }}
|
||||||
</p>
|
</p>
|
||||||
@@ -81,7 +78,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div v-else key="deposit" class="dwallet-form__extras">
|
<div v-else key="deposit" class="dwallet-form__extras">
|
||||||
<p v-if="!isBazretalaProject()" class="dwallet-form__hint dwallet-form__hint--warn">
|
<p class="dwallet-form__hint dwallet-form__hint--warn">
|
||||||
حداقل مبلغ واریزی 100 هزار تومان می باشد.
|
حداقل مبلغ واریزی 100 هزار تومان می باشد.
|
||||||
</p>
|
</p>
|
||||||
<div class="dwallet-quick-amounts">
|
<div class="dwallet-quick-amounts">
|
||||||
@@ -108,7 +105,7 @@
|
|||||||
<span v-else>{{ isDeposit ? 'واریز' : 'برداشت' }}</span>
|
<span v-else>{{ isDeposit ? 'واریز' : 'برداشت' }}</span>
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
|
|
||||||
<BoursecuWithdrawGuide v-if="!isDeposit && isBoursecu" />
|
<BoursecuWithdrawGuide v-if="!isDeposit" />
|
||||||
</a-form>
|
</a-form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -136,53 +133,34 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="dwallet-side__header">
|
<div class="dwallet-side__header">
|
||||||
<h3 class="dwallet-side__title">{{ isBoursecu ? 'حسابهای بانکی' : 'کارتهای بانکی' }}</h3>
|
<h3 class="dwallet-side__title">حسابهای بانکی</h3>
|
||||||
<button
|
<button
|
||||||
v-if="isBoursecu"
|
|
||||||
type="button"
|
type="button"
|
||||||
class="dwallet-side__add-link"
|
class="dwallet-side__add-link"
|
||||||
@click="showAddCard = true"
|
@click="showAddCard = true"
|
||||||
>
|
>
|
||||||
+ افزودن شبا
|
+ افزودن شبا
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
v-else
|
|
||||||
type="button"
|
|
||||||
class="dwallet-side__add-btn"
|
|
||||||
@click="showAddCard = true"
|
|
||||||
>
|
|
||||||
<BasicIcon icon="vuesax-linear:add" size="16" />
|
|
||||||
<span>افزودن کارت</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p v-if="isBoursecu && cardItems.length > 0" class="dwallet-side__subtitle">واریز به</p>
|
<p v-if="cardItems.length > 0" class="dwallet-side__subtitle">واریز به</p>
|
||||||
|
|
||||||
<div v-if="!loading && cardItems.length === 0" class="dwallet-side__empty dwallet-side__empty--cards">
|
<div v-if="!loading && cardItems.length === 0" class="dwallet-side__empty dwallet-side__empty--cards">
|
||||||
<BasicIcon icon="vuesax-linear:card" size="32" />
|
<BasicIcon icon="vuesax-linear:card" size="32" />
|
||||||
<p>هیچ کارتی یافت نشد</p>
|
<p>هیچ کارتی یافت نشد</p>
|
||||||
<button type="button" class="dwallet-side__add-btn dwallet-side__add-btn--primary" @click="showAddCard = true">
|
<button type="button" class="dwallet-side__add-btn dwallet-side__add-btn--primary" @click="showAddCard = true">
|
||||||
{{ isBoursecu ? 'افزودن شبا' : 'افزودن کارت جدید' }}
|
افزودن شبا
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BoursecuBankAccountPicker
|
<BoursecuBankAccountPicker
|
||||||
v-else-if="isBoursecu"
|
v-else
|
||||||
v-model:id="form.card_id"
|
v-model:id="form.card_id"
|
||||||
variant="desktop"
|
variant="desktop"
|
||||||
:items="cardItems"
|
:items="cardItems"
|
||||||
@add-account="showAddCard = true"
|
@add-account="showAddCard = true"
|
||||||
@card-deleted="getCards"
|
@card-deleted="getCards"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div v-else-if="cardItems.length > 0" class="dwallet-cards">
|
|
||||||
<CardSlider
|
|
||||||
v-model:id="form.card_id"
|
|
||||||
:items="cardItems"
|
|
||||||
class="dwallet-cards__slider"
|
|
||||||
@cardDeleted="getCards"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,15 +177,11 @@ import ListAnim from '@/components/ListAnim.vue'
|
|||||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||||
import { useConfigStore } from '@/store/configStore'
|
import { useConfigStore } from '@/store/configStore'
|
||||||
import { required } from '@/utils/inputRules'
|
import { required } from '@/utils/inputRules'
|
||||||
import CardSlider from '../components/UISlider/index.vue'
|
|
||||||
import BoursecuBankAccountPicker from '../components/BoursecuBankAccountPicker.vue'
|
import BoursecuBankAccountPicker from '../components/BoursecuBankAccountPicker.vue'
|
||||||
import BoursecuWithdrawGuide from '../components/BoursecuWithdrawGuide.vue'
|
import BoursecuWithdrawGuide from '../components/BoursecuWithdrawGuide.vue'
|
||||||
import Item from '../components/Item.vue'
|
import Item from '../components/Item.vue'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { useWalletPageContext } from '../composables/useWalletPage'
|
import { useWalletPageContext } from '../composables/useWalletPage'
|
||||||
|
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isDeposit,
|
isDeposit,
|
||||||
walletStore,
|
walletStore,
|
||||||
@@ -220,7 +194,6 @@ const {
|
|||||||
loadingMore,
|
loadingMore,
|
||||||
desktopDepositScrollEl,
|
desktopDepositScrollEl,
|
||||||
depositQuickAmounts,
|
depositQuickAmounts,
|
||||||
isBazretalaProject,
|
|
||||||
usePriceWithoutType,
|
usePriceWithoutType,
|
||||||
formatCashWalletBalanceText,
|
formatCashWalletBalanceText,
|
||||||
setIsDeposit,
|
setIsDeposit,
|
||||||
|
|||||||
@@ -83,22 +83,7 @@
|
|||||||
:support-link="depositGuideSupportLink"
|
:support-link="depositGuideSupportLink"
|
||||||
:sms-link="depositSmsSupportLink"
|
:sms-link="depositSmsSupportLink"
|
||||||
>
|
>
|
||||||
<template v-if="config.config.name === 'garoosi'">
|
<template>
|
||||||
<p>جهت شارژ حساب کاربری خود، مبلغ موردنظر را به شماره کارت زیر واریز نموده و از طریق لینک زیر به پشتیبان اطلاع دهید.</p>
|
|
||||||
<p class="deposit-guide-note deposit-guide-note--warn">در صورت عدم همخوانی کارت ملی و فیش واریزی کیف پول شارژ نمیشود!</p>
|
|
||||||
<p class="deposit-guide-note">(سیده زهرا موسوی)</p>
|
|
||||||
<p class="deposit-guide-note">شماره کارت: 6037701900311389</p>
|
|
||||||
<p class="deposit-guide-note">شماره شبا: IR 080160000000001143804581</p>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else-if="isBazretalaProject()">
|
|
||||||
<p>جهت شارژ حساب کاربری خود، مبلغ موردنظر را به شماره کارت زیر واریز نموده و به شماره پشتیبانی 09121784258 در برنامه بله اطلاع دهید.</p>
|
|
||||||
<p class="deposit-guide-note">(گنجينه طلاي حاجي ابوالفتح - بانک ملی)</p>
|
|
||||||
<p class="deposit-guide-note">شماره کارت: 6037998800496928</p>
|
|
||||||
<p class="deposit-guide-note">شماره شبا: IR 110170000000372468150002</p>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else>
|
|
||||||
<p>{{ supportMessengerText }}</p>
|
<p>{{ supportMessengerText }}</p>
|
||||||
</template>
|
</template>
|
||||||
</WalletDepositGuideModal>
|
</WalletDepositGuideModal>
|
||||||
@@ -138,7 +123,6 @@ import WalletDepositGuideModal from './components/WalletDepositGuideModal.vue'
|
|||||||
const isDesktop = useDesktopBreakpoint()
|
const isDesktop = useDesktopBreakpoint()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
config,
|
|
||||||
showAddCard,
|
showAddCard,
|
||||||
chargeAccountModal,
|
chargeAccountModal,
|
||||||
showConfirmCode,
|
showConfirmCode,
|
||||||
@@ -149,7 +133,6 @@ const {
|
|||||||
supportMessengerText,
|
supportMessengerText,
|
||||||
depositGuideSupportLink,
|
depositGuideSupportLink,
|
||||||
depositSmsSupportLink,
|
depositSmsSupportLink,
|
||||||
isBazretalaProject,
|
|
||||||
handleOnComplete,
|
handleOnComplete,
|
||||||
loading,
|
loading,
|
||||||
addCard,
|
addCard,
|
||||||
|
|||||||
@@ -30,11 +30,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="px-5 mpage-content mpage-content--with-subheader"
|
class="px-5 mpage-content mpage-content--with-subheader"
|
||||||
:class="isDeposit ? 'pb-2' : isBoursecu ? 'pb-[calc(var(--app-bottom-chrome-height)+1rem)]' : 'pb-[calc(var(--app-bottom-chrome-height)+var(--app-add-card-height)+1rem)]'"
|
:class="isDeposit ? 'pb-2' : 'pb-[calc(var(--app-bottom-chrome-height)+1rem)]'"
|
||||||
>
|
>
|
||||||
<a-form :model="form" class="!mt-5" name="basic" @finish="ok()">
|
<a-form :model="form" class="!mt-5" name="basic" @finish="ok()">
|
||||||
<BoursecuBankAccountPicker
|
<BoursecuBankAccountPicker
|
||||||
v-if="!isDeposit && isBoursecu"
|
v-if="!isDeposit"
|
||||||
v-model:id="form.card_id"
|
v-model:id="form.card_id"
|
||||||
variant="mobile"
|
variant="mobile"
|
||||||
:items="cardItems"
|
:items="cardItems"
|
||||||
@@ -59,9 +59,6 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
<Transition mode="out-in" name="fade">
|
<Transition mode="out-in" name="fade">
|
||||||
<div v-if="!isDeposit">
|
<div v-if="!isDeposit">
|
||||||
<div v-if="!isBoursecu" class="text-red text-xs font-bold mb-2">
|
|
||||||
حداقل مبلغ برداشتی 100 هزار تومان می باشد.
|
|
||||||
</div>
|
|
||||||
<div class="font-bold text-xs">
|
<div class="font-bold text-xs">
|
||||||
{{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }}
|
{{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }}
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +82,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mt-3">
|
<div v-else class="mt-3">
|
||||||
<div v-if="!isBazretalaProject()" class="text-red text-xs font-bold mb-2">
|
<div class="text-red text-xs font-bold mb-2">
|
||||||
حداقل مبلغ واریزی 100 هزار تومان می باشد.
|
حداقل مبلغ واریزی 100 هزار تومان می باشد.
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@@ -118,7 +115,7 @@
|
|||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!isDeposit && isBoursecu"
|
v-if="!isDeposit"
|
||||||
class="wallet-withdraw-guide-panel relative z-10"
|
class="wallet-withdraw-guide-panel relative z-10"
|
||||||
>
|
>
|
||||||
<BoursecuWithdrawGuide />
|
<BoursecuWithdrawGuide />
|
||||||
@@ -137,44 +134,12 @@
|
|||||||
</list-anim>
|
</list-anim>
|
||||||
<TransactionSkeleton v-for="i in 13" v-else :key="i" class="mt-1" />
|
<TransactionSkeleton v-for="i in 13" v-else :key="i" class="mt-1" />
|
||||||
</div>
|
</div>
|
||||||
<Transition mode="out-in" name="fade">
|
|
||||||
<template v-if="!isDeposit">
|
|
||||||
<div
|
|
||||||
v-if="!loading && cardItems.length === 0 && !isBoursecu"
|
|
||||||
class="h-30 flex items-center justify-center"
|
|
||||||
>
|
|
||||||
هیچ کارتی یافت نشد
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Teleport to="body">
|
|
||||||
<CardSlider
|
|
||||||
v-if="!isDeposit && !isBoursecu && cardItems.length > 0 && !showAddCard"
|
|
||||||
v-model:id="form.card_id"
|
|
||||||
:items="cardItems"
|
|
||||||
class="card-slider-wrap wallet-card-slider"
|
|
||||||
@cardDeleted="getCards"
|
|
||||||
/>
|
|
||||||
</Teleport>
|
|
||||||
|
|
||||||
<Teleport to="body">
|
|
||||||
<div
|
|
||||||
v-if="!isDeposit && !isBoursecu && !showAddCard"
|
|
||||||
class="add-card app-dock-add-bar"
|
|
||||||
@click="showAddCard = true"
|
|
||||||
>
|
|
||||||
<div>افزودن کارت جدید</div>
|
|
||||||
<BasicIcon icon="vuesax-linear:add" />
|
|
||||||
</div>
|
|
||||||
</Teleport>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
|
||||||
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
|
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
|
||||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||||
import Bg_main from '@/components/bg_main.vue'
|
import Bg_main from '@/components/bg_main.vue'
|
||||||
@@ -183,15 +148,11 @@ import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
|||||||
import { useConfigStore } from '@/store/configStore'
|
import { useConfigStore } from '@/store/configStore'
|
||||||
import { required } from '@/utils/inputRules'
|
import { required } from '@/utils/inputRules'
|
||||||
import img from '@/assets/img/user_ly1.svg'
|
import img from '@/assets/img/user_ly1.svg'
|
||||||
import CardSlider from '../components/UISlider/index.vue'
|
|
||||||
import BoursecuBankAccountPicker from '../components/BoursecuBankAccountPicker.vue'
|
import BoursecuBankAccountPicker from '../components/BoursecuBankAccountPicker.vue'
|
||||||
import BoursecuWithdrawGuide from '../components/BoursecuWithdrawGuide.vue'
|
import BoursecuWithdrawGuide from '../components/BoursecuWithdrawGuide.vue'
|
||||||
import Item from '../components/Item.vue'
|
import Item from '../components/Item.vue'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { useWalletPageContext } from '../composables/useWalletPage'
|
import { useWalletPageContext } from '../composables/useWalletPage'
|
||||||
|
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isDeposit,
|
isDeposit,
|
||||||
walletStore,
|
walletStore,
|
||||||
@@ -204,7 +165,6 @@ const {
|
|||||||
loadingMore,
|
loadingMore,
|
||||||
mobileDepositScrollEl,
|
mobileDepositScrollEl,
|
||||||
depositQuickAmounts,
|
depositQuickAmounts,
|
||||||
isBazretalaProject,
|
|
||||||
usePriceWithoutType,
|
usePriceWithoutType,
|
||||||
formatCashWalletBalanceText,
|
formatCashWalletBalanceText,
|
||||||
setIsDeposit,
|
setIsDeposit,
|
||||||
|
|||||||
@@ -23,10 +23,7 @@
|
|||||||
:src="getProjectLoginLogo(config.config?.avatar)"
|
:src="getProjectLoginLogo(config.config?.avatar)"
|
||||||
alt=""
|
alt=""
|
||||||
:class="[
|
:class="[
|
||||||
'z-100 self-center w-36',
|
'z-100 self-center w-36 rounded aspect-square',
|
||||||
config.config?.name === 'garoosi'
|
|
||||||
? 'h-auto object-contain'
|
|
||||||
: 'rounded aspect-square',
|
|
||||||
]"
|
]"
|
||||||
style="margin-bottom: 60px"
|
style="margin-bottom: 60px"
|
||||||
>
|
>
|
||||||
@@ -190,27 +187,7 @@
|
|||||||
ورود با اثر انگشت
|
ورود با اثر انگشت
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
|
|
||||||
<template v-if="config.config?.name === 'garoosi'">
|
<div v-if="!isTWA() && !!setting.getSettingByKey('apk_download_link')" class="mt-1">
|
||||||
<div v-if="!isTWA()" class="dauth-actions-row">
|
|
||||||
<a
|
|
||||||
class="dauth-link-btn dauth-link-btn--primary"
|
|
||||||
download="Garoosi.apk"
|
|
||||||
href="https://garoosigholaktala.ir/apk/Garoosi.apk"
|
|
||||||
>
|
|
||||||
دانلود اپ اندروید
|
|
||||||
</a>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="installWebApp">
|
|
||||||
نصب نسخه وب اپ
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToEducate">
|
|
||||||
آموزش کار با نرم افزار
|
|
||||||
</button>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToAboutUs">
|
|
||||||
درباره ما
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<div v-else-if="!isTWA() && !!setting.getSettingByKey('apk_download_link')" class="mt-1">
|
|
||||||
<a
|
<a
|
||||||
class="dauth-link-btn dauth-link-btn--primary !hover:text-primary "
|
class="dauth-link-btn dauth-link-btn--primary !hover:text-primary "
|
||||||
:href="setting.getSettingByKey('apk_download_link')"
|
:href="setting.getSettingByKey('apk_download_link')"
|
||||||
@@ -254,29 +231,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
|
|
||||||
<template v-if="config.config?.name === 'garoosi'">
|
<div v-if="!isTWA() && !!setting.getSettingByKey('apk_download_link')" class=" mt-1">
|
||||||
<div v-if="!isTWA()" class="flex w-full gap-2 mt-2">
|
|
||||||
<a
|
|
||||||
class="flex w-full items-center justify-center rounded py-2 text-white bg-primary border-none cursor-pointer no-underline"
|
|
||||||
download="Garoosi.apk"
|
|
||||||
href="https://garoosigholaktala.ir/apk/Garoosi.apk"
|
|
||||||
>
|
|
||||||
<div>دانلود اپ اندروید</div>
|
|
||||||
</a>
|
|
||||||
<BasicButton type="primary" class="w-full" @click="installWebApp">
|
|
||||||
<div>نصب نسخه وب اپ</div>
|
|
||||||
</BasicButton>
|
|
||||||
</div>
|
|
||||||
<BasicButton class="w-full !font-bold mt-2" @click="goToEducate">
|
|
||||||
<div class="flex gap-2 items-center">آموزش کار با نرم افزار</div>
|
|
||||||
</BasicButton>
|
|
||||||
<BasicButton class="mt-2 w-full" icon="" iconSize="18" @click="goToAboutUs">
|
|
||||||
<div class="flex">
|
|
||||||
<div>درباره ما</div>
|
|
||||||
</div>
|
|
||||||
</BasicButton>
|
|
||||||
</template>
|
|
||||||
<div v-else-if="!isTWA() && !!setting.getSettingByKey('apk_download_link')" class=" mt-1">
|
|
||||||
<a
|
<a
|
||||||
class="dauth-link-btn dauth-link-btn--primary !hover:text-primary "
|
class="dauth-link-btn dauth-link-btn--primary !hover:text-primary "
|
||||||
:href="setting.getSettingByKey('apk_download_link')"
|
:href="setting.getSettingByKey('apk_download_link')"
|
||||||
@@ -294,9 +249,6 @@
|
|||||||
ثبت نام کنید.
|
ثبت نام کنید.
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- <BasicButton v-if="config.config.name === 'garoosi'" class="w-full !font-bold" @click="goToEducate">
|
|
||||||
<div class="flex gap-2 items-center">آموزش کار با نرم افزار</div>
|
|
||||||
</BasicButton>-->
|
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<!-- <div v-if="URLUserType() === 'single'" class="fixed bottom-5 left-0 right-0 text-center">
|
<!-- <div v-if="URLUserType() === 'single'" class="fixed bottom-5 left-0 right-0 text-center">
|
||||||
|
|||||||
@@ -22,12 +22,7 @@
|
|||||||
v-else-if="variant !== 'desktop'"
|
v-else-if="variant !== 'desktop'"
|
||||||
:src="getProjectLoginLogo(config.config?.avatar)"
|
:src="getProjectLoginLogo(config.config?.avatar)"
|
||||||
alt=""
|
alt=""
|
||||||
:class="[
|
class="z-100 self-center w-36 rounded aspect-square"
|
||||||
'z-100 self-center w-36',
|
|
||||||
config.config?.name === 'garoosi'
|
|
||||||
? 'h-auto object-contain mb-[60px]'
|
|
||||||
: 'rounded aspect-square',
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<div v-if="variant !== 'desktop'" class="font-bold text-center text-xl">ثبت نام</div>
|
<div v-if="variant !== 'desktop'" class="font-bold text-center text-xl">ثبت نام</div>
|
||||||
<a-form
|
<a-form
|
||||||
@@ -104,14 +99,6 @@
|
|||||||
<a-spin v-if="loading" size="small" />
|
<a-spin v-if="loading" size="small" />
|
||||||
<span v-else>ثبت نام</span>
|
<span v-else>ثبت نام</span>
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
<template v-if="config.config?.name === 'garoosi'">
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToEducate">
|
|
||||||
آموزش کار با نرم افزار
|
|
||||||
</button>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToAboutUs">
|
|
||||||
درباره ما
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="variant === 'desktop'" class="dauth-switch">
|
<div v-if="variant === 'desktop'" class="dauth-switch">
|
||||||
@@ -133,16 +120,6 @@
|
|||||||
<div v-else>ثبت نام</div>
|
<div v-else>ثبت نام</div>
|
||||||
</div>
|
</div>
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
<template v-if="config.config?.name === 'garoosi'">
|
|
||||||
<BasicButton class="w-full mt-2 !font-bold" @click="goToEducate">
|
|
||||||
<div class="flex gap-2 items-center">آموزش کار با نرم افزار</div>
|
|
||||||
</BasicButton>
|
|
||||||
<BasicButton class="mt-2 w-full" icon="" iconSize="18" @click="goToAboutUs">
|
|
||||||
<div class="flex">
|
|
||||||
<div>درباره ما</div>
|
|
||||||
</div>
|
|
||||||
</BasicButton>
|
|
||||||
</template>
|
|
||||||
<div
|
<div
|
||||||
class="cursor-pointer flex gap-1 justify-center mt-5 text-xs"
|
class="cursor-pointer flex gap-1 justify-center mt-5 text-xs"
|
||||||
@click="$emit('register', false)"
|
@click="$emit('register', false)"
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dauth" :class="{ 'dauth--boursecu': isBoursecu }">
|
<div class="dauth dauth--boursecu">
|
||||||
<div class="dauth__layout">
|
<div class="dauth__layout">
|
||||||
<aside
|
<aside class="dauth-brand dauth-brand--boursecu">
|
||||||
class="dauth-brand"
|
|
||||||
:class="{
|
|
||||||
'dauth-brand--boursecu': isBoursecu,
|
|
||||||
'dauth-brand--soroushgold': isSoroushgold,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div class="dauth-brand__pattern" />
|
<div class="dauth-brand__pattern" />
|
||||||
<div class="dauth-brand__content">
|
<div class="dauth-brand__content">
|
||||||
<img
|
<img
|
||||||
:src="logo"
|
:src="logo"
|
||||||
alt=""
|
alt=""
|
||||||
class="dauth-brand__logo"
|
class="dauth-brand__logo"
|
||||||
:class="{ 'dauth-brand__logo--round': !hasCustomLayout }"
|
|
||||||
>
|
>
|
||||||
<h1 class="dauth-brand__title">{{ brandTitle }}</h1>
|
<h1 class="dauth-brand__title">{{ brandTitle }}</h1>
|
||||||
<p v-if="tagline" class="dauth-brand__tagline">{{ tagline }}</p>
|
<p v-if="tagline" class="dauth-brand__tagline">{{ tagline }}</p>
|
||||||
@@ -46,15 +39,9 @@ import { useConfigStore } from '@/store/configStore'
|
|||||||
import {
|
import {
|
||||||
getProjectDesktopLoginBrandLogo,
|
getProjectDesktopLoginBrandLogo,
|
||||||
getProjectLoginTaglineLines,
|
getProjectLoginTaglineLines,
|
||||||
hasCustomLoginLogoLayout,
|
|
||||||
isBoursecuProject,
|
|
||||||
isSoroushgoldProject,
|
|
||||||
} from '@/utils/config'
|
} from '@/utils/config'
|
||||||
|
|
||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
const isSoroushgold = isSoroushgoldProject()
|
|
||||||
const hasCustomLayout = hasCustomLoginLogoLayout() || isSoroushgold
|
|
||||||
const version = getDisplayAppVersion(pkg.version)
|
const version = getDisplayAppVersion(pkg.version)
|
||||||
|
|
||||||
const logo = computed(() => getProjectDesktopLoginBrandLogo(config.config?.avatar))
|
const logo = computed(() => getProjectDesktopLoginBrandLogo(config.config?.avatar))
|
||||||
@@ -69,20 +56,11 @@ const tagline = computed(() => {
|
|||||||
|
|
||||||
const brandTitle = computed(() => config.config?.name_fa ?? 'خوش آمدید')
|
const brandTitle = computed(() => config.config?.name_fa ?? 'خوش آمدید')
|
||||||
|
|
||||||
const features = computed(() => {
|
const features = [
|
||||||
if (isBoursecu) {
|
'قیمت لحظهای و نمودار بازار',
|
||||||
return [
|
'مدیریت دارایی و کیف پول',
|
||||||
'قیمت لحظهای و نمودار بازار',
|
'معاملات سریع و امن',
|
||||||
'مدیریت دارایی و کیف پول',
|
]
|
||||||
'معاملات سریع و امن',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
'ورود امن با پیامک یا رمز عبور',
|
|
||||||
'مدیریت یکپارچه داراییها',
|
|
||||||
'دسترسی سریع به خدمات',
|
|
||||||
]
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" src="../styles/desktop-auth.less"></style>
|
<style lang="less" src="../styles/desktop-auth.less"></style>
|
||||||
|
|||||||
@@ -173,27 +173,7 @@ function goToAboutUs() {
|
|||||||
ورود با اثر انگشت
|
ورود با اثر انگشت
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
|
|
||||||
<template v-if="config.config?.name === 'garoosi'">
|
<div v-if="!isTWA() && !!setting.getSettingByKey('apk_download_link')" class="dauth-actions-row ">
|
||||||
<div v-if="!isTWA()" class="dauth-actions-row">
|
|
||||||
<a
|
|
||||||
class="dauth-link-btn dauth-link-btn--primary"
|
|
||||||
download="Garoosi.apk"
|
|
||||||
href="https://garoosigholaktala.ir/apk/Garoosi.apk"
|
|
||||||
>
|
|
||||||
دانلود اپ اندروید
|
|
||||||
</a>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="installWebApp">
|
|
||||||
نصب نسخه وب اپ
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToEducate">
|
|
||||||
آموزش کار با نرم افزار
|
|
||||||
</button>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToAboutUs">
|
|
||||||
درباره ما
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<div v-else-if="!isTWA() && !!setting.getSettingByKey('apk_download_link')" class="dauth-actions-row ">
|
|
||||||
<a
|
<a
|
||||||
class="dauth-link-btn dauth-link-btn--primary !hover:text-primary "
|
class="dauth-link-btn dauth-link-btn--primary !hover:text-primary "
|
||||||
:href="setting.getSettingByKey('apk_download_link')"
|
:href="setting.getSettingByKey('apk_download_link')"
|
||||||
|
|||||||
@@ -114,15 +114,6 @@ function handleSuccessDismiss() {
|
|||||||
<a-spin v-if="loading" size="small" />
|
<a-spin v-if="loading" size="small" />
|
||||||
<span v-else>ثبت نام</span>
|
<span v-else>ثبت نام</span>
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
|
|
||||||
<template v-if="config.config?.name === 'garoosi'">
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToEducate">
|
|
||||||
آموزش کار با نرم افزار
|
|
||||||
</button>
|
|
||||||
<button type="button" class="dauth-link-btn" @click="goToAboutUs">
|
|
||||||
درباره ما
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dauth-switch">
|
<div class="dauth-switch">
|
||||||
|
|||||||
@@ -21,58 +21,23 @@
|
|||||||
|
|
||||||
<!-- Mobile: original layout -->
|
<!-- Mobile: original layout -->
|
||||||
<div v-show="!isDesktop" class="login-page flex flex-col items-center">
|
<div v-show="!isDesktop" class="login-page flex flex-col items-center">
|
||||||
<template v-if="!isBoursecu">
|
|
||||||
<div class="fixed top-0 right-0 left-0 h-1/3 w-screen flex">
|
|
||||||
<img :src="img_topGradiant" alt="" class="absolute z-10 w-screen h-full object-cover" />
|
|
||||||
<img :src="img_pattern" alt="" class="absolute w-screen h-full object-none" />
|
|
||||||
</div>
|
|
||||||
<div class="fixed bottom-0 right-0 left-0 h-1/3 w-screen">
|
|
||||||
<img :src="img_bottomGradiant" alt="" class="absolute z-10 w-screen h-full object-cover" />
|
|
||||||
<img :src="img_pattern" alt="" class="absolute w-screen h-full object-none" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="login-page__content z-1000 w-full p-5">
|
<div class="login-page__content z-1000 w-full p-5">
|
||||||
<Login v-if="!loginPage.enterType" @register="loginPage.setEnterType" />
|
<Login v-if="!loginPage.enterType" @register="loginPage.setEnterType" />
|
||||||
<Register v-else @register="loginPage.setEnterType" />
|
<Register v-else @register="loginPage.setEnterType" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isGaroosi" class="login-page__enamad z-1000">
|
|
||||||
<a
|
|
||||||
referrerpolicy="origin"
|
|
||||||
target="_blank"
|
|
||||||
href="https://trustseal.enamad.ir/?id=710578&Code=DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
referrerpolicy="origin"
|
|
||||||
src="https://trustseal.enamad.ir/logo.aspx?id=710578&Code=DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
|
|
||||||
alt="enamad"
|
|
||||||
style="cursor: pointer"
|
|
||||||
code="DdltBYWJgvc7LJs9eM46SEliXRRU0kSW"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
|
||||||
import { useLoginPage } from './composables/useLoginPage'
|
import { useLoginPage } from './composables/useLoginPage'
|
||||||
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import { useConfigStore } from '@/store/configStore'
|
|
||||||
import Login from './components/Login.vue'
|
import Login from './components/Login.vue'
|
||||||
import Register from './components/Register.vue'
|
import Register from './components/Register.vue'
|
||||||
import DesktopAuthShell from './desktop/components/DesktopAuthShell.vue'
|
import DesktopAuthShell from './desktop/components/DesktopAuthShell.vue'
|
||||||
import img_topGradiant from './assets/img/gr_top_white.svg'
|
|
||||||
import img_bottomGradiant from './assets/img/gr_bottom_white.svg'
|
|
||||||
import img_pattern from './assets/img/pattern.svg'
|
|
||||||
|
|
||||||
const isDesktop = useDesktopBreakpoint()
|
const isDesktop = useDesktopBreakpoint()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
const loginPage = useLoginPage()
|
const loginPage = useLoginPage()
|
||||||
const config = useConfigStore()
|
|
||||||
const isGaroosi = computed(() => config.config?.name === 'garoosi')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -98,16 +63,4 @@ const isGaroosi = computed(() => config.config?.name === 'garoosi')
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-page__enamad {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 20px 16px;
|
|
||||||
margin-top: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-page__enamad img {
|
|
||||||
max-width: 96px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login-page flex items-center justify-center">
|
<div class="login-page flex items-center justify-center">
|
||||||
<template v-if="!isBoursecu">
|
|
||||||
<div class="fixed top-0 right-0 left-0 h-1/3 w-screen flex">
|
|
||||||
<img :src="img_topGradiant" alt="" class="absolute z-10 w-screen h-full object-cover" />
|
|
||||||
<img :src="img_pattern" alt="" class="absolute w-screen h-full object-none" />
|
|
||||||
</div>
|
|
||||||
<div class="fixed bottom-0 right-0 left-0 h-1/3 w-screen">
|
|
||||||
<img :src="img_bottomGradiant" alt="" class="absolute z-10 w-screen h-full object-cover" />
|
|
||||||
<img :src="img_pattern" alt="" class="absolute w-screen h-full object-none" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="z-1000 w-full p-5">
|
<div class="z-1000 w-full p-5">
|
||||||
<Login v-if="!page.enterType" key="login" @register="page.setEnterType" />
|
<Login v-if="!page.enterType" key="login" @register="page.setEnterType" />
|
||||||
<Register v-else key="register" @register="page.setEnterType" />
|
<Register v-else key="register" @register="page.setEnterType" />
|
||||||
@@ -21,13 +11,8 @@
|
|||||||
import Login from '../components/Login.vue'
|
import Login from '../components/Login.vue'
|
||||||
import Register from '../components/Register.vue'
|
import Register from '../components/Register.vue'
|
||||||
import { useLoginPageContext } from '../composables/useLoginPage'
|
import { useLoginPageContext } from '../composables/useLoginPage'
|
||||||
import { isBoursecuProject } from '@/utils/config'
|
|
||||||
import img_topGradiant from '../assets/img/gr_top_white.svg'
|
|
||||||
import img_bottomGradiant from '../assets/img/gr_bottom_white.svg'
|
|
||||||
import img_pattern from '../assets/img/pattern.svg'
|
|
||||||
|
|
||||||
const page = useLoginPageContext()
|
const page = useLoginPageContext()
|
||||||
const isBoursecu = isBoursecuProject()
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user