File tree Expand file tree Collapse file tree 10 files changed +185
-4
lines changed Expand file tree Collapse file tree 10 files changed +185
-4
lines changed Original file line number Diff line number Diff line change @@ -5,3 +5,4 @@ TSIMS_URL=
5
5
SENTRY_DSN =
6
6
CLUB_DATA_SECRET_KEY =
7
7
SENTRY_AUTH_TOKEN =
8
+ NOCODB_URL =
Original file line number Diff line number Diff line change @@ -18,6 +18,19 @@ const route = useRoute()
18
18
</NuxtLink >
19
19
</div >
20
20
</div >
21
+ <div class =" px-3 py-2" >
22
+ <h2 class =" relative px-4 text-lg font-semibold tracking-tight" >
23
+ 学校事务
24
+ </h2 >
25
+ <div class =" mt-2" >
26
+ <NuxtLink to =" /forms" >
27
+ <Button :variant =" route.name === 'forms' ? 'secondary' : 'ghost'" class =" w-full justify-start" >
28
+ <Icon class =" mr-2 h-4 w-4" name =" material-symbols:grid-view-outline-rounded" />
29
+ 表单
30
+ </Button >
31
+ </NuxtLink >
32
+ </div >
33
+ </div >
21
34
<div class =" px-3 py-2" >
22
35
<h2 class =" relative px-4 text-lg font-semibold tracking-tight" >
23
36
社团信息
Original file line number Diff line number Diff line change
1
+ ---
2
+ 20240930_0001 :
3
+ title : " Form 1"
4
+ description : " This is the first form"
5
+ url : " https://wazkw5hf.nocodb.com/#/nc/form/7f4847a8-c4d5-40f9-b052-4222d07b3e2b?embed"
6
+ start_date : " 2024-09-30"
7
+ end_date : " 2024-10-30"
Original file line number Diff line number Diff line change @@ -81,10 +81,8 @@ watch(
81
81
<!-- Sidebar -->
82
82
<Sidebar class =" top-0 hidden lg:inline-block h-full w-1/6" />
83
83
<!-- Main content -->
84
- <ScrollArea class =" h-full px-4 lg:px-8 w-full pt-8" >
85
- <div class =" pb-24" >
86
- <slot />
87
- </div >
84
+ <ScrollArea class =" h-full px-4 lg:px-8 w-full pt-8 mb-24" >
85
+ <slot />
88
86
</ScrollArea >
89
87
</div >
90
88
</div >
Original file line number Diff line number Diff line change 50
50
"vaul-vue" : " ^0.2.0" ,
51
51
"vee-validate" : " ^4.13.2" ,
52
52
"vue-clerk" : " ^0.6.9" ,
53
+ "yaml" : " ^2.5.1" ,
53
54
"zod" : " ^3.23.8"
54
55
},
55
56
"devDependencies" : {
Original file line number Diff line number Diff line change
1
+ <script setup lang="ts">
2
+ import { useWindowSize } from ' @vueuse/core'
3
+ import { useClerk } from ' vue-clerk'
4
+ import { toast } from ' ~/components/ui/toast'
5
+ import type { Form } from ' ~/types/data/forms'
6
+
7
+ const clerk = useClerk ()
8
+
9
+ const { height } = useWindowSize ()
10
+
11
+ definePageMeta ({
12
+ middleware: [' auth' ],
13
+ })
14
+
15
+ useHead ({
16
+ title: ' Forms | Enspire' ,
17
+ })
18
+
19
+ const { data } = await useAsyncData <Form []>(' classroomStatuses' , () => {
20
+ return $fetch <Form []>(` /api/forms/open ` , {
21
+ headers: useRequestHeaders (),
22
+ method: ' GET' ,
23
+ })
24
+ })
25
+
26
+ if (! data .value ) {
27
+ toast ({
28
+ title: ' 错误' ,
29
+ description: ' 获取教室信息出错' ,
30
+ })
31
+ }
32
+
33
+ const form = data .value ! .find (form => form .id === useRoute ().params .id )
34
+ </script >
35
+
36
+ <template >
37
+ <div v-if =" form" class =" font-bold text-xl" >
38
+ {{ form.title }}
39
+ </div >
40
+ <div v-if =" form" class =" text-muted-foreground text-sm" >
41
+ {{ form.description }}
42
+ </div >
43
+ <div v-if =" form" class =" rounded" >
44
+ <ClientOnly >
45
+ <iframe :height =" height - 110" width =" 100%" class =" rounded" :src =" `${form.url}&userid=${clerk.user.id}`" />
46
+ </ClientOnly >
47
+ </div >
48
+ </template >
49
+
50
+ <style scoped>
51
+
52
+ </style >
Original file line number Diff line number Diff line change
1
+ <script setup lang="ts">
2
+ import {
3
+ Card ,
4
+ CardDescription ,
5
+ CardFooter ,
6
+ CardHeader ,
7
+ CardTitle ,
8
+ } from ' @/components/ui/card'
9
+ import Toaster from ' @/components/ui/toast/Toaster.vue'
10
+ import { toast } from ' ~/components/ui/toast'
11
+ import type { Form } from ' ~/types/data/forms'
12
+
13
+ definePageMeta ({
14
+ middleware: [' auth' ],
15
+ })
16
+
17
+ useHead ({
18
+ title: ' Forms | Enspire' ,
19
+ })
20
+
21
+ const { data } = await useAsyncData <Form []>(' classroomStatuses' , () => {
22
+ return $fetch <Form []>(` /api/forms/open ` , {
23
+ headers: useRequestHeaders (),
24
+ method: ' GET' ,
25
+ })
26
+ })
27
+
28
+ if (! data .value ) {
29
+ toast ({
30
+ title: ' 错误' ,
31
+ description: ' 获取教室信息出错' ,
32
+ })
33
+ }
34
+ </script >
35
+
36
+ <template >
37
+ <div class =" font-bold flex items-center space-x-2 text-lg" >
38
+ <Icon name =" material-symbols:edit-square-outline" />
39
+ <div >可填写的表单</div >
40
+ </div >
41
+ <div class =" grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 mt-2" >
42
+ <NuxtLink v-for =" club in data" :key =" club.id" :to =" `/forms/${club.id}`" >
43
+ <Card class =" hover:underline" >
44
+ <CardHeader >
45
+ <CardTitle >{{ club.title }}</CardTitle >
46
+ <CardDescription >{{ club.description }}</CardDescription >
47
+ </CardHeader >
48
+ <CardFooter class =" text-muted-foreground text-sm flex items-center" >
49
+ <div >点击填写</div >
50
+ <Icon name =" material-symbols:arrow-forward" />
51
+ </CardFooter >
52
+ </Card >
53
+ </NuxtLink >
54
+ </div >
55
+ <Toaster />
56
+ </template >
57
+
58
+ <style scoped>
59
+ </style >
Original file line number Diff line number Diff line change
1
+ import dayjs from 'dayjs'
2
+ import { createStorage } from 'unstorage'
3
+ import fsLiteDriver from 'unstorage/drivers/fs-lite'
4
+ import { parse } from 'yaml'
5
+ import type { Form , Forms } from '~/types/data/forms'
6
+
7
+ const storage = createStorage ( {
8
+ driver : fsLiteDriver ( { base : './data' } ) ,
9
+ } )
10
+
11
+ export default eventHandler ( async ( event ) => {
12
+ const { auth } = event . context
13
+
14
+ if ( ! auth . userId ) {
15
+ setResponseStatus ( event , 403 )
16
+ return
17
+ }
18
+
19
+ const yaml = await storage . getItem ( 'forms:forms.yaml' ) as string
20
+
21
+ if ( ! yaml ) {
22
+ setResponseStatus ( event , 404 )
23
+ return
24
+ }
25
+
26
+ const yamlForms = parse ( yaml ) as Forms
27
+
28
+ const forms : Form [ ] = ( Object . entries ( yamlForms ) . map ( ( [ id , entry ] ) => ( {
29
+ id,
30
+ ...entry ,
31
+ } ) ) )
32
+
33
+ return forms
34
+ . filter ( entry => dayjs ( ) . isBefore ( dayjs ( entry . end_date ) ) )
35
+ } )
Original file line number Diff line number Diff line change
1
+ export interface Form {
2
+ id ?: string
3
+ title : string
4
+ description : string
5
+ url : string
6
+ start_date : string
7
+ end_date : string
8
+ }
9
+
10
+ export interface Forms {
11
+ [ key : string ] : Form
12
+ }
You can’t perform that action at this time.
0 commit comments