Files
sub2api/frontend/src/components/user/monitor/MonitorMetricPair.vue
T
erio a1425b457d feat(channel-monitor): redesign user dashboard as card grid
Reference check-cx UI: INTELLIGENCE MONITOR hero + 3-column card grid
with 60-point timeline bars.

Backend:
- Add PrimaryPingLatencyMs + Timeline[60] to UserMonitorView
- ListRecentHistoryForMonitors: batch CTE + ROW_NUMBER() window query
- indexLatestByModel / indexAvailabilityByModel helpers

Frontend:
- 7 new components: ProviderIcon, MonitorMetricPair, MonitorAvailabilityRow,
  MonitorTimeline, MonitorHero, MonitorCard, MonitorCardGrid
- ChannelStatusView 381→~180 lines (delegated to subcomponents)
- AbortController reload concurrency protection
- HSL 0-120° availability color mapping
- Replace emoji with Icon component (bolt / globe)
- i18n: monitorCommon.* shared namespace, channelStatus.hero.*

Bump VERSION to 0.1.114.24
2026-04-20 23:38:59 +08:00

46 lines
1.6 KiB
Vue

<template>
<div class="mt-5 grid grid-cols-2 gap-2">
<div
class="rounded-xl p-3 bg-gray-50/80 dark:bg-dark-900/40 border border-gray-100 dark:border-dark-700/50"
>
<div
class="flex items-center gap-1.5 text-[10px] font-semibold uppercase tracking-wider text-gray-400"
>
<Icon :name="primaryIcon" size="xs" />
<span>{{ primaryLabel }}</span>
</div>
<div class="mt-1.5 text-lg font-bold font-mono tabular-nums text-gray-900 dark:text-gray-100">
{{ primaryValue }}<span class="text-xs font-normal text-gray-400 ml-0.5">{{ primaryUnit }}</span>
</div>
</div>
<div
class="rounded-xl p-3 bg-gray-50/80 dark:bg-dark-900/40 border border-gray-100 dark:border-dark-700/50"
>
<div
class="flex items-center gap-1.5 text-[10px] font-semibold uppercase tracking-wider text-gray-400"
>
<Icon :name="secondaryIcon" size="xs" />
<span>{{ secondaryLabel }}</span>
</div>
<div class="mt-1.5 text-lg font-bold font-mono tabular-nums text-gray-900 dark:text-gray-100">
{{ secondaryValue }}<span class="text-xs font-normal text-gray-400 ml-0.5">{{ secondaryUnit }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import Icon from '@/components/icons/Icon.vue'
defineProps<{
primaryLabel: string
primaryValue: string
primaryUnit: string
primaryIcon: 'bolt' | 'globe' | 'clock' | 'link'
secondaryLabel: string
secondaryValue: string
secondaryUnit: string
secondaryIcon: 'bolt' | 'globe' | 'clock' | 'link'
}>()
</script>