From 78942e95e1b277f8f56eb0767295954904fbcd78 Mon Sep 17 00:00:00 2001 From: titver968 Date: Wed, 21 May 2025 08:31:07 +0200 Subject: [PATCH] schulart und Noten in fronend. Erste versuch Zeitraum in backend --- package-lock.json | 91 ++++++++----------- package.json | 4 +- .../migration.sql | 45 +++++++++ prisma/schema.prisma | 13 ++- src/routes/+page.svelte | 24 +++-- src/routes/admin/+page.svelte | 9 +- src/routes/admin/zeitraum/+page.server.ts | 8 ++ src/routes/admin/zeitraum/+page.svelte | 50 ++++++++++ src/routes/api/admin/zeitraum/+server.ts | 22 +++++ src/routes/api/anmelden/+server.ts | 1 - 10 files changed, 199 insertions(+), 68 deletions(-) create mode 100644 prisma/migrations/20250520124044_add_praktikumszeitraum/migration.sql create mode 100644 src/routes/admin/zeitraum/+page.server.ts create mode 100644 src/routes/admin/zeitraum/+page.svelte create mode 100644 src/routes/api/admin/zeitraum/+server.ts diff --git a/package-lock.json b/package-lock.json index ebdaf6a..b063bee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "praktikum", "version": "0.0.1", "dependencies": { - "@prisma/client": "^6.7.0", + "@prisma/client": "^6.8.2", "@sveltejs/adapter-node": "^5.2.12", "bcryptjs": "^3.0.2" }, @@ -28,7 +28,7 @@ "postcss": "^8.5.3", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", - "prisma": "^6.7.0", + "prisma": "^6.8.2", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwindcss": "^3.4.17", @@ -859,9 +859,9 @@ "license": "MIT" }, "node_modules/@prisma/client": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.7.0.tgz", - "integrity": "sha512-+k61zZn1XHjbZul8q6TdQLpuI/cvyfil87zqK2zpreNIXyXtpUv3+H/oM69hcsFcZXaokHJIzPAt5Z8C8eK2QA==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.8.2.tgz", + "integrity": "sha512-5II+vbyzv4si6Yunwgkj0qT/iY0zyspttoDrL3R4BYgLdp42/d2C8xdi9vqkrYtKt9H32oFIukvyw3Koz5JoDg==", "hasInstallScript": true, "license": "Apache-2.0", "engines": { @@ -881,64 +881,63 @@ } }, "node_modules/@prisma/config": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.7.0.tgz", - "integrity": "sha512-di8QDdvSz7DLUi3OOcCHSwxRNeW7jtGRUD2+Z3SdNE3A+pPiNT8WgUJoUyOwJmUr5t+JA2W15P78C/N+8RXrOA==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.8.2.tgz", + "integrity": "sha512-ZJY1fF4qRBPdLQ/60wxNtX+eu89c3AkYEcP7L3jkp0IPXCNphCYxikTg55kPJLDOG6P0X+QG5tCv6CmsBRZWFQ==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "esbuild": ">=0.12 <1", - "esbuild-register": "3.6.0" + "jiti": "2.4.2" } }, "node_modules/@prisma/debug": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.7.0.tgz", - "integrity": "sha512-RabHn9emKoYFsv99RLxvfG2GHzWk2ZI1BuVzqYtmMSIcuGboHY5uFt3Q3boOREM9de6z5s3bQoyKeWnq8Fz22w==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.8.2.tgz", + "integrity": "sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.7.0.tgz", - "integrity": "sha512-3wDMesnOxPrOsq++e5oKV9LmIiEazFTRFZrlULDQ8fxdub5w4NgRBoxtWbvXmj2nJVCnzuz6eFix3OhIqsZ1jw==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.8.2.tgz", + "integrity": "sha512-XqAJ//LXjqYRQ1RRabs79KOY4+v6gZOGzbcwDQl0D6n9WBKjV7qdrbd042CwSK0v0lM9MSHsbcFnU2Yn7z8Zlw==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.7.0", - "@prisma/engines-version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed", - "@prisma/fetch-engine": "6.7.0", - "@prisma/get-platform": "6.7.0" + "@prisma/debug": "6.8.2", + "@prisma/engines-version": "6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e", + "@prisma/fetch-engine": "6.8.2", + "@prisma/get-platform": "6.8.2" } }, "node_modules/@prisma/engines-version": { - "version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed.tgz", - "integrity": "sha512-EvpOFEWf1KkJpDsBCrih0kg3HdHuaCnXmMn7XFPObpFTzagK1N0Q0FMnYPsEhvARfANP5Ok11QyoTIRA2hgJTA==", + "version": "6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e.tgz", + "integrity": "sha512-Rkik9lMyHpFNGaLpPF3H5q5TQTkm/aE7DsGM5m92FZTvWQsvmi6Va8On3pWvqLHOt5aPUvFb/FeZTmphI4CPiQ==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.7.0.tgz", - "integrity": "sha512-zLlAGnrkmioPKJR4Yf7NfW3hftcvqeNNEHleMZK9yX7RZSkhmxacAYyfGsCcqRt47jiZ7RKdgE0Wh2fWnm7WsQ==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.8.2.tgz", + "integrity": "sha512-lCvikWOgaLOfqXGacEKSNeenvj0n3qR5QvZUOmPE2e1Eh8cMYSobxonCg9rqM6FSdTfbpqp9xwhSAOYfNqSW0g==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.7.0", - "@prisma/engines-version": "6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed", - "@prisma/get-platform": "6.7.0" + "@prisma/debug": "6.8.2", + "@prisma/engines-version": "6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e", + "@prisma/get-platform": "6.8.2" } }, "node_modules/@prisma/get-platform": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.7.0.tgz", - "integrity": "sha512-i9IH5lO4fQwnMLvQLYNdgVh9TK3PuWBfQd7QLk/YurnAIg+VeADcZDbmhAi4XBBDD+hDif9hrKyASu0hbjwabw==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.8.2.tgz", + "integrity": "sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.7.0" + "@prisma/debug": "6.8.2" } }, "node_modules/@rollup/plugin-commonjs": { @@ -2547,19 +2546,6 @@ "@esbuild/win32-x64": "0.25.2" } }, - "node_modules/esbuild-register": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", - "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "peerDependencies": { - "esbuild": ">=0.12 <1" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -4223,15 +4209,15 @@ } }, "node_modules/prisma": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.7.0.tgz", - "integrity": "sha512-vArg+4UqnQ13CVhc2WUosemwh6hr6cr6FY2uzDvCIFwH8pu8BXVv38PktoMLVjtX7sbYThxbnZF5YiR8sN2clw==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.8.2.tgz", + "integrity": "sha512-JNricTXQxzDtRS7lCGGOB4g5DJ91eg3nozdubXze3LpcMl1oWwcFddrj++Up3jnRE6X/3gB/xz3V+ecBk/eEGA==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/config": "6.7.0", - "@prisma/engines": "6.7.0" + "@prisma/config": "6.8.2", + "@prisma/engines": "6.8.2" }, "bin": { "prisma": "build/index.js" @@ -4239,9 +4225,6 @@ "engines": { "node": ">=18.18" }, - "optionalDependencies": { - "fsevents": "2.3.3" - }, "peerDependencies": { "typescript": ">=5.1.0" }, diff --git a/package.json b/package.json index 090b3c3..2a32354 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "postcss": "^8.5.3", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", - "prisma": "^6.7.0", + "prisma": "^6.8.2", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwindcss": "^3.4.17", @@ -43,7 +43,7 @@ "vite-plugin": "^0.0.0" }, "dependencies": { - "@prisma/client": "^6.7.0", + "@prisma/client": "^6.8.2", "@sveltejs/adapter-node": "^5.2.12", "bcryptjs": "^3.0.2" } diff --git a/prisma/migrations/20250520124044_add_praktikumszeitraum/migration.sql b/prisma/migrations/20250520124044_add_praktikumszeitraum/migration.sql new file mode 100644 index 0000000..0878969 --- /dev/null +++ b/prisma/migrations/20250520124044_add_praktikumszeitraum/migration.sql @@ -0,0 +1,45 @@ +-- CreateTable +CREATE TABLE "Praktikumszeitraum" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "bezeichnung" TEXT NOT NULL, + "startDatum" DATETIME NOT NULL, + "endDatum" DATETIME NOT NULL +); + +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Anmeldung" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "anrede" TEXT NOT NULL, + "vorname" TEXT NOT NULL, + "nachname" TEXT NOT NULL, + "geburtsdatum" TEXT NOT NULL, + "strasse" TEXT NOT NULL, + "hausnummer" TEXT NOT NULL, + "ort" TEXT NOT NULL, + "plz" TEXT NOT NULL, + "telefon" TEXT NOT NULL, + "email" TEXT NOT NULL, + "schulart" TEXT NOT NULL, + "zeitraum" TEXT NOT NULL, + "motivation" TEXT NOT NULL, + "praktikumId" INTEGER, + "wunsch1Id" INTEGER NOT NULL, + "wunsch2Id" INTEGER NOT NULL, + "wunsch3Id" INTEGER NOT NULL, + "timestamp" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "Anmeldung_praktikumId_fkey" FOREIGN KEY ("praktikumId") REFERENCES "Praktikumszeitraum" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "Anmeldung_wunsch1Id_fkey" FOREIGN KEY ("wunsch1Id") REFERENCES "Dienststelle" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "Anmeldung_wunsch2Id_fkey" FOREIGN KEY ("wunsch2Id") REFERENCES "Dienststelle" ("id") ON DELETE RESTRICT ON UPDATE CASCADE, + CONSTRAINT "Anmeldung_wunsch3Id_fkey" FOREIGN KEY ("wunsch3Id") REFERENCES "Dienststelle" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); +INSERT INTO "new_Anmeldung" ("anrede", "email", "geburtsdatum", "hausnummer", "id", "motivation", "nachname", "ort", "plz", "schulart", "strasse", "telefon", "timestamp", "vorname", "wunsch1Id", "wunsch2Id", "wunsch3Id", "zeitraum") SELECT "anrede", "email", "geburtsdatum", "hausnummer", "id", "motivation", "nachname", "ort", "plz", "schulart", "strasse", "telefon", "timestamp", "vorname", "wunsch1Id", "wunsch2Id", "wunsch3Id", "zeitraum" FROM "Anmeldung"; +DROP TABLE "Anmeldung"; +ALTER TABLE "new_Anmeldung" RENAME TO "Anmeldung"; +CREATE UNIQUE INDEX "Anmeldung_email_key" ON "Anmeldung"("email"); +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; + +-- CreateIndex +CREATE UNIQUE INDEX "Praktikumszeitraum_bezeichnung_key" ON "Praktikumszeitraum"("bezeichnung"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6b71f41..45e2a9a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -23,6 +23,14 @@ model Dienststelle { anmeldungenWunsch3 Anmeldung[] @relation("Wunsch3") } +model Praktikumszeitraum { + id Int @id @default(autoincrement()) + bezeichnung String @unique // z. B. "Frühjahr 2025" + startDatum DateTime + endDatum DateTime + anmeldungen Anmeldung[] +} + model Anmeldung { id Int @id @default(autoincrement()) anrede String @@ -36,8 +44,11 @@ model Anmeldung { telefon String email String @unique schulart String - zeitraum String motivation String + + praktikumId Int + praktikum Praktikumszeitraum @relation(fields: [praktikumId], references: [id]) + wunsch1Id Int wunsch2Id Int diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 90d9531..f2ae043 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -93,11 +93,19 @@ const deutsch = parseInt(deutschNote); const mathe = parseInt(matheNote); - - if (isNaN(deutsch) || isNaN(mathe) || deutsch > 3 && mathe > 3) { - ablehnungHinweis = 'Du brauchst mindestens eine 3 in Deutsch oder Mathematik, um dich bewerben zu können. Bewirb dich gern erneut, wenn du die Voraussetzung erfüllst.'; - showAblehnungModal = true; - return; + + if (['Gymnasium', 'Gymnasialzweig'].includes(schulart) ) { + if (isNaN(deutsch) || isNaN(mathe) || deutsch > 4 && mathe > 4) { + ablehnungHinweis = 'Du brauchst mindestens eine 4 in Deutsch oder Mathematik, um dich bewerben zu können. Bewirb dich gern erneut, wenn du die Voraussetzung erfüllst.'; + showAblehnungModal = true; + return; + } + } else { + if (isNaN(deutsch) || isNaN(mathe) || deutsch > 3 && mathe > 3) { + ablehnungHinweis = 'Du brauchst mindestens eine 3 in Deutsch oder Mathematik, um dich bewerben zu können. Bewirb dich gern erneut, wenn du die Voraussetzung erfüllst.'; + showAblehnungModal = true; + return; + } } if (sozialverhalten === 'Entspricht den Erwartungen mit Einschränkungen') { @@ -151,11 +159,13 @@
diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte index b694b23..ea6efc8 100644 --- a/src/routes/admin/+page.svelte +++ b/src/routes/admin/+page.svelte @@ -33,13 +33,16 @@

