141 lines
5.9 KiB
Vue
141 lines
5.9 KiB
Vue
<template>
|
|
<div class="relative min-h-screen text-white">
|
|
<!-- Background Image -->
|
|
<div class="fixed inset-0 z-0">
|
|
<div class="absolute inset-0 bg-[url('@/assets/garage-bg.png')] bg-cover bg-center bg-fixed"></div>
|
|
</div>
|
|
|
|
<!-- Header -->
|
|
<BaseHeader>
|
|
<template #left>
|
|
<HeaderLogo />
|
|
</template>
|
|
<template #center>
|
|
<span class="text-sm font-semibold text-white/70 tracking-wide">
|
|
{{ t('dashboard.trustScore') }}
|
|
</span>
|
|
</template>
|
|
<template #right>
|
|
<HeaderCompanySwitcher />
|
|
<HeaderProfile />
|
|
</template>
|
|
</BaseHeader>
|
|
|
|
<!-- Content -->
|
|
<div class="relative z-10 pt-20">
|
|
<div class="mx-auto max-w-4xl px-4 py-8 sm:px-6 lg:px-8">
|
|
<div class="rounded-2xl border border-white/10 bg-black/40 p-6 backdrop-blur-xl shadow-xl shadow-black/20">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<svg class="w-6 h-6 text-[#00E5A0]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
|
</svg>
|
|
<h2 class="text-xl font-bold text-white">{{ t('dashboard.trustScore') }}</h2>
|
|
</div>
|
|
|
|
<!-- Trust Score Gauge -->
|
|
<div class="rounded-xl border border-white/10 bg-white/5 p-6 mb-6">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<span class="text-lg font-bold text-white">{{ trustScoreLabel }}</span>
|
|
<span class="text-4xl font-extrabold" :class="trustScoreColor">{{ trustScorePercent }}%</span>
|
|
</div>
|
|
<div class="h-3 overflow-hidden rounded-full bg-slate-700">
|
|
<div
|
|
class="h-full rounded-full bg-gradient-to-r from-emerald-400 to-emerald-600 transition-all duration-500"
|
|
:style="{ width: trustScorePercent + '%' }"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats Grid -->
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-6">
|
|
<div class="rounded-xl border border-white/10 bg-white/5 p-4">
|
|
<p class="text-xs text-white/50 uppercase tracking-wider mb-1">{{ t('profile.completion') }}</p>
|
|
<p class="text-2xl font-bold text-[#00E5A0]">{{ profileCompletion }}%</p>
|
|
</div>
|
|
<div class="rounded-xl border border-white/10 bg-white/5 p-4">
|
|
<p class="text-xs text-white/50 uppercase tracking-wider mb-1">{{ t('header.myCompanies') }}</p>
|
|
<p class="text-2xl font-bold text-white">{{ organizationsCount }}</p>
|
|
</div>
|
|
<div class="rounded-xl border border-white/10 bg-white/5 p-4">
|
|
<p class="text-xs text-white/50 uppercase tracking-wider mb-1">{{ t('dashboard.totalVehicles') }}</p>
|
|
<p class="text-2xl font-bold text-white">{{ vehiclesCount }}</p>
|
|
</div>
|
|
<div class="rounded-xl border border-white/10 bg-white/5 p-4">
|
|
<p class="text-xs text-white/50 uppercase tracking-wider mb-1">{{ t('finance.rewards') }}</p>
|
|
<p class="text-2xl font-bold text-amber-500">{{ serviceCoins }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Back button -->
|
|
<div class="mt-8 text-center">
|
|
<button
|
|
@click="router.push('/dashboard')"
|
|
class="inline-flex items-center gap-2 rounded-xl border border-white/[0.12] bg-white/[0.04] px-6 py-3 text-white/70 transition-all duration-200 hover:border-[#00E5A0]/40 hover:text-white hover:bg-white/[0.08] backdrop-blur-sm cursor-pointer"
|
|
>
|
|
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="19" y1="12" x2="5" y2="12" />
|
|
<polyline points="12 19 5 12 12 5" />
|
|
</svg>
|
|
{{ t('common.backToGarage') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useAuthStore } from '../stores/auth'
|
|
import { useVehicleStore } from '../stores/vehicle'
|
|
import { useFinanceStore } from '../stores/finance'
|
|
import BaseHeader from '../components/layout/BaseHeader.vue'
|
|
import HeaderLogo from '../components/header/HeaderLogo.vue'
|
|
import HeaderCompanySwitcher from '../components/header/HeaderCompanySwitcher.vue'
|
|
import HeaderProfile from '../components/header/HeaderProfile.vue'
|
|
|
|
const router = useRouter()
|
|
const { t } = useI18n()
|
|
const authStore = useAuthStore()
|
|
const vehicleStore = useVehicleStore()
|
|
const financeStore = useFinanceStore()
|
|
|
|
const trustScorePercent = computed(() => 75)
|
|
const trustScoreLabel = computed(() => {
|
|
const pct = trustScorePercent.value
|
|
if (pct >= 90) return 'A+'
|
|
if (pct >= 75) return 'A'
|
|
if (pct >= 60) return 'B'
|
|
if (pct >= 40) return 'C'
|
|
return 'D'
|
|
})
|
|
const trustScoreColor = computed(() => {
|
|
const pct = trustScorePercent.value
|
|
if (pct >= 75) return 'text-emerald-400'
|
|
if (pct >= 50) return 'text-amber-400'
|
|
return 'text-red-400'
|
|
})
|
|
|
|
const profileCompletion = computed(() => {
|
|
const p = authStore.user?.person
|
|
if (!p) return 0
|
|
let total = 0
|
|
let filled = 0
|
|
if (p.first_name) filled++; total++
|
|
if (p.last_name) filled++; total++
|
|
if (p.phone) filled++; total++
|
|
return Math.round((filled / total) * 100)
|
|
})
|
|
|
|
const organizationsCount = computed(() => authStore.myOrganizations.length)
|
|
const vehiclesCount = computed(() => vehicleStore.vehicles.length)
|
|
const serviceCoins = computed(() => {
|
|
const coins = financeStore.serviceCoins
|
|
if (Number.isInteger(coins)) return coins.toLocaleString()
|
|
return coins.toFixed(2)
|
|
})
|
|
</script>
|