131 lines
3.7 KiB
Vue
131 lines
3.7 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
|
import { usePriceWithoutType } from '@/utils/usePrice'
|
|
import { useWalletAssets } from '@/composables/useWalletAssets'
|
|
import type { WalletMetalTotal } from '@/models/walletAssets'
|
|
import { buildBoursecuHomeAssetRows, resolveSummaryMetalWeight } from '@/utils/productAssets'
|
|
import { useHomePageContext } from '../../composables/useHomePage'
|
|
|
|
const emit = defineEmits<{
|
|
openGoldModal: [metal: WalletMetalTotal, modalText?: 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 totalRialValue = computed(() => assetsSummary.value?.total_rial_value ?? 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
|
|
modalText?: string
|
|
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 (isBoursecuLayout.value) {
|
|
buildBoursecuHomeAssetRows(assetsSummary.value).forEach((row) => {
|
|
items.push({
|
|
id: row.id,
|
|
label: row.label,
|
|
value: row.value,
|
|
metal: row.metal,
|
|
modalText: row.modalText,
|
|
showInfo: row.info !== 'none',
|
|
onInfo: row.info === 'rial' ? 'rial' : 'gold',
|
|
})
|
|
})
|
|
return items
|
|
}
|
|
|
|
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(totalRialValue.value)} ریال`,
|
|
showInfo: true,
|
|
onInfo: 'rial',
|
|
})
|
|
|
|
return items
|
|
})
|
|
|
|
function formatMetalTotal(metal: WalletMetalTotal) {
|
|
return `${usePriceWithoutType(resolveSummaryMetalWeight(metal, inventoryCards.value), false)}${metal.unit}`
|
|
}
|
|
|
|
function handleInfo(metric: MetricItem) {
|
|
if (metric.onInfo === 'rial') {
|
|
emit('openRialModal')
|
|
return
|
|
}
|
|
if (metric.metal) {
|
|
emit('openGoldModal', metric.metal, metric.modalText)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<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>
|