Files
justvitamin/src/components/views/ConversionDriver.vue
T

84 lines
3.2 KiB
Vue

<template>
<div class="view">
<div class="view-label">Conversion Driver</div>
<div class="view-header">
<h1>What makes people buy</h1>
<p class="subtitle">Understand the real-world impact your product has on customers' lives. These benefit insights help you create emotional connections in your visuals by showing outcomes that matter most to your target audience, not just product features.</p>
</div>
<div v-if="loading" class="loading">Loading…</div>
<div v-else-if="!data" class="empty">No conversion driver data available for this product yet.</div>
<template v-else>
<div class="section-title">
Conversion Driver <span class="count-badge">{{ data.drivers?.length }}</span>
</div>
<div class="table-actions">
<button class="export-btn primary">↑ Export</button>
</div>
<div class="table-wrap">
<table class="data-table">
<thead>
<tr>
<th style="width:40px">#</th>
<th style="width:120px">Relevance</th>
<th>Conversion Driver</th>
<th style="width:130px">Customer Journey</th>
<th style="width:80px">Data</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data.drivers" :key="item.rank" class="driver-row" @click="selected = selected === item.rank ? null : item.rank">
<td class="rank">{{ item.rank }}</td>
<td><DotRating :value="item.relevance" :max="5" color="negative" /></td>
<td class="aspect-cell">
<div class="driver-text">{{ item.driver }}</div>
<div v-if="selected === item.rank" class="driver-evidence">{{ item.evidence }}</div>
</td>
<td><JourneyBadge :journey="item.customerJourney" /></td>
<td class="reliability-cell">{{ item.dataReliability }}%</td>
</tr>
</tbody>
</table>
</div>
</template>
</div>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import DotRating from '../primitives/DotRating.vue'
import JourneyBadge from '../primitives/JourneyBadge.vue'
const route = useRoute()
const data = ref(null)
const loading = ref(false)
const selected = ref(null)
async function load(sku) {
if (!sku) return
loading.value = true
selected.value = null
try {
const res = await fetch(`/api/intelligence/${sku}/conversion-driver`)
data.value = res.ok ? await res.json() : null
} finally { loading.value = false }
}
onMounted(() => load(route.params.sku))
watch(() => route.params.sku, load)
</script>
<style scoped src="../views/view.css" />
<style scoped>
.section-title { font-size: 18px; font-weight: 600; margin-bottom: 4px; }
.driver-row { cursor: pointer; }
.driver-text { font-size: 13px; color: var(--text-primary); font-weight: 500; }
.driver-evidence {
font-size: 11px; color: var(--text-muted); margin-top: 4px;
line-height: 1.5; padding: 6px 10px;
background: var(--bg); border-radius: var(--radius); border-left: 3px solid var(--accent);
}
.reliability-cell { font-size: 12px; color: var(--positive); font-weight: 600; }
</style>