diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 23a0deb..963d672 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -33,10 +33,11 @@ model Dienststelle { } model Praktikumszeitraum { - id Int @id @default(autoincrement()) - bezeichnung String @unique // z. B. "Frühjahr 2025" + id Int @id @default(autoincrement()) + bezeichnung String @unique // z. B. "Frühjahr 2025" startDatum DateTime endDatum DateTime + anmeldungen Anmeldung[] @relation("PraktikumszeitraumAnmeldungen") } enum Status { @@ -46,25 +47,42 @@ enum Status { } model Anmeldung { - id Int @id @default(autoincrement()) - anrede String - vorname String - nachname String - email String - noteDeutsch String? - noteMathe String? + id Int @id @default(autoincrement()) + anrede String + vorname String + nachname String + geburtsdatum String // Neu hinzugefügt + strasse String // Neu hinzugefügt + hausnummer String // Neu hinzugefügt + ort String // Neu hinzugefügt + plz String // Neu hinzugefügt + telefon String // Neu hinzugefügt + email String + schulart String // Neu hinzugefügt + schulklasse String? // Neu hinzugefügt + noteDeutsch Int // Geändert von String zu Int + noteMathe Int // Geändert von String zu Int sozialverhalten String? - status Status @default(OFFEN) - zugewiesenId Int? // ID der zugewiesenen Dienststelle - zugewiesen Dienststelle? @relation("Zugewiesen", fields: [zugewiesenId], references: [id]) - wunsch1Id Int? - wunsch1 Dienststelle? @relation("Wunsch1", fields: [wunsch1Id], references: [id]) - wunsch2Id Int? - wunsch2 Dienststelle? @relation("Wunsch2", fields: [wunsch2Id], references: [id]) - wunsch3Id Int? - wunsch3 Dienststelle? @relation("Wunsch3", fields: [wunsch3Id], references: [id]) - timestamp BigInt - pdfs PdfDatei[] + motivation String? // Neu hinzugefügt + alter Int? // Neu hinzugefügt für Altersvalidierung + status Status @default(OFFEN) + + // Praktikumszeitraum Relation + praktikumId Int? + praktikum Praktikumszeitraum? @relation("PraktikumszeitraumAnmeldungen", fields: [praktikumId], references: [id]) + + // Dienststellen Relationen + zugewiesenId Int? + zugewiesen Dienststelle? @relation("Zugewiesen", fields: [zugewiesenId], references: [id]) + wunsch1Id Int? + wunsch1 Dienststelle? @relation("Wunsch1", fields: [wunsch1Id], references: [id]) + wunsch2Id Int? + wunsch2 Dienststelle? @relation("Wunsch2", fields: [wunsch2Id], references: [id]) + wunsch3Id Int? + wunsch3 Dienststelle? @relation("Wunsch3", fields: [wunsch3Id], references: [id]) + + timestamp DateTime @default(now()) + pdfs PdfDatei[] @@map("anmeldungen") } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index c2e4afa..1d9c8a7 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -33,6 +33,43 @@ let ablehnungHinweis = ''; let showAblehnungModal = false; let alter = ''; + $: { + if (geburtsdatum && zeitraum && zeitraeume.length > 0) { + const gewaehlterZeitraum = zeitraeume.find(z => z.id == zeitraum); + if (gewaehlterZeitraum) { + const geburt = new Date(geburtsdatum); + const praktikumStart = new Date(gewaehlterZeitraum.startDatum); + + let altersberechnung = praktikumStart.getFullYear() - geburt.getFullYear(); + const monthDiff = praktikumStart.getMonth() - geburt.getMonth(); + + if (monthDiff < 0 || (monthDiff === 0 && praktikumStart.getDate() < geburt.getDate())) { + altersberechnung--; + } + alter = altersberechnung.toString(); + } + } + } + + $: filteredDienststellen = (dienststellen ?? []).filter(d => { + if (d.plaetze <= 0) return false; + + // PK Mitte nur anzeigen wenn mindestens 18 Jahre alt + if (d.name.includes('PK Mitte') || d.name.toLowerCase().includes('polizeikommissariat mitte')) { + return parseInt(alter) >= 18; + } + return true; + } + ); + + $: filteredZeitraeume = (zeitraeume ?? []).filter(zeitraum => { + const heute = new Date(); + const startDatum = new Date(zeitraum.startDatum); + + // Nur Zeiträume anzeigen, die noch nicht gestartet haben + return startDatum > heute; + }); + let startDatum = ''; $: hideSozialVerhalten = @@ -107,11 +144,19 @@ data.append('noteMathe', noteMathe); data.append('sozialverhalten', sozialverhalten); data.append('schulklasse', schulklasse); + data.append('alter', alter); for (const pdf of pdfDateien) { data.append('pdfs', pdf); } + const altersWert = parseInt(alter); + if (isNaN(altersWert) || altersWert < 14) { + ablehnungHinweis = 'Du musst mindestens 14 Jahre alt sein, um ein Praktikum beginnen zu können. Bewirb dich gern erneut, wenn du das Mindestalter erreicht hast.'; + showAblehnungModal = true; + return; + } + const deutsch = parseInt(noteDeutsch); const mathe = parseInt(noteMathe); @@ -216,7 +261,7 @@
- {#each (dienststellen ?? []).filter(d => d.plaetze > 0) as d} + {#each filteredDienststellen as d} {/each} @@ -309,6 +350,17 @@
{/if} + {#if alter} +
+ Alter zu Praktikumsbeginn: {alter} Jahre + {#if parseInt(alter) < 14} + + (Mindestalter 14 Jahre erforderlich) + + {/if} +
+ {/if} + {#if fehler}

{fehler}

{/if} diff --git a/src/routes/api/anmelden/+server.ts b/src/routes/api/anmelden/+server.ts index c020b8a..38f35c9 100644 --- a/src/routes/api/anmelden/+server.ts +++ b/src/routes/api/anmelden/+server.ts @@ -5,14 +5,16 @@ import { json } from '@sveltejs/kit'; const prisma = new PrismaClient(); -export async function POST({ request }) { +export async function POST({ request }: RequestEvent) { const formData = await request.formData(); const get = (key: string) => formData.get(key)?.toString() ?? ''; - const pdfs = formData.getAll('pdfs') as File[]; + // const pdfs = formData.getAll('pdfs') as File[]; + const pdfFiles = formData.getAll('pdfs') as File[]; + const pdfData = []; - const gespeichertePfade: string[] = []; + // const gespeichertePfade: string[] = []; const noteDeutsch = Number(get('noteDeutsch')); const noteMathe = Number(get('noteMathe')); @@ -20,46 +22,57 @@ export async function POST({ request }) { return json({ error: 'Bitte gib gültige Noten an.' }, { status: 400 }); } - for (const pdf of pdfs) { - if (pdf.size > 0 && pdf.type === 'application/pdf') { - const buffer = Buffer.from(await pdf.arrayBuffer()); - const dateiname = `${randomUUID()}.pdf`; - const pfad = `/uploads/${dateiname}`; - await writeFile(`static${pfad}`, buffer); - gespeichertePfade.push(pfad); + for (const file of pdfFiles) { + if (file.size > 0 && file.type === 'application/pdf') { + const buffer = Buffer.from(await file.arrayBuffer()); + const filename = `${randomUUID()}.pdf`; + const uploadPath = `/uploads/${filename}`; + await writeFile(`static${uploadPath}`, buffer); + pdfData.push({ pfad: uploadPath }); } } try { - await prisma.anmeldung.create({ + const anmeldung = await prisma.anmeldung.create({ data: { - anrede: get('anrede'), - vorname: get('vorname'), - nachname: get('nachname'), - geburtsdatum: get('geburtsdatum'), - strasse: get('strasse'), - hausnummer: get('hausnummer'), - ort: get('ort'), - plz: get('plz'), - telefon: get('telefon'), - email: get('email'), - noteDeutsch, - noteMathe, - sozialverhalten: get('sozialverhalten'), - praktikumId: Number(formData.get('praktikumId')), - schulart: get('schulart'), - motivation: get('motivation'), - wunsch1Id: parseInt(get('wunsch1Id')), - wunsch2Id: parseInt(get('wunsch2Id')), - wunsch3Id: parseInt(get('wunsch3Id')), + // Persönliche Daten + anrede: formData.get('anrede') as string, + vorname: formData.get('vorname') as string, + nachname: formData.get('nachname') as string, + geburtsdatum: formData.get('geburtsdatum') as string, + // Adresse + strasse: formData.get('strasse') as string, + hausnummer: formData.get('hausnummer') as string, + ort: formData.get('ort') as string, + plz: formData.get('plz') as string, + // Kontakt + telefon: formData.get('telefon') as string, + email: formData.get('email') as string, + // Schule + schulart: formData.get('schulart') as string, + schulklasse: formData.get('schulklasse') as string, + noteDeutsch: parseInt(formData.get('noteDeutsch') as string), + noteMathe: parseInt(formData.get('noteMathe') as string), + sozialverhalten: formData.get('sozialverhalten') as string || null, + // Praktikum + praktikumId: parseInt(formData.get('zeitraum') as string), + motivation: formData.get('motivation') as string || '', + // Wünsche + wunsch1Id: parseInt(formData.get('wunsch1Id') as string), + wunsch2Id: parseInt(formData.get('wunsch2Id') as string), + wunsch3Id: parseInt(formData.get('wunsch3Id') as string), + // Alter (falls vom Frontend gesendet) + alter: formData.get('alter') ? parseInt(formData.get('alter') as string) : null, + // System + zugewiesenId: null, + // timestamp wird automatisch durch @default(now()) gesetzt pdfs: { - create: gespeichertePfade.map((pfad) => ({ pfad })) - }, - zugewiesenId: null + create: pdfData + } } }); - return json({ success: true }); + return json({ success: true, anmeldung }); } catch (err: unknown) { if (err instanceof Error && (err as { code?: string }).code === 'P2002') { return json({ error: 'Diese E-Mail wurde bereits verwendet.' }, { status: 400 });