From 89a635a444a3d7ea009156db2cc02176c19d5bfa Mon Sep 17 00:00:00 2001 From: core Date: Wed, 28 Feb 2024 13:38:49 -0500 Subject: [PATCH] admin page work: facility creation/deletion --- src/routes/admin/+layout.server.ts | 2 + src/routes/admin/+layout.svelte | 4 + src/routes/admin/+page.server.ts | 19 +++ src/routes/admin/+page.svelte | 67 ++++++++ src/routes/admin/facilities/+page.server.ts | 57 +++++++ src/routes/admin/facilities/+page.svelte | 167 ++++++++++++++++++++ src/routes/admin/facilities/actions.svelte | 39 +++++ src/routes/admin/facilities/schema.ts | 10 ++ 8 files changed, 365 insertions(+) create mode 100644 src/routes/admin/+layout.svelte create mode 100644 src/routes/admin/+page.server.ts create mode 100644 src/routes/admin/facilities/+page.server.ts create mode 100644 src/routes/admin/facilities/+page.svelte create mode 100644 src/routes/admin/facilities/actions.svelte create mode 100644 src/routes/admin/facilities/schema.ts diff --git a/src/routes/admin/+layout.server.ts b/src/routes/admin/+layout.server.ts index a4b63b0..105ee50 100644 --- a/src/routes/admin/+layout.server.ts +++ b/src/routes/admin/+layout.server.ts @@ -8,4 +8,6 @@ export const load: LayoutServerLoad = async ({ cookies }) => { if (!user.isSiteAdmin) { redirect(307, "/"); } + + return { user }; }; diff --git a/src/routes/admin/+layout.svelte b/src/routes/admin/+layout.svelte new file mode 100644 index 0000000..1157b7a --- /dev/null +++ b/src/routes/admin/+layout.svelte @@ -0,0 +1,4 @@ +
+ +
diff --git a/src/routes/admin/+page.server.ts b/src/routes/admin/+page.server.ts new file mode 100644 index 0000000..6f09890 --- /dev/null +++ b/src/routes/admin/+page.server.ts @@ -0,0 +1,19 @@ +import type { PageServerLoad } from "./$types"; +import prisma from "$lib/prisma"; + +export const load: PageServerLoad = async () => { + return { + totalUsers: await prisma.user.count(), + totalFacilities: await prisma.facility.count(), + divisionStaffAuthorizations: await prisma.userFacilityAssignment.count({ + where: { + assignmentType: "DivisionalStaff" + } + }), + siteAdministrators: await prisma.user.count({ + where: { + isSiteAdmin: true + } + }) + } +} diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte index e69de29..acf8254 100644 --- a/src/routes/admin/+page.svelte +++ b/src/routes/admin/+page.svelte @@ -0,0 +1,67 @@ + + +
+

Site Administration

+
+ +
+ + + Users + + + +
{data.totalUsers}
+ Manage Users → +
+
+ + + Facilities + + + +
{data.totalFacilities}
+ Manage Facilities → +
+
+ + + Staff Authorizations + + + +
{data.divisionStaffAuthorizations}
+ Manage Staff Authorizations → +
+
+ + + Site Administrators + + + +
{data.siteAdministrators}
+ Manage Site Administrators → +
+
+
+ +
+ +
diff --git a/src/routes/admin/facilities/+page.server.ts b/src/routes/admin/facilities/+page.server.ts new file mode 100644 index 0000000..acffdbf --- /dev/null +++ b/src/routes/admin/facilities/+page.server.ts @@ -0,0 +1,57 @@ +import type { PageServerLoad, Actions } from "./$types"; +import prisma from "$lib/prisma"; +import {superValidate} from "sveltekit-superforms/server"; +import {formSchema} from "./schema"; +import {fail} from "@sveltejs/kit"; +import {loadUserData} from "$lib/auth"; + +export const load: PageServerLoad = async ({ parent }) => { + let { user } = await parent(); + if (!user.isSiteAdmin) { return {}; } + + return { + facilities: await prisma.facility.findMany()!, + form: await superValidate(formSchema) + } +} + +export const actions: Actions = { + create: async (event) => { + let form = await superValidate(event, formSchema); + + if (!form.valid) { + return fail(400, { form }); + } + + let { user } = await loadUserData(event.cookies, null); + if (!user.isSiteAdmin) { + return fail(400, { form }); + } + + await prisma.facility.create({ + data: { + id: form.data.id.toString(), + name: form.data.name.toString(), + dotnetId: form.data.dotnetId.toString(), + dotnetType: form.data.dotnetType.toString() === 'Division' ? 'Division' : 'Subdivision', + contactEmail: "todo@vatsim.me", + website: "https://vatsim.me" + } + }); + + return { + form + } + }, + delete: async (event) => { + let { user } = await loadUserData(event.cookies, null); + if (!user.isSiteAdmin) { + return fail(400, {}); + } + await prisma.facility.delete({ + where: { + id: (await event.request.formData()).get("id")!.toString() + } + }); + } +} diff --git a/src/routes/admin/facilities/+page.svelte b/src/routes/admin/facilities/+page.svelte new file mode 100644 index 0000000..efa9093 --- /dev/null +++ b/src/routes/admin/facilities/+page.svelte @@ -0,0 +1,167 @@ + + +
+

Manage Facilities

+ +
+ + + + {#each $headerRows as headerRow} + + + {#each headerRow.cells as cell (cell.id)} + + + + + + {/each} + + + {/each} + + + {#each $pageRows as row (row.id)} + + + {#each row.cells as cell (cell.id)} + + + + + + {/each} + + + {/each} + + + + + + + New Facility + + +
+ + + + Facility ID + + + + + + + Facility Name + + + + + + + .NET ID + + + + + + + .NET Type + + + + Division + Subdivision + + + + + + + + Create + + +
+
+
diff --git a/src/routes/admin/facilities/actions.svelte b/src/routes/admin/facilities/actions.svelte new file mode 100644 index 0000000..9a4b2f6 --- /dev/null +++ b/src/routes/admin/facilities/actions.svelte @@ -0,0 +1,39 @@ + + + + + Remove + + + Are you sure? + + This is an incredibly destructive operation. All data associated with this facility and it's membership information will be permanently obliterated! + + + + + + + + diff --git a/src/routes/admin/facilities/schema.ts b/src/routes/admin/facilities/schema.ts new file mode 100644 index 0000000..58c9c85 --- /dev/null +++ b/src/routes/admin/facilities/schema.ts @@ -0,0 +1,10 @@ +import { z } from "zod"; + +export const formSchema = z.object({ + id: z.string(), + name: z.string(), + dotnetId: z.string(), + dotnetType: z.enum(["Subdivision", "Division"]), +}); + +export type FormSchema = typeof formSchema;