Skip to content

Commit bf3e2bb

Browse files
authored
feat: enhance home page (#694)
* feat: enhance home page * feat(docs): changeset * fix: add profile breadcrumb * fix: use Chinese text instead * fix: more accurate description * feat: changeset
1 parent 27f6e2f commit bf3e2bb

File tree

6 files changed

+194
-18
lines changed

6 files changed

+194
-18
lines changed

.changeset/metal-snails-bake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"enspire": patch
3+
---
4+
5+
Edit Profile Sidebar text

.changeset/perfect-needles-arrive.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"enspire": patch
3+
---
4+
5+
Fix Profile breadcrumb

.changeset/selfish-beds-shave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"enspire": minor
3+
---
4+
5+
Enhance Home Page

app/components/custom/sidebar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ const sidebarData = ref({
295295
<NuxtLink to="/profile" as-child>
296296
<DropdownMenuItem>
297297
<Icon class="mr-1" name="material-symbols:person-outline" />
298-
<span>Profile</span>
298+
<span>个人资料</span>
299299
</DropdownMenuItem>
300300
</NuxtLink>
301301
</DropdownMenuGroup>

app/pages/index.vue

Lines changed: 177 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<script setup lang="ts">
2+
import type { AllClubs } from '@@/types/api/user/all_clubs'
3+
import type { MyRecords } from '@@/types/api/cas/record/my'
24
import Announcements from '@/components/custom/Index/announcements.vue'
5+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
6+
import { Skeleton } from '@/components/ui/skeleton'
7+
import { useUser } from 'vue-clerk'
38
49
definePageMeta({
510
middleware: ['auth'],
@@ -10,26 +15,181 @@ useHead({
1015
title: 'Home | Enspire',
1116
})
1217
18+
const { user } = useUser()
1319
const now = new Date().getHours()
20+
21+
// Get user's clubs
22+
const { data: clubs } = useQuery<AllClubs>({
23+
queryKey: ['/api/user/all_clubs'],
24+
})
25+
26+
// Track total CAS hours
27+
const isLoading = ref(true)
28+
const totalCASHours = ref(0)
29+
30+
watch(clubs, async () => {
31+
isLoading.value = true
32+
if (clubs.value?.president?.length || clubs.value?.vice?.length) {
33+
let total = 0
34+
for (const club of [...(clubs.value.president || []), ...(clubs.value.vice || [])]) {
35+
const { data } = await useFetch<MyRecords>(`/api/cas/record/my?club=${club.id}`)
36+
if (data.value) {
37+
total += data.value.data.reduce((sum, record) => {
38+
return sum + record.cTime + record.aTime + record.sTime
39+
}, 0)
40+
}
41+
}
42+
totalCASHours.value = total
43+
}
44+
isLoading.value = false
45+
}, { immediate: true })
1446
</script>
1547

1648
<template>
17-
<div class="text-3xl font-bold">
18-
{{
19-
now < 5 ? '晚上好!'
20-
: now < 12 ? '早上好!'
21-
: now < 13 ? '中午好!'
22-
: now < 18 ? '下午好!' : '晚上好!'
23-
}}
24-
</div>
25-
<div class="text-muted-foreground">
26-
Welcome to Enspire!
27-
</div>
28-
<div class="mt-7 space-y-2">
29-
<Announcements />
30-
</div>
31-
</template>
49+
<div class="space-y-6">
50+
51+
<!-- Welcome Section -->
52+
<div>
53+
<div class="text-3xl font-bold">
54+
{{
55+
now < 5 ? '晚上好!'
56+
: now < 12 ? '早上好!'
57+
: now < 13 ? '中午好!'
58+
: now < 18 ? '下午好!' : '晚上好!'
59+
}}
60+
</div>
61+
<div class="text-muted-foreground">
62+
Welcome to Enspire!
63+
</div>
64+
</div>
3265

33-
<style scoped>
66+
<!-- Quick Stats -->
67+
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
68+
<Card class="transition-all hover:shadow-md hover:bg-muted/50">
69+
<CardHeader>
70+
<CardTitle class="flex items-center gap-2">
71+
<Icon name="lucide:users" class="h-5 w-5 text-primary" />
72+
我的社团
73+
</CardTitle>
74+
</CardHeader>
75+
<CardContent>
76+
<div v-if="isLoading" class="space-y-2">
77+
<Skeleton class="h-8 w-16" />
78+
<Skeleton class="h-4 w-32" />
79+
</div>
80+
<div v-else>
81+
<div class="text-2xl font-bold">
82+
{{ (clubs?.president?.length || 0) + (clubs?.vice?.length || 0) + (clubs?.member?.length || 0) }}
83+
</div>
84+
<p class="mt-1 text-xs text-muted-foreground">总计参与社团数量</p>
85+
</div>
86+
</CardContent>
87+
</Card>
3488

35-
</style>
89+
<Card class="transition-all hover:shadow-md hover:bg-muted/50">
90+
<CardHeader>
91+
<CardTitle class="flex items-center gap-2">
92+
<Icon name="lucide:star" class="h-5 w-5 text-primary" />
93+
管理社团
94+
</CardTitle>
95+
</CardHeader>
96+
<CardContent>
97+
<div v-if="isLoading" class="space-y-2">
98+
<Skeleton class="h-8 w-16" />
99+
<Skeleton class="h-4 w-32" />
100+
</div>
101+
<div v-else>
102+
<div class="text-2xl font-bold">
103+
{{ (clubs?.president?.length || 0) + (clubs?.vice?.length || 0) }}
104+
</div>
105+
<p class="mt-1 text-xs text-muted-foreground">担任社长或副社长的社团数量</p>
106+
</div>
107+
</CardContent>
108+
</Card>
109+
110+
<Card class="transition-all hover:shadow-md hover:bg-muted/50">
111+
<CardHeader>
112+
<CardTitle class="flex items-center gap-2">
113+
<Icon name="lucide:clock" class="h-5 w-5 text-primary" />
114+
活动记录时间
115+
</CardTitle>
116+
</CardHeader>
117+
<CardContent>
118+
<div v-if="isLoading" class="space-y-2">
119+
<Skeleton class="h-8 w-16" />
120+
<Skeleton class="h-4 w-32" />
121+
</div>
122+
<div v-else>
123+
<div class="text-2xl font-bold">
124+
{{ totalCASHours }}
125+
</div>
126+
<p class="mt-1 text-xs text-muted-foreground">总计活动时间(小时)</p>
127+
</div>
128+
</CardContent>
129+
</Card>
130+
</div>
131+
132+
<!-- Quick Actions -->
133+
<div>
134+
<h2 class="mb-4 text-lg font-semibold flex items-center gap-2">
135+
<Icon name="lucide:zap" class="h-5 w-5" />
136+
快捷操作
137+
</h2>
138+
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
139+
<NuxtLink to="/cas/clubs" class="group">
140+
<Card class="transition-all hover:bg-muted/50 hover:shadow-md">
141+
<CardHeader>
142+
<CardTitle class="flex items-center gap-2">
143+
<Icon name="lucide:map" class="h-5 w-5" />
144+
浏览社团
145+
</CardTitle>
146+
<CardDescription class="flex items-center">
147+
查看所有社团信息
148+
<Icon name="lucide:arrow-right" class="ml-1 h-4 w-4 transition-transform group-hover:translate-x-1" />
149+
</CardDescription>
150+
</CardHeader>
151+
</Card>
152+
</NuxtLink>
153+
154+
<NuxtLink to="/forms" class="group">
155+
<Card class="transition-all hover:bg-muted/50 hover:shadow-md">
156+
<CardHeader>
157+
<CardTitle class="flex items-center gap-2">
158+
<Icon name="lucide:clipboard" class="h-5 w-5" />
159+
填写表单
160+
</CardTitle>
161+
<CardDescription class="flex items-center">
162+
查看待填写的表单
163+
<Icon name="lucide:arrow-right" class="ml-1 h-4 w-4 transition-transform group-hover:translate-x-1" />
164+
</CardDescription>
165+
</CardHeader>
166+
</Card>
167+
</NuxtLink>
168+
169+
<NuxtLink to="/manage/statuses" class="group">
170+
<Card class="transition-all hover:bg-muted/50 hover:shadow-md">
171+
<CardHeader>
172+
<CardTitle class="flex items-center gap-2">
173+
<Icon name="lucide:door-open" class="h-5 w-5" />
174+
教室状态
175+
</CardTitle>
176+
<CardDescription class="flex items-center">
177+
查看教室预约状态
178+
<Icon name="lucide:arrow-right" class="ml-1 h-4 w-4 transition-transform group-hover:translate-x-1" />
179+
</CardDescription>
180+
</CardHeader>
181+
</Card>
182+
</NuxtLink>
183+
</div>
184+
</div>
185+
186+
<!-- Announcements Section -->
187+
<div>
188+
<h2 class="mb-4 text-lg font-semibold flex items-center gap-2">
189+
<Icon name="lucide:megaphone" class="h-5 w-5" />
190+
公告
191+
</h2>
192+
<Announcements />
193+
</div>
194+
</div>
195+
</template>

app/pages/profile.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const isDark = usePreferredDark()
1818
1919
definePageMeta({
2020
middleware: ['auth'],
21+
breadcrumb: 'Profile',
2122
})
2223
2324
useHead({

0 commit comments

Comments
 (0)