feat(convert,assets): convert page route and assets portfolio chart
Add convert mobile/desktop views and assets chart from price history; polish calculator and wallet/home integration. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { computed, ref, watch, type ComputedRef } from 'vue'
|
||||
import {
|
||||
fetchZaanboxPriceHistory,
|
||||
type LandingHistoryRange,
|
||||
} from '@/api/zaarboxPriceHistory'
|
||||
import { buildSeriesChartPaths } from '@/utils/chartAreaPaths'
|
||||
const CHART_RANGE_OPTIONS = [
|
||||
{ value: 'DAILY' as const, shortLabel: '۲۴ ساعت', label: 'ارزش دارایی — ۲۴ ساعت گذشته' },
|
||||
{ value: 'WEEKLY' as const, shortLabel: 'هفته', label: 'ارزش دارایی — هفته گذشته' },
|
||||
{ value: 'MONTHLY' as const, shortLabel: 'ماه', label: 'ارزش دارایی — ماه گذشته' },
|
||||
]
|
||||
|
||||
export function useAssetsPortfolioChart(
|
||||
cashRial: ComputedRef<number>,
|
||||
metalRial: ComputedRef<number>,
|
||||
) {
|
||||
const chartRange = ref<LandingHistoryRange>('MONTHLY')
|
||||
const chartDrawn = ref(false)
|
||||
const chartLoading = ref(false)
|
||||
const priceHistory = ref<Array<{ timeMs: number; price: number }>>([])
|
||||
|
||||
async function loadChartHistory(range: LandingHistoryRange) {
|
||||
chartLoading.value = true
|
||||
try {
|
||||
priceHistory.value = await fetchZaanboxPriceHistory(range)
|
||||
} catch {
|
||||
priceHistory.value = []
|
||||
} finally {
|
||||
chartLoading.value = false
|
||||
chartDrawn.value = true
|
||||
}
|
||||
}
|
||||
|
||||
function setChartRange(range: LandingHistoryRange) {
|
||||
chartRange.value = range
|
||||
void loadChartHistory(range)
|
||||
}
|
||||
|
||||
const portfolioSeries = computed(() => {
|
||||
const cash = Math.max(0, cashRial.value)
|
||||
const metal = Math.max(0, metalRial.value)
|
||||
const prices = priceHistory.value
|
||||
|
||||
if (prices.length < 2) {
|
||||
const total = cash + metal
|
||||
if (total <= 0) return []
|
||||
return prices.map((point) => ({ timeMs: point.timeMs, value: total }))
|
||||
}
|
||||
|
||||
const refPrice = prices[prices.length - 1]?.price
|
||||
if (!refPrice || metal <= 0) {
|
||||
const total = cash + metal
|
||||
return prices.map((point) => ({ timeMs: point.timeMs, value: total }))
|
||||
}
|
||||
|
||||
return prices.map((point) => ({
|
||||
timeMs: point.timeMs,
|
||||
value: Math.round(cash + metal * (point.price / refPrice)),
|
||||
}))
|
||||
})
|
||||
|
||||
const portfolioChart = computed(() => buildSeriesChartPaths(portfolioSeries.value))
|
||||
|
||||
watch(
|
||||
() => cashRial.value + metalRial.value,
|
||||
(total) => {
|
||||
if (total > 0 && priceHistory.value.length === 0) {
|
||||
void loadChartHistory(chartRange.value)
|
||||
}
|
||||
},
|
||||
{ flush: 'post' },
|
||||
)
|
||||
|
||||
async function initAssetsPortfolioChart() {
|
||||
await loadChartHistory(chartRange.value)
|
||||
}
|
||||
|
||||
return {
|
||||
chartRange,
|
||||
chartRangeOptions: CHART_RANGE_OPTIONS,
|
||||
chartDrawn,
|
||||
chartLoading,
|
||||
portfolioChart,
|
||||
setChartRange,
|
||||
initAssetsPortfolioChart,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user