Skip to content

Commit a9d49ee

Browse files
authored
Merge pull request #69 from TaskFlow-CLAP/CLAP-216
CLAP-216 통계 페이지 API 연결
2 parents 78b0028 + 353d932 commit a9d49ee

File tree

5 files changed

+122
-18
lines changed

5 files changed

+122
-18
lines changed

src/components/LineChart.vue

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<template>
22
<Line
3+
v-if="labels.length !== 0"
34
:data="teamData"
45
:options="options" />
6+
<NoContent
7+
v-else
8+
content="데이터가 없습니다" />
59
</template>
610

711
<script setup lang="ts">
@@ -17,6 +21,7 @@ import {
1721
LinearScale,
1822
Colors
1923
} from 'chart.js'
24+
import NoContent from './lists/NoContent.vue'
2025
2126
ChartJS.register(
2227
Title,
@@ -41,14 +46,22 @@ const teamData = {
4146
{
4247
label: dataLabel,
4348
data: series,
44-
fill: true,
45-
tension: 0.4
49+
fill: true
4650
}
4751
]
4852
}
4953
5054
const options = {
5155
responsive: true,
52-
maintainAspectRatio: false
56+
maintainAspectRatio: false,
57+
scales: {
58+
y: {
59+
beginAtZero: true,
60+
ticks: {
61+
stepSize: 1
62+
},
63+
suggestedMax: Math.max(...series) + 1
64+
}
65+
}
5366
}
5467
</script>

src/components/PieChart.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<template>
22
<Pie
3+
v-if="labels.length !== 0"
34
:data="teamData"
45
:options="options" />
6+
<NoContent
7+
v-else
8+
content="데이터가 없습니다" />
59
</template>
610

711
<script setup lang="ts">
@@ -16,6 +20,7 @@ import {
1620
type ChartEvent,
1721
type ActiveElement
1822
} from 'chart.js'
23+
import NoContent from './lists/NoContent.vue'
1924
ChartJS.register(Title, Tooltip, Legend, ArcElement, Colors)
2025
2126
const { labels, series } = defineProps<{ labels: string[]; series: number[] }>()

src/components/statistics/StatisticsCard.vue

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,29 @@
1010
<div class="w-full h-[1px] bg-border-1" />
1111
<div class="h-60">
1212
<PieChart
13+
:key="JSON.stringify(labels) + periodType"
1314
v-if="chartType === 'pie'"
14-
:labels="['a', 'b', 'c']"
15-
:series="[1, 2, 3]" />
15+
:labels="labels"
16+
:series="series" />
1617
<LineChart
18+
:key="JSON.stringify(labels) + periodType"
1719
v-if="chartType === 'line'"
18-
:labels="['a', 'b', 'c']"
19-
:series="[1, 2, 3]"
20+
:labels="labels"
21+
:series="series"
2022
:data-label="title.slice(4)" />
2123
</div>
2224
</div>
2325
</template>
2426

2527
<script setup lang="ts">
26-
import { ref } from 'vue'
28+
import { computed, ref } from 'vue'
2729
import PieChart from '../PieChart.vue'
2830
import LineChart from '../LineChart.vue'
2931
import PeriodButtons from './PeriodButtons.vue'
3032
import type { PeriodType } from '@/types/manager'
33+
import axiosInstance from '@/utils/axios'
34+
import { useQuery } from '@tanstack/vue-query'
35+
import type { StatisticsData } from '@/types/admin'
3136
3237
const { title, statisticsType, chartType } = defineProps<{
3338
title: string
@@ -45,4 +50,31 @@ const periodType = ref<PeriodType>('DAY')
4550
const changePeriod = (newPeriodType: PeriodType) => {
4651
periodType.value = newPeriodType
4752
}
53+
54+
const fetchStatistics = async () => {
55+
const response = await axiosInstance.get('/api/tasks/statistics', {
56+
headers: {
57+
Authorization: `Bearer ${import.meta.env.VITE_ACCESS_TOKEN}`
58+
},
59+
params: {
60+
periodType: periodType.value,
61+
statisticsType
62+
}
63+
})
64+
65+
return response.data
66+
}
67+
68+
const { data } = useQuery<StatisticsData[]>({
69+
queryKey: [statisticsType, periodType],
70+
queryFn: fetchStatistics
71+
})
72+
73+
const labels = computed(() => {
74+
return data.value?.map(el => el.key) || []
75+
})
76+
77+
const series = computed(() => {
78+
return data.value?.map(el => el.count) || []
79+
})
4880
</script>

src/components/statistics/StatisticsCategoryCard.vue

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,29 @@
1111
<div class="h-60 flex overflow-hidden">
1212
<div class="w-1/2 px-1">
1313
<PieChart
14-
:labels="['a', 'b', 'c', 'd']"
15-
:series="[1, 2, 3, 4]"
14+
:key="JSON.stringify(mainLabels) + periodType"
15+
:labels="mainLabels"
16+
:series="mainSeries"
1617
@on-click="changeMainCategory" />
1718
</div>
1819
<div class="w-1/2 px-1">
1920
<PieChart
20-
:key="mainCategory"
21-
:labels="
22-
mainCategory
23-
? [`${mainCategory}-1`, `${mainCategory}-2`, `${mainCategory}-3`, `${mainCategory}-4`]
24-
: ['카테고리를 선택해주세요']
25-
"
26-
:series="mainCategory ? [1, 2, 3, 4] : []" />
21+
:key="JSON.stringify(subLabels) + mainCategory + periodType"
22+
:labels="subLabels"
23+
:series="subSeries" />
2724
</div>
2825
</div>
2926
</div>
3027
</template>
3128

3229
<script setup lang="ts">
33-
import { ref } from 'vue'
30+
import { computed, ref } from 'vue'
3431
import PieChart from '../PieChart.vue'
3532
import PeriodButtons from './PeriodButtons.vue'
3633
import type { PeriodType } from '@/types/manager'
34+
import axiosInstance from '@/utils/axios'
35+
import { useQuery } from '@tanstack/vue-query'
36+
import type { StatisticsData } from '@/types/admin'
3737
3838
const periodType = ref<PeriodType>('DAY')
3939
const changePeriod = (newPeriodType: PeriodType) => {
@@ -42,4 +42,53 @@ const changePeriod = (newPeriodType: PeriodType) => {
4242
4343
const mainCategory = ref('')
4444
const changeMainCategory = (value: string) => (mainCategory.value = value)
45+
46+
const fetchMainStatistics = async () => {
47+
const response = await axiosInstance.get('/api/tasks/statistics', {
48+
headers: {
49+
Authorization: `Bearer ${import.meta.env.VITE_ACCESS_TOKEN}`
50+
},
51+
params: {
52+
periodType: periodType.value,
53+
statisticsType: 'REQUEST_BY_CATEGORY'
54+
}
55+
})
56+
57+
return response.data
58+
}
59+
const { data: mainData } = useQuery<StatisticsData[]>({
60+
queryKey: ['REQUEST_BY_CATEGORY', periodType],
61+
queryFn: fetchMainStatistics
62+
})
63+
const mainLabels = computed(() => {
64+
return mainData.value?.map(el => el.key) || []
65+
})
66+
const mainSeries = computed(() => {
67+
return mainData.value?.map(el => el.count) || []
68+
})
69+
70+
const fetchSubStatistics = async () => {
71+
const response = await axiosInstance.get('/api/tasks/statistics/subcategory', {
72+
headers: {
73+
Authorization: `Bearer ${import.meta.env.VITE_ACCESS_TOKEN}`
74+
},
75+
params: {
76+
periodType: periodType.value,
77+
mainCategory: mainCategory.value
78+
}
79+
})
80+
81+
return response.data
82+
}
83+
const { data: subData } = useQuery<StatisticsData[]>({
84+
queryKey: [mainCategory.value, periodType],
85+
queryFn: fetchSubStatistics,
86+
enabled: computed(() => mainCategory.value !== '')
87+
})
88+
const subLabels = computed(() => {
89+
return subData.value?.map(el => el.key) || []
90+
})
91+
const subSeries = computed(() => {
92+
return subData.value?.map(el => el.count) || []
93+
})
4594
</script>

src/types/admin.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,8 @@ export interface NewLabelTypes {
5656
labelName: string
5757
labelColor: string
5858
}
59+
60+
export interface StatisticsData {
61+
key: string
62+
count: number
63+
}

0 commit comments

Comments
 (0)