diff --git a/app/pages/admin/training.vue b/app/pages/admin/training.vue new file mode 100644 index 0000000..1d619cd --- /dev/null +++ b/app/pages/admin/training.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d70ba6..ba77f41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3186,9 +3186,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - graphmatch@1.1.1: - resolution: {integrity: sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg==} - gzip-size@7.0.0: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6893,7 +6890,9 @@ snapshots: '@prisma/debug@7.3.0': {} - '@prisma/dev@0.20.0(typescript@5.9.3)': + '@prisma/debug@7.0.0': {} + + '@prisma/dev@0.13.0(typescript@5.9.3)': dependencies: '@electric-sql/pglite': 0.3.15 '@electric-sql/pglite-socket': 0.0.20(@electric-sql/pglite@0.3.15) @@ -8138,10 +8137,10 @@ snapshots: csstype@3.2.3: {} - db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3): + db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3): optionalDependencies: - '@electric-sql/pglite': 0.3.15 - better-sqlite3: 12.8.0 + '@electric-sql/pglite': 0.3.2 + better-sqlite3: 11.10.0 mysql2: 3.15.3 debug@4.4.3: @@ -8761,8 +8760,6 @@ snapshots: graphemer@1.4.0: {} - graphmatch@1.1.1: {} - gzip-size@7.0.0: dependencies: duplexer: 0.1.2 @@ -9303,7 +9300,7 @@ snapshots: natural-compare@1.4.0: {} - nitropack@2.12.9(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3): + nitropack@2.12.9(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3): dependencies: '@cloudflare/kv-asset-handler': 0.4.0 '@rollup/plugin-alias': 5.1.1(rollup@4.53.2) @@ -9324,7 +9321,7 @@ snapshots: cookie-es: 2.0.0 croner: 9.1.0 crossws: 0.3.5 - db0: 0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3) + db0: 0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3) defu: 6.1.4 destr: 2.0.5 dot-prop: 10.1.0 @@ -9370,7 +9367,7 @@ snapshots: unenv: 2.0.0-rc.24 unimport: 5.5.0 unplugin-utils: 0.3.1 - unstorage: 1.17.2(db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3))(ioredis@5.8.2) + unstorage: 1.17.2(db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3))(ioredis@5.8.2) untyped: 2.0.0 unwasm: 0.3.11 youch: 4.1.0-beta.12 @@ -9455,16 +9452,16 @@ snapshots: transitivePeerDependencies: - vue - nuxt@4.2.1(@electric-sql/pglite@0.3.15)(@parcel/watcher@2.5.1)(@types/node@24.10.1)(@vue/compiler-sfc@3.5.24)(better-sqlite3@12.8.0)(db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3))(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(yaml@2.8.1): + nuxt@4.2.1(@electric-sql/pglite@0.3.2)(@parcel/watcher@2.5.1)(@types/node@24.10.1)(@vue/compiler-sfc@3.5.24)(better-sqlite3@11.10.0)(db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3))(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(yaml@2.8.1): dependencies: '@dxup/nuxt': 0.2.2(magicast@0.5.1) '@nuxt/cli': 3.30.0(magicast@0.5.1) '@nuxt/devtools': 3.1.0(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(vue@3.5.24(typescript@5.9.3)) '@nuxt/kit': 4.2.1(magicast@0.5.1) - '@nuxt/nitro-server': 4.2.1(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3))(ioredis@5.8.2)(magicast@0.5.1)(mysql2@3.15.3)(nuxt@4.2.1(@electric-sql/pglite@0.3.15)(@parcel/watcher@2.5.1)(@types/node@24.10.1)(@vue/compiler-sfc@3.5.24)(better-sqlite3@12.8.0)(db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3))(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3) + '@nuxt/nitro-server': 4.2.1(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3))(ioredis@5.8.2)(magicast@0.5.1)(mysql2@3.15.3)(nuxt@4.2.1(@electric-sql/pglite@0.3.2)(@parcel/watcher@2.5.1)(@types/node@24.10.1)(@vue/compiler-sfc@3.5.24)(better-sqlite3@11.10.0)(db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3))(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(yaml@2.8.1))(typescript@5.9.3) '@nuxt/schema': 4.2.1 '@nuxt/telemetry': 2.6.6(magicast@0.5.1) - '@nuxt/vite-builder': 4.2.1(@types/node@24.10.1)(eslint@9.39.1(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.1)(nuxt@4.2.1(@electric-sql/pglite@0.3.15)(@parcel/watcher@2.5.1)(@types/node@24.10.1)(@vue/compiler-sfc@3.5.24)(better-sqlite3@12.8.0)(db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3))(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))(yaml@2.8.1) + '@nuxt/vite-builder': 4.2.1(@types/node@24.10.1)(eslint@9.39.1(jiti@2.6.1))(lightningcss@1.30.2)(magicast@0.5.1)(nuxt@4.2.1(@electric-sql/pglite@0.3.2)(@parcel/watcher@2.5.1)(@types/node@24.10.1)(@vue/compiler-sfc@3.5.24)(better-sqlite3@11.10.0)(db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3))(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.1)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.1))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.53.2)(terser@5.44.1)(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))(yaml@2.8.1) '@unhead/vue': 2.0.19(vue@3.5.24(typescript@5.9.3)) '@vue/shared': 3.5.24 c12: 3.3.2(magicast@0.5.1) @@ -9975,7 +9972,7 @@ snapshots: pretty-bytes@7.1.0: {} - prisma@7.3.0(@types/react@19.2.6)(better-sqlite3@12.8.0)(magicast@0.5.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + prisma@7.0.0(@types/react@19.2.6)(better-sqlite3@11.10.0)(magicast@0.5.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3): dependencies: '@prisma/config': 7.3.0(magicast@0.5.1) '@prisma/dev': 0.20.0(typescript@5.9.3) @@ -10724,7 +10721,7 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - unstorage@1.17.2(db0@0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3))(ioredis@5.8.2): + unstorage@1.17.2(db0@0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3))(ioredis@5.8.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -10735,7 +10732,7 @@ snapshots: ofetch: 1.5.1 ufo: 1.6.1 optionalDependencies: - db0: 0.3.4(@electric-sql/pglite@0.3.15)(better-sqlite3@12.8.0)(mysql2@3.15.3) + db0: 0.3.4(@electric-sql/pglite@0.3.2)(better-sqlite3@11.10.0)(mysql2@3.15.3) ioredis: 5.8.2 untun@0.1.3: @@ -11009,7 +11006,6 @@ snapshots: zeptomatch@2.1.0: dependencies: grammex: 3.1.11 - graphmatch: 1.1.1 zip-stream@6.0.1: dependencies: diff --git a/prisma/schema/schema.prisma b/prisma/schema/schema.prisma index 0617bab..2799d52 100644 --- a/prisma/schema/schema.prisma +++ b/prisma/schema/schema.prisma @@ -62,3 +62,14 @@ model Verification { @@map("verification") } + +model TrainingCertificate { + id Int @id @default(autoincrement()) + name String + email String + fileUrl String + status String @default("PENDING") + createdAt DateTime @default(now()) +} + + diff --git a/prisma/schema/volunteer.prisma b/prisma/schema/volunteer.prisma index d0ad539..844db65 100644 --- a/prisma/schema/volunteer.prisma +++ b/prisma/schema/volunteer.prisma @@ -13,6 +13,7 @@ model Volunteer { events RSVP[] emailVerified Boolean @default(false) + zoomVerified Boolean @default(false) imageURL String? createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt diff --git a/server/api/admin/training.get.ts b/server/api/admin/training.get.ts new file mode 100644 index 0000000..35e5f29 --- /dev/null +++ b/server/api/admin/training.get.ts @@ -0,0 +1,8 @@ +import prisma from "~~/server/utils/prisma"; + +export default defineEventHandler(async () => { + return await prisma.trainingCertificate.findMany({ + where: { status: "PENDING" } + }); +}); + diff --git a/server/api/admin/training.post.ts b/server/api/admin/training.post.ts new file mode 100644 index 0000000..c06e3f3 --- /dev/null +++ b/server/api/admin/training.post.ts @@ -0,0 +1,14 @@ +import prisma from "~~/server/utils/prisma"; + +export default defineEventHandler(async (event) => { + const body = await readBody(event); + + return await prisma.trainingCertificate.create({ + data: { + name: body.name, + email: body.email, + fileUrl: "", + status: "PENDING" + } + }); +}); \ No newline at end of file diff --git a/server/api/admin/volunteer.delete.ts b/server/api/admin/volunteer.delete.ts new file mode 100644 index 0000000..016dfaf --- /dev/null +++ b/server/api/admin/volunteer.delete.ts @@ -0,0 +1,9 @@ +import prisma from "~~/server/utils/prisma"; + +export default defineEventHandler(async (event) => { + const body = await readBody(event) + + return await prisma.volunteer.delete({ + where: { id: body.id } + }) +}) diff --git a/server/api/admin/volunteer.get.ts b/server/api/admin/volunteer.get.ts new file mode 100644 index 0000000..b6b0dfa --- /dev/null +++ b/server/api/admin/volunteer.get.ts @@ -0,0 +1,11 @@ +import prisma from "~~/server/utils/prisma"; + +export default defineEventHandler(async () => { + return await prisma.volunteer.findMany({ + select: { + id: true, + name: true, + zoomVerified: true + } + }); +}); diff --git a/server/api/admin/volunteer.patch.ts b/server/api/admin/volunteer.patch.ts new file mode 100644 index 0000000..1cb1d6c --- /dev/null +++ b/server/api/admin/volunteer.patch.ts @@ -0,0 +1,14 @@ +import prisma from "~~/server/utils/prisma"; + +export default defineEventHandler(async (event) => { + const body = await readBody(event); + + return await prisma.trainingCertificate.update({ + where: { + id: body.id + }, + data: { + status: body.verified ? "APPROVED" : "PENDING" + } + }); +}); \ No newline at end of file