From bd5ccb62013161e21fcd8b417c1cdb3db2b0991c Mon Sep 17 00:00:00 2001 From: ByungCheol Date: Sat, 11 Jul 2026 23:19:07 +0900 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=EC=A7=80=EC=97=AD=EB=B3=84=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=EA=B1=B4=EC=88=98=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20+=20=EB=A9=94=EB=89=B4=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 통계 화면(/statistics): 시군구 지역별 매칭건수 전체 — 요약카드·막대분포·상세표(비율) - 대시보드 지역 카드는 상위 5개만 노출 + '전체 통계' 링크 - 메뉴: '피신고자 관리' → '신고 관리', '통계' 추가 Co-Authored-By: Claude Opus 4.8 (1M context) --- src/layouts/AdminLayout.vue | 3 +- src/pages/DashboardPage.vue | 13 ++-- src/pages/StatisticsPage.vue | 123 +++++++++++++++++++++++++++++++++++ src/router/index.ts | 1 + 4 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 src/pages/StatisticsPage.vue diff --git a/src/layouts/AdminLayout.vue b/src/layouts/AdminLayout.vue index 11090b5..723d97b 100644 --- a/src/layouts/AdminLayout.vue +++ b/src/layouts/AdminLayout.vue @@ -59,9 +59,10 @@ const drawer = ref(true) const menu = [ { name: 'dashboard', label: '대시보드', icon: 'dashboard' }, + { name: 'statistics', label: '통계', icon: 'insights' }, { name: 'members', label: '회원 관리', icon: 'group' }, { name: 'subscriptions', label: '구독 관리', icon: 'card_membership' }, - { name: 'reports', label: '피신고자 관리', icon: 'report' }, + { name: 'reports', label: '신고 관리', icon: 'report' }, { name: 'blacklist', label: '블랙리스트', icon: 'block' }, ] diff --git a/src/pages/DashboardPage.vue b/src/pages/DashboardPage.vue index b4e85f0..1c91a34 100644 --- a/src/pages/DashboardPage.vue +++ b/src/pages/DashboardPage.vue @@ -77,12 +77,16 @@
- -
지역별 매칭 (시군구)
-
체크인 지역 기준
+ +
+
지역별 매칭건수 (시군구)
+
체크인 지역 기준 · 상위 5개
+
+ +
-
+
{{ r.region }}
@@ -127,6 +131,7 @@ const tierRows = computed(() => { const order = ['FREE', 'AD_FREE', 'PREMIUM'] return [...(summary.value?.members.byTier ?? [])].sort((a, b) => order.indexOf(a.key) - order.indexOf(b.key)) }) +const topRegions = computed(() => regions.value.slice(0, 5)) const regionMax = computed(() => Math.max(1, ...regions.value.map((r) => r.checkIns))) const visitorMax = computed(() => Math.max(1, ...visitors.value.map((v) => v.count))) diff --git a/src/pages/StatisticsPage.vue b/src/pages/StatisticsPage.vue new file mode 100644 index 0000000..2685cd6 --- /dev/null +++ b/src/pages/StatisticsPage.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/src/router/index.ts b/src/router/index.ts index c9f1a36..951d650 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -14,6 +14,7 @@ const routes: RouteRecordRaw[] = [ children: [ { path: '', redirect: { name: 'dashboard' } }, { path: 'dashboard', name: 'dashboard', component: () => import('@/pages/DashboardPage.vue') }, + { path: 'statistics', name: 'statistics', component: () => import('@/pages/StatisticsPage.vue') }, { path: 'members', name: 'members', component: () => import('@/pages/MembersPage.vue') }, { path: 'members/:id', name: 'member-detail', component: () => import('@/pages/MemberDetailPage.vue') }, { path: 'subscriptions', name: 'subscriptions', component: () => import('@/pages/SubscriptionsPage.vue') },