Replace home chart with landing live card, catalog-driven tabs, and smoother range transitions; normalize مظنه to قیمت in user-facing strings; add installment and zaarbox chart APIs.
162 lines
4.6 KiB
Vue
162 lines
4.6 KiB
Vue
<template>
|
||
<div
|
||
class="dhome-surface dhome-hero-price"
|
||
:class="{
|
||
'dhome-hero-price--boursecu-open': displayState === 'open' || quotePending,
|
||
'dhome-hero-price--boursecu-closed': displayState !== 'open' && !quotePending,
|
||
}"
|
||
>
|
||
<div
|
||
v-if="quotePending"
|
||
class="flex flex-col items-center gap-2 py-4"
|
||
aria-busy="true"
|
||
aria-label="در حال بارگذاری قیمت"
|
||
>
|
||
<div class="h-3 w-24 rounded boursecu-price-skeleton animate-pulse" />
|
||
<div class="h-4 w-32 rounded boursecu-price-skeleton animate-pulse" />
|
||
<div class="h-8 w-40 rounded boursecu-price-skeleton animate-pulse" />
|
||
</div>
|
||
|
||
<template v-else-if="displayState !== 'open'">
|
||
<div class="dhome-hero-price__closed">
|
||
<div class="dhome-hero-price__closed-icon">
|
||
<BasicIcon
|
||
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
||
size="22"
|
||
color="#ffffff"
|
||
/>
|
||
</div>
|
||
<p class="dhome-hero-price__closed-title">{{ statusTitle }}</p>
|
||
<p v-if="statusHint" class="dhome-hero-price__closed-hint">{{ statusHint }}</p>
|
||
</div>
|
||
</template>
|
||
|
||
<template v-else>
|
||
<span class="dhome-label dhome-label--boursecu">
|
||
قیمت لحظهای کاتد مس
|
||
</span>
|
||
<div class="dhome-hero-price__value-row">
|
||
<span
|
||
v-if="percentChange !== 0"
|
||
class="dhome-hero-price__delta"
|
||
:class="percentChange > 0 ? 'dhome-hero-price__delta--up' : 'dhome-hero-price__delta--down'"
|
||
>
|
||
<BasicIcon
|
||
:icon="percentChange > 0 ? 'vuesax-linear:arrow-up-2' : 'vuesax-linear:arrow-down-2'"
|
||
size="14"
|
||
/>
|
||
<span class="dhome-hero-price__delta-value">{{ formatSignedPercentChange(percentChange) }}</span>
|
||
</span>
|
||
<span
|
||
class="dhome-hero-price__odometer o-text dhome-hero-price__odometer--boursecu"
|
||
style="direction: ltr"
|
||
>{{ usePriceWithoutType(displayGoldVal) }}</span>
|
||
<span class="dhome-hero-price__unit dhome-hero-price__unit--boursecu">ریال</span>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed } from 'vue'
|
||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||
import { useUserStore } from '@/store/userStore'
|
||
import { getTradeBuyPrice, lastPrice, percentPriceChanged } from '@/utils/price'
|
||
import {
|
||
NO_QUOTE_MESSAGE,
|
||
STORE_CLOSED_TITLE,
|
||
getPriceDisplayState,
|
||
getStoreClosedHint,
|
||
isHomeQuotePending,
|
||
} from '@/utils/storeHours'
|
||
import { formatSignedPercentChange, usePriceWithoutType } from '@/utils/usePrice'
|
||
|
||
const userStore = useUserStore()
|
||
|
||
const displayState = computed(() => getPriceDisplayState())
|
||
const quotePending = computed(() => isHomeQuotePending())
|
||
|
||
const statusTitle = computed(() =>
|
||
displayState.value === 'closed' ? STORE_CLOSED_TITLE : NO_QUOTE_MESSAGE
|
||
)
|
||
|
||
const statusHint = computed(() => {
|
||
if (displayState.value === 'closed') {
|
||
return getStoreClosedHint(userStore.getValueByKey('closed_message'))
|
||
}
|
||
return 'در حال حاضر قیمتی برای نمایش وجود ندارد.'
|
||
})
|
||
|
||
const displayGoldVal = computed(() => {
|
||
if (displayState.value !== 'open') return 0
|
||
return getTradeBuyPrice(lastPrice.value)
|
||
})
|
||
|
||
const percentChange = computed(() => {
|
||
if (!getTradeBuyPrice(lastPrice.value)) return 0
|
||
return percentPriceChanged()
|
||
})
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.dhome-hero-price--boursecu-open {
|
||
background: linear-gradient(135deg, #c98a4a 0%, #a86528 100%);
|
||
border-color: transparent;
|
||
box-shadow: 0 4px 14px rgba(168, 101, 40, 0.28);
|
||
}
|
||
|
||
.dhome-hero-price--boursecu-closed {
|
||
background: linear-gradient(135deg, #4a5568 0%, #2d3748 100%);
|
||
border-color: transparent;
|
||
box-shadow: 0 4px 14px rgba(45, 55, 72, 0.22);
|
||
}
|
||
|
||
.dhome-label--boursecu {
|
||
color: rgba(255, 255, 255, 0.92);
|
||
}
|
||
|
||
.dhome-hero-price__odometer--boursecu {
|
||
color: #ffffff !important;
|
||
}
|
||
|
||
.dhome-hero-price__unit--boursecu {
|
||
color: rgba(255, 255, 255, 0.85);
|
||
}
|
||
|
||
.boursecu-price-skeleton {
|
||
background: rgba(255, 255, 255, 0.25);
|
||
}
|
||
|
||
.dhome-hero-price__closed {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 6px;
|
||
}
|
||
|
||
.dhome-hero-price__closed-icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 44px;
|
||
height: 44px;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.12);
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.dhome-hero-price__closed-title {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.dhome-hero-price__closed-hint {
|
||
margin: 0;
|
||
font-size: 12px;
|
||
line-height: 1.7;
|
||
color: rgba(255, 255, 255, 0.78);
|
||
}
|
||
</style>
|