feat: add SingleRecordMnt component for student record maintenance with search, add, edit, view, and delete functionalities
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<v-sheet class="bg-surface" v-bind="$attrs">
|
||||
<!-- Top Stats Cards -->
|
||||
<v-row class="mb-4">
|
||||
<v-col v-for="(stat, index) in props.stats" :key="index" cols="12" md="3" sm="6">
|
||||
<AnalysisStatsCard
|
||||
:color="stat.color"
|
||||
:icon="stat.icon"
|
||||
:label="stat.label"
|
||||
:title="stat.title"
|
||||
:total="stat.total"
|
||||
:value="stat.value"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- Main Trend Chart (Sparkline Area) -->
|
||||
<v-row class="mb-4">
|
||||
<v-col cols="12">
|
||||
<AnalysisTrendChart
|
||||
:active-filter="activeFilter"
|
||||
:data="props.trendData"
|
||||
:filters="props.trendFilters"
|
||||
:title="props.trendTitle"
|
||||
@filter-change="activeFilter = $event"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- Bottom Charts Grid -->
|
||||
<v-row>
|
||||
<!-- Chart 1: Bar Chart (Proxy for Radar/Distribution) -->
|
||||
<v-col cols="12" md="4">
|
||||
<AnalysisBarChart :data="props.barData" :title="props.chart1Title" />
|
||||
</v-col>
|
||||
|
||||
<!-- Chart 2: Donut Chart (Source) -->
|
||||
<v-col cols="12" md="4">
|
||||
<AnalysisPieChart :data="props.pie1Data" :title="props.chart2Title" />
|
||||
</v-col>
|
||||
|
||||
<!-- Chart 3: Donut Chart (Distribution) -->
|
||||
<v-col cols="12" md="4">
|
||||
<AnalysisDonutChart :data="props.pie2Data" :title="props.chart3Title" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-sheet>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import AnalysisBarChart from './base/analysis/AnalysisBarChart.vue'
|
||||
import AnalysisDonutChart from './base/analysis/AnalysisDonutChart.vue'
|
||||
import AnalysisPieChart from './base/analysis/AnalysisPieChart.vue'
|
||||
import AnalysisStatsCard from './base/analysis/AnalysisStatsCard.vue'
|
||||
import AnalysisTrendChart from './base/analysis/AnalysisTrendChart.vue'
|
||||
|
||||
interface StatsItem {
|
||||
title: string
|
||||
value: string | number
|
||||
label: string
|
||||
total: string | number
|
||||
icon: string
|
||||
color: string
|
||||
}
|
||||
|
||||
interface BarDataItem {
|
||||
label: string
|
||||
value: number
|
||||
color: string
|
||||
}
|
||||
|
||||
interface PieData {
|
||||
value: number
|
||||
label: string
|
||||
color: string
|
||||
}
|
||||
|
||||
interface DonutData extends PieData {
|
||||
icon: string
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
// Stats Cards Data
|
||||
stats: { type: Array as () => StatsItem[], default: () => [] },
|
||||
|
||||
// Trend Chart
|
||||
trendTitle: { type: String, default: '流量趨勢' },
|
||||
trendData: { type: Array as () => number[], default: () => [] },
|
||||
trendFilters: { type: Array as () => string[], default: () => ['流量', '訪問量'] },
|
||||
|
||||
// Chart Titles
|
||||
chart1Title: { type: String, default: '核心素養' },
|
||||
chart2Title: { type: String, default: '訪問來源' },
|
||||
chart3Title: { type: String, default: '成績分佈' },
|
||||
|
||||
// Data for Charts
|
||||
barData: { type: Array as () => BarDataItem[], default: () => [] },
|
||||
pie1Data: {
|
||||
type: Object as () => PieData,
|
||||
default: () => ({ value: 75, label: '直接訪問', color: 'primary' }),
|
||||
},
|
||||
pie2Data: {
|
||||
type: Object as () => DonutData,
|
||||
default: () => ({ value: 65, label: '及格率', color: 'success', icon: 'mdi-school' }),
|
||||
},
|
||||
})
|
||||
|
||||
const activeFilter = ref(props.trendFilters[0] || '')
|
||||
</script>
|
||||
Reference in New Issue
Block a user