Jimin Huang
Change settings
6c34ff7
raw
history blame
2.93 kB
<!-- src/views/LiveView.vue -->
<script setup>
import { ref, computed, onMounted } from 'vue'
import CompareChartE from '../components/CompareChartE.vue'
import AssetTabs from '../components/AssetTabs.vue'
import { dataService } from '../lib/dataService.js'
const ASSETS = ['BTC','ETH','SOL','BNB','DOGE','XRP']
const asset = ref(ASSETS[0])
const agents = ref([])
function score(row){ return typeof row.balance === 'number' ? row.balance : -Infinity }
const winners = computed(() => {
const rows = (agents.value || []).filter(r => r.asset === asset.value)
const byAgent = new Map()
for (const r of rows) {
const k = r.agent_name
const cur = byAgent.get(k)
if (!cur || score(r) > score(cur)) byAgent.set(k, r)
}
return [...byAgent.values()]
})
const winnersForChart = computed(() =>
winners.value.map(w => ({
agent_name: w.agent_name,
asset: w.asset,
model: w.model,
strategy: w.strategy,
decision_ids: Array.isArray(w.decision_ids) ? w.decision_ids : undefined
}))
)
const winnersSorted = computed(() => [...winners.value].sort((a,b) => score(b) - score(a)))
const fmtUSD = n => (n ?? 0).toLocaleString(undefined,{ style:'currency', currency:'USD', maximumFractionDigits:2 })
onMounted(async () => {
try {
// run the service load if needed (this populates tableRows + caches decisions)
if (!dataService.loaded) await dataService.load(false)
} catch (e) {
console.error('LiveView: dataService.load failed', e)
}
// copy rows to local reactive state
agents.value = Array.isArray(dataService.tableRows) ? dataService.tableRows : []
console.log('LiveView: loaded rows =', agents.value.length)
})
</script>
<template>
<div class="p-4 space-y-4">
<AssetTabs v-model="asset" />
<CompareChartE v-if="winnersForChart.length" :selected="winnersForChart" :visible="true" />
<div v-else class="p-4 text-sm text-gray-500 border rounded-lg">
No data for {{ asset }} yet. Make sure Supabase has decisions/runs for this asset and that
<code>dataService.load()</code> completes. Check console for “LiveView: loaded rows” count.
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div v-for="row in winnersSorted" :key="row.agent_name+'|'+row.asset+'|'+row.model"
class="p-4 rounded-2xl border shadow-sm flex justify-between items-center">
<div class="min-w-0">
<div class="font-semibold truncate">{{ row.agent_name }}</div>
<div class="text-xs opacity-70 truncate">{{ row.model }}</div>
</div>
<div class="text-right">
<div class="font-bold text-xl leading-6">{{ fmtUSD(row.balance) }}</div>
<div class="text-xs opacity-70">EOD {{ (row.end_date || row.last_nav_ts) ? new Date(row.end_date || row.last_nav_ts).toLocaleDateString() : '-' }}</div>
</div>
</div>
</div>
</div>
</template>