Admin-Bereich

diff --git a/src/routes/admin/zeitraum/+page.server.ts b/src/routes/admin/zeitraum/+page.server.ts new file mode 100644 index 0000000..a39bc2d --- /dev/null +++ b/src/routes/admin/zeitraum/+page.server.ts @@ -0,0 +1,8 @@ +import type { PageServerLoad } from './$types'; +import { redirect } from '@sveltejs/kit'; + +export const load: PageServerLoad = async ({ cookies }) => { + if (cookies.get('admin_session') !== 'true') { + throw redirect(303, '/admin'); // zurück zur Login-Seite + } +}; \ No newline at end of file diff --git a/src/routes/admin/zeitraum/+page.svelte b/src/routes/admin/zeitraum/+page.svelte new file mode 100644 index 0000000..903d8e6 --- /dev/null +++ b/src/routes/admin/zeitraum/+page.svelte @@ -0,0 +1,50 @@ + + +

🗓 Praktikumszeiträume verwalten

+ +
+ +
+ + +
+ +
+ +

📋 Bereits erfasste Zeiträume

+
+ {#each zeitraeume as z} +
+

{z.bezeichnung}

+

+ {new Date(z.startDatum).toLocaleDateString()} – {new Date(z.endDatum).toLocaleDateString()} +

+
+ {/each} +
+ + \ No newline at end of file diff --git a/src/routes/api/admin/zeitraum/+server.ts b/src/routes/api/admin/zeitraum/+server.ts new file mode 100644 index 0000000..ee955e0 --- /dev/null +++ b/src/routes/api/admin/zeitraum/+server.ts @@ -0,0 +1,22 @@ +import { db } from '$lib/server/prisma' + +export async function GET() { + const zeitraeume = await db.praktikumszeitraum.findMany({ + orderBy: { startDatum: 'asc' } + }) + return new Response(JSON.stringify(zeitraeume)) +} + +export async function POST({ request }) { + const { bezeichnung, startDatum, endDatum } = await request.json() + + await db.praktikumszeitraum.create({ + data: { + bezeichnung, + startDatum: new Date(startDatum), + endDatum: new Date(endDatum) + } + }) + + return new Response('OK') +} \ No newline at end of file diff --git a/src/routes/api/anmelden/+server.ts b/src/routes/api/anmelden/+server.ts index c8d3c18..cfa808f 100644 --- a/src/routes/api/anmelden/+server.ts +++ b/src/routes/api/anmelden/+server.ts @@ -38,7 +38,6 @@ export async function POST({ request }) { telefon: get('telefon'), email: get('email'), schulart: get('schulart'), - zeitraum: get('zeitraum'), motivation: get('motivation'), wunsch1Id: parseInt(get('wunsch1Id')), wunsch2Id: parseInt(get('wunsch2Id')),