feat: complete admin panel and backend admin api migration
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<!--
|
||||
Ported from legacy henza_admin/src/components/statistics-cards/StatisticsCardLine.vue.
|
||||
|
||||
The legacy component renders an ApexCharts sparkline under the figure, but
|
||||
EVERY live caller passes :hideChart="true" (verified: 3 of 3 on the wholesale
|
||||
dashboard), and the only apexchart markup in either dashboard sits inside
|
||||
commented-out Vuexy demo cards. So the chart branch is not ported and
|
||||
vue-apexcharts is not a dependency — adding it would ship a library nothing
|
||||
renders.
|
||||
-->
|
||||
<a-card class="stat-card">
|
||||
<div class="stat-row">
|
||||
<span class="stat-icon" :class="`icon-${color}`">
|
||||
<component :is="iconComponent" />
|
||||
</span>
|
||||
<div>
|
||||
<h2 class="stat-value">{{ statistic }}</h2>
|
||||
<span class="stat-title">{{ statisticTitle }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import {
|
||||
ShoppingOutlined,
|
||||
TeamOutlined,
|
||||
DollarOutlined,
|
||||
BarChartOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
icon?: string;
|
||||
statistic?: string | number;
|
||||
statisticTitle?: string;
|
||||
color?: string;
|
||||
/** Kept for call-site parity; the chart branch is not ported (see above). */
|
||||
hideChart?: boolean;
|
||||
}>(),
|
||||
{ color: 'primary', hideChart: true },
|
||||
);
|
||||
|
||||
/** feather name -> ant icon, matching the icons the live cards ask for */
|
||||
const ICONS: Record<string, unknown> = {
|
||||
UsersIcon: TeamOutlined,
|
||||
ShoppingBagIcon: ShoppingOutlined,
|
||||
DollarSignIcon: DollarOutlined,
|
||||
BarChartIcon: BarChartOutlined,
|
||||
};
|
||||
|
||||
const iconComponent = computed(() => ICONS[props.icon ?? ''] ?? BarChartOutlined);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.stat-card {
|
||||
height: 100%;
|
||||
}
|
||||
.stat-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
.stat-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
font-size: 22px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.icon-primary {
|
||||
background: rgba(28, 45, 86, 0.1);
|
||||
color: #1c2d56;
|
||||
}
|
||||
.icon-warning {
|
||||
background: rgba(255, 159, 67, 0.12);
|
||||
color: #ff9f43;
|
||||
}
|
||||
.icon-success {
|
||||
background: rgba(40, 199, 111, 0.12);
|
||||
color: #28c76f;
|
||||
}
|
||||
.icon-danger {
|
||||
background: rgba(234, 84, 85, 0.12);
|
||||
color: #ea5455;
|
||||
}
|
||||
.stat-value {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
color: #1c2d56;
|
||||
}
|
||||
.stat-title {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user