++
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div v-if="scorecard?.length">
|
||||
<h2 class="section-title">Scorecard</h2>
|
||||
<h2 class="section-title">{{ t('report.scorecard') }}</h2>
|
||||
<div class="grid grid-cols-2 lg:grid-cols-3 gap-3">
|
||||
<div
|
||||
v-for="s in scorecard"
|
||||
v-for="s in enriched"
|
||||
:key="s.metric"
|
||||
:class="['border rounded-lg p-4 transition-colors', cardBg(s.rating)]"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs text-slate-500">{{ s.label }}</span>
|
||||
<span class="text-xs text-slate-500">{{ s.labelLocalized }}</span>
|
||||
<span :class="['text-[10px] font-semibold uppercase px-1.5 py-0.5 rounded', ratingColor(s.rating)]">
|
||||
{{ s.rating }}
|
||||
{{ s.ratingLocalized }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
@@ -18,7 +18,7 @@
|
||||
<span class="text-xs text-slate-500">/100</span>
|
||||
<span :class="['text-xs ml-auto', trendColor(s.trend)]">
|
||||
{{ s.trend === 'up' ? '↑' : s.trend === 'down' ? '↓' : '→' }}
|
||||
<span class="text-slate-500 ml-0.5">from {{ s.start_value }}</span>
|
||||
<span class="text-slate-500 ml-0.5">{{ _fromLabel() }} {{ s.start_value }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- Sparkline -->
|
||||
@@ -56,12 +56,40 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed as _computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const props = defineProps({
|
||||
scorecard: { type: Array, default: () => [] },
|
||||
metricsHistory: { type: Array, default: () => [] },
|
||||
forecasts: { type: Object, default: () => ({}) },
|
||||
})
|
||||
|
||||
const { t, tm } = useI18n()
|
||||
|
||||
// Look up a metric/rating/trend key in the report.* namespace and fall back
|
||||
// to the raw enum value if the key isn't recognized. Lets the backend keep
|
||||
// canonical English enum strings while we render localized labels.
|
||||
function _metricLabel(key) {
|
||||
const keyMap = { stability: 'report.metricLabels.stability', prosperity: 'report.metricLabels.prosperity',
|
||||
trust: 'report.metricLabels.trust', freedom: 'report.metricLabels.freedom',
|
||||
conflict: 'report.metricLabels.conflict', brand_sentiment: 'report.metricLabels.brandSentiment',
|
||||
purchase_intent: 'report.metricLabels.purchaseIntent', word_of_mouth: 'report.metricLabels.wordOfMouth',
|
||||
churn_risk: 'report.metricLabels.churnRisk', adoption_rate: 'report.metricLabels.adoptionRate' }
|
||||
const i18nKey = keyMap[key]
|
||||
return i18nKey ? t(i18nKey) : key
|
||||
}
|
||||
function _ratingLabel(r) { return t(`report.ratings.${r}`, r) }
|
||||
function _trendLabel(t_) { return t(`report.trends.${t_}`, t_) }
|
||||
function _fromLabel() { return t('report.from') }
|
||||
|
||||
const enriched = _computed(() => props.scorecard.map(s => ({
|
||||
...s,
|
||||
labelLocalized: _metricLabel(s.metric),
|
||||
ratingLocalized: _ratingLabel(s.rating),
|
||||
trendLocalized: _trendLabel(s.trend),
|
||||
})))
|
||||
|
||||
function getSparkline(metricKey) {
|
||||
if (!props.metricsHistory?.length) return []
|
||||
const hist = props.metricsHistory
|
||||
|
||||
Reference in New Issue
Block a user