diff --git a/prisma/migrations/20250726135031_on_delete/migration.sql b/prisma/migrations/20250726135031_on_delete/migration.sql new file mode 100644 index 0000000..163ace0 --- /dev/null +++ b/prisma/migrations/20250726135031_on_delete/migration.sql @@ -0,0 +1,14 @@ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_PdfDatei" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "pfad" TEXT NOT NULL, + "anmeldungId" INTEGER NOT NULL, + CONSTRAINT "PdfDatei_anmeldungId_fkey" FOREIGN KEY ("anmeldungId") REFERENCES "anmeldungen" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); +INSERT INTO "new_PdfDatei" ("anmeldungId", "id", "pfad") SELECT "anmeldungId", "id", "pfad" FROM "PdfDatei"; +DROP TABLE "PdfDatei"; +ALTER TABLE "new_PdfDatei" RENAME TO "PdfDatei"; +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/prisma/migrations/20250726135957_remove_processed_by/migration.sql b/prisma/migrations/20250726135957_remove_processed_by/migration.sql new file mode 100644 index 0000000..9b6ad01 --- /dev/null +++ b/prisma/migrations/20250726135957_remove_processed_by/migration.sql @@ -0,0 +1,50 @@ +/* + Warnings: + + - You are about to drop the column `processedBy` on the `anmeldungen` table. All the data in the column will be lost. + +*/ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_anmeldungen" ( + "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, + "schulklasse" TEXT, + "noteDeutsch" INTEGER NOT NULL, + "noteMathe" INTEGER NOT NULL, + "sozialverhalten" TEXT, + "motivation" TEXT, + "alter" INTEGER, + "status" TEXT NOT NULL DEFAULT 'OFFEN', + "processedAt" DATETIME, + "praktikumId" INTEGER, + "zugewiesenId" INTEGER, + "wunsch1Id" INTEGER, + "wunsch2Id" INTEGER, + "wunsch3Id" INTEGER, + "timestamp" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "anmeldungen_praktikumId_fkey" FOREIGN KEY ("praktikumId") REFERENCES "Praktikumszeitraum" ("id") ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT "anmeldungen_zugewiesenId_fkey" FOREIGN KEY ("zugewiesenId") REFERENCES "Dienststelle" ("id") ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT "anmeldungen_wunsch1Id_fkey" FOREIGN KEY ("wunsch1Id") REFERENCES "Dienststelle" ("id") ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT "anmeldungen_wunsch2Id_fkey" FOREIGN KEY ("wunsch2Id") REFERENCES "Dienststelle" ("id") ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT "anmeldungen_wunsch3Id_fkey" FOREIGN KEY ("wunsch3Id") REFERENCES "Dienststelle" ("id") ON DELETE SET NULL ON UPDATE CASCADE +); +INSERT INTO "new_anmeldungen" ("alter", "anrede", "email", "geburtsdatum", "hausnummer", "id", "motivation", "nachname", "noteDeutsch", "noteMathe", "ort", "plz", "praktikumId", "processedAt", "schulart", "schulklasse", "sozialverhalten", "status", "strasse", "telefon", "timestamp", "vorname", "wunsch1Id", "wunsch2Id", "wunsch3Id", "zugewiesenId") SELECT "alter", "anrede", "email", "geburtsdatum", "hausnummer", "id", "motivation", "nachname", "noteDeutsch", "noteMathe", "ort", "plz", "praktikumId", "processedAt", "schulart", "schulklasse", "sozialverhalten", "status", "strasse", "telefon", "timestamp", "vorname", "wunsch1Id", "wunsch2Id", "wunsch3Id", "zugewiesenId" FROM "anmeldungen"; +DROP TABLE "anmeldungen"; +ALTER TABLE "new_anmeldungen" RENAME TO "anmeldungen"; +CREATE INDEX "anmeldungen_status_idx" ON "anmeldungen"("status"); +CREATE INDEX "anmeldungen_processedAt_idx" ON "anmeldungen"("processedAt"); +CREATE INDEX "anmeldungen_zugewiesenId_idx" ON "anmeldungen"("zugewiesenId"); +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/prisma/migrations/20250726142352_plaetzze_not_negativ/migration.sql b/prisma/migrations/20250726142352_plaetzze_not_negativ/migration.sql new file mode 100644 index 0000000..9d616ce --- /dev/null +++ b/prisma/migrations/20250726142352_plaetzze_not_negativ/migration.sql @@ -0,0 +1,14 @@ +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Dienststelle" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" TEXT NOT NULL, + "plaetze" INTEGER NOT NULL DEFAULT 0 +); +INSERT INTO "new_Dienststelle" ("id", "name", "plaetze") SELECT "id", "name", "plaetze" FROM "Dienststelle"; +DROP TABLE "Dienststelle"; +ALTER TABLE "new_Dienststelle" RENAME TO "Dienststelle"; +CREATE UNIQUE INDEX "Dienststelle_name_key" ON "Dienststelle"("name"); +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b4ed039..b8af39b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -25,7 +25,7 @@ model EmailConfig { model Dienststelle { id Int @id @default(autoincrement()) name String @unique - plaetze Int + plaetze Int @default(0) anmeldungenWunsch1 Anmeldung[] @relation("Wunsch1") anmeldungenWunsch2 Anmeldung[] @relation("Wunsch2") anmeldungenWunsch3 Anmeldung[] @relation("Wunsch3") @@ -70,7 +70,7 @@ model Anmeldung { status Status @default(OFFEN) // Neue Felder für Status-Tracking - processedBy String? // Wer bearbeitet die Anmeldung + // processedBy String? // Wer bearbeitet die Anmeldung processedAt DateTime? // Wann wurde sie bearbeitet // Praktikumszeitraum Relation @@ -100,6 +100,6 @@ model Anmeldung { model PdfDatei { id Int @id @default(autoincrement()) pfad String - anmeldung Anmeldung @relation(fields: [anmeldungId], references: [id]) + anmeldung Anmeldung @relation(fields: [anmeldungId], references: [id], onDelete: Cascade) anmeldungId Int } \ No newline at end of file diff --git a/src/lib/components/AnmeldungenTable.svelte b/src/lib/components/AnmeldungenTable.svelte index 5e3a462..62657aa 100644 --- a/src/lib/components/AnmeldungenTable.svelte +++ b/src/lib/components/AnmeldungenTable.svelte @@ -33,12 +33,13 @@ }); } + // Vereinfachte Logik ohne processing Status function canBeAccepted(status: string): boolean { - return status === 'pending' || status === 'processing'; + return status === 'pending'; } function canBeRejected(status: string): boolean { - return status === 'pending' || status === 'processing'; + return status === 'pending'; } @@ -46,62 +47,51 @@ - - - - - - - - {#each anmeldungen as anmeldung (anmeldung.id)} - - - + + - - - - - - - - - - - - {/each} diff --git a/src/routes/admin/anmeldungen/+page.svelte b/src/routes/admin/anmeldungen/+page.svelte index 2999187..4880952 100644 --- a/src/routes/admin/anmeldungen/+page.svelte +++ b/src/routes/admin/anmeldungen/+page.svelte @@ -20,10 +20,10 @@ wunsch3?: { id: number; name: string }; timestamp: number; id: number; - status?: 'pending' | 'accepted' | 'rejected' | 'processing'; // Neuer Status - assignedDienststelle?: { id: number; name: string }; // Zugewiesene Dienststelle - processedBy?: string; // Wer die Anmeldung bearbeitet - processedAt?: number; // Wann bearbeitet + status?: 'pending' | 'accepted' | 'rejected'; // processing entfernt + assignedDienststelle?: { id: number; name: string }; + processedBy?: string; + processedAt?: number; } interface EmailConfig { @@ -35,8 +35,8 @@ let isLoading = true; let error = ''; - // Filter für Status - let statusFilter: 'all' | 'pending' | 'accepted' | 'rejected' | 'processing' = 'all'; + // Filter für Status (processing entfernt) + let statusFilter: 'all' | 'pending' | 'accepted' | 'rejected' = 'all'; let filteredAnmeldungen: Anmeldung[] = []; // Dialog state @@ -63,11 +63,10 @@ Ihr Praktikumsteam`; let isLoadingEmailConfig = false; let isSavingEmailConfig = false; - // Status-Badge Funktionen + // Status-Badge Funktionen (processing entfernt) function getStatusColor(status: string): string { switch (status) { case 'pending': return 'bg-yellow-100 text-yellow-800'; - case 'processing': return 'bg-blue-100 text-blue-800'; case 'accepted': return 'bg-green-100 text-green-800'; case 'rejected': return 'bg-red-100 text-red-800'; default: return 'bg-gray-100 text-gray-800'; @@ -77,7 +76,6 @@ Ihr Praktikumsteam`; function getStatusText(status: string): string { switch (status) { case 'pending': return 'Offen'; - case 'processing': return 'In Bearbeitung'; case 'accepted': return 'Angenommen'; case 'rejected': return 'Abgelehnt'; default: return 'Unbekannt'; @@ -94,7 +92,7 @@ Ihr Praktikumsteam`; } $: { - filterAnmeldungen(); + anmeldungen, statusFilter, filterAnmeldungen(); } async function loadAnmeldungen() { @@ -105,42 +103,31 @@ Ihr Praktikumsteam`; const res = await fetch('/api/admin/anmeldungen'); if (!res.ok) { - throw new Error(`Fehler beim Laden: ${res.status}`); + const errorText = await res.text(); + console.error('❌ API Fehler:', res.status, errorText); + throw new Error(`Fehler beim Laden: ${res.status} - ${errorText}`); } - anmeldungen = await res.json(); - // Standardstatus setzen falls nicht vorhanden - anmeldungen = anmeldungen.map(a => ({ ...a, status: a.status || 'pending' })); + const data = await res.json(); + + // Prüfen ob es ein Array ist + if (!Array.isArray(data)) { + console.error('❌ Antwort ist kein Array:', data); + throw new Error('Antwort vom Server ist kein Array'); + } + + anmeldungen = data.map(a => { + return { ...a, status: a.status || 'pending' }; + }); + } catch (err) { error = err instanceof Error ? err.message : 'Unbekannter Fehler'; - console.error('Fehler beim Laden der Anmeldungen:', err); + console.error('❌ Frontend Fehler beim Laden der Anmeldungen:', err); } finally { isLoading = false; } } - async function setProcessingStatus(anmeldungId: number) { - try { - const res = await fetch(`/api/admin/anmeldungen?id=${anmeldungId}`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - action: 'set_processing', - processedBy: 'current_user' // Hier sollte der aktuelle Benutzer stehen - }) - }); - - if (!res.ok) { - throw new Error(`Fehler beim Setzen des Status: ${res.status}`); - } - - await loadAnmeldungen(); - } catch (err) { - error = err instanceof Error ? err.message : 'Fehler beim Setzen des Status'; - console.error(err); - } - } - async function loadEmailConfig() { try { isLoadingEmailConfig = true; @@ -193,16 +180,6 @@ Ihr Praktikumsteam`; const anmeldung = anmeldungen.find(a => a.id === event.detail.id); if (!anmeldung) return; - // Prüfen ob bereits bearbeitet wird - if (anmeldung.status === 'processing') { - if (!confirm('Diese Anmeldung wird bereits bearbeitet. Trotzdem fortfahren?')) { - return; - } - } - - // Status auf "in Bearbeitung" setzen - setProcessingStatus(event.detail.id); - availableWishes = [ anmeldung.wunsch1 && { id: anmeldung.wunsch1.id, name: `1. Wunsch: ${anmeldung.wunsch1.name}` }, anmeldung.wunsch2 && { id: anmeldung.wunsch2.id, name: `2. Wunsch: ${anmeldung.wunsch2.name}` }, @@ -265,15 +242,6 @@ Ihr Praktikumsteam`; } async function handleReject(event: CustomEvent<{id: number}>) { - const anmeldung = anmeldungen.find(a => a.id === event.detail.id); - - // Prüfen ob bereits bearbeitet wird - if (anmeldung?.status === 'processing') { - if (!confirm('Diese Anmeldung wird bereits bearbeitet. Trotzdem ablehnen?')) { - return; - } - } - if (!confirm('Diese Anmeldung wirklich ablehnen?')) return; try { @@ -316,10 +284,6 @@ Ihr Praktikumsteam`; function closeDialog() { showDialog = false; selectedAnmeldungId = null; - // Status zurücksetzen falls Dialog abgebrochen wird - if (selectedAnmeldungId) { - // Hier könnten Sie den Status zurück auf "pending" setzen - } } onMount(() => { @@ -341,7 +305,7 @@ Ihr Praktikumsteam`;
- +
@@ -374,8 +337,8 @@ Ihr Praktikumsteam`;
- -
+ +
@@ -394,24 +357,6 @@ Ihr Praktikumsteam`;
-
-
-
-
- - - -
-
-
-

In Bearbeitung

-

- {anmeldungen.filter(a => a.status === 'processing').length} -

-
-
-
-
diff --git a/src/routes/api/admin/anmeldungen/+server.ts b/src/routes/api/admin/anmeldungen/+server.ts index ef25cfb..961c7cd 100644 --- a/src/routes/api/admin/anmeldungen/+server.ts +++ b/src/routes/api/admin/anmeldungen/+server.ts @@ -1,4 +1,4 @@ -// src/routes/api/admin/anmeldungen/+server.js +// src/routes/api/admin/anmeldungen/+server.ts import { json } from '@sveltejs/kit'; import { PrismaClient } from '@prisma/client'; @@ -17,59 +17,60 @@ export async function GET() { pdfs: true }, orderBy: [ - { - status: 'asc' // BEARBEITUNG zuerst, dann OFFEN, etc. - }, { timestamp: 'desc' } ] }); - // Daten für Frontend formatieren const formattedAnmeldungen = anmeldungen.map(anmeldung => ({ id: anmeldung.id, anrede: anmeldung.anrede, vorname: anmeldung.vorname, nachname: anmeldung.nachname, email: anmeldung.email, - noteDeutsch: anmeldung.noteDeutsch?.toString(), - noteMathe: anmeldung.noteMathe?.toString(), + + // Noten als String konvertieren (falls sie als Int gespeichert sind) + noteDeutsch: anmeldung.noteDeutsch ? anmeldung.noteDeutsch.toString() : undefined, + noteMathe: anmeldung.noteMathe ? anmeldung.noteMathe.toString() : undefined, sozialverhalten: anmeldung.sozialverhalten, // Status-Mapping für Frontend status: mapPrismaStatusToFrontend(anmeldung.status), - processedBy: anmeldung.processedBy, - processedAt: anmeldung.processedAt?.getTime(), + // processedBy: anmeldung.processedBy, + processedAt: anmeldung.processedAt ? anmeldung.processedAt.getTime() : undefined, - // Wünsche + // Wünsche - sicherstellen dass sie existieren wunsch1: anmeldung.wunsch1 ? { id: anmeldung.wunsch1.id, name: anmeldung.wunsch1.name - } : null, + } : undefined, wunsch2: anmeldung.wunsch2 ? { id: anmeldung.wunsch2.id, name: anmeldung.wunsch2.name - } : null, + } : undefined, wunsch3: anmeldung.wunsch3 ? { id: anmeldung.wunsch3.id, name: anmeldung.wunsch3.name - } : null, + } : undefined, // Zugewiesene Dienststelle assignedDienststelle: anmeldung.zugewiesen ? { id: anmeldung.zugewiesen.id, name: anmeldung.zugewiesen.name - } : null, + } : undefined, - timestamp: anmeldung.timestamp.getTime(), - pdfs: anmeldung.pdfs + // Timestamp + timestamp: anmeldung.timestamp ? anmeldung.timestamp.getTime() : Date.now(), + + // PDFs + pdfs: anmeldung.pdfs || [] })); return json(formattedAnmeldungen); } catch (error) { console.error('Fehler beim Laden der Anmeldungen:', error); - return json({ error: 'Fehler beim Laden der Anmeldungen' }, { status: 500 }); + return json({ error: 'Fehler beim Laden der Anmeldungen', details: error.message }, { status: 500 }); } } @@ -82,7 +83,7 @@ export async function POST({ request, url }) { return json({ error: 'ID und Dienststelle erforderlich' }, { status: 400 }); } - // Prüfen ob Anmeldung existiert und bearbeitet werden kann + // Prüfen ob Anmeldung existiert const existingAnmeldung = await prisma.anmeldung.findUnique({ where: { id } }); @@ -96,27 +97,37 @@ export async function POST({ request, url }) { } // Anmeldung als angenommen markieren - await prisma.anmeldung.update({ - where: { id }, - data: { - status: 'ANGENOMMEN', - zugewiesenId: dienststelleId, - processedBy: 'current_user', // TODO: Echten Benutzer verwenden - processedAt: new Date() + await prisma.$transaction([ + prisma.anmeldung.update({ + where: { id }, + data: { + status: 'ANGENOMMEN', + zugewiesenId: dienststelleId, + processedAt: new Date() + } + }), + + prisma.dienststelle.update({ + where: { id: dienststelleId }, + data: { + plaetze: { + decrement: 1 + } } - }); + }) + ]); return json({ success: true }); } catch (error) { console.error('Fehler beim Annehmen der Anmeldung:', error); - return json({ error: 'Fehler beim Annehmen der Anmeldung' }, { status: 500 }); + return json({ error: 'Fehler beim Annehmen der Anmeldung', details: error.message }, { status: 500 }); } } export async function PATCH({ request, url }) { try { const id = parseInt(url.searchParams.get('id') || '0'); - const { action, processedBy } = await request.json(); + const { action } = await request.json(); if (!id) { return json({ error: 'ID erforderlich' }, { status: 400 }); @@ -128,28 +139,21 @@ export async function PATCH({ request, url }) { case 'reject': updateData = { status: 'ABGELEHNT', - processedBy: 'current_user', // TODO: Echten Benutzer verwenden processedAt: new Date() }; break; case 'set_processing': - // Nur setzen wenn noch OFFEN const anmeldung = await prisma.anmeldung.findUnique({ where: { id } }); - + if (!anmeldung) { return json({ error: 'Anmeldung nicht gefunden' }, { status: 404 }); } - - if (anmeldung.status !== 'OFFEN') { - return json({ error: 'Anmeldung kann nicht mehr bearbeitet werden' }, { status: 409 }); - } updateData = { status: 'BEARBEITUNG', - processedBy: processedBy || 'current_user', processedAt: new Date() }; break; @@ -157,7 +161,6 @@ export async function PATCH({ request, url }) { case 'reset_processing': updateData = { status: 'OFFEN', - processedBy: null, processedAt: null }; break; @@ -166,7 +169,7 @@ export async function PATCH({ request, url }) { return json({ error: 'Unbekannte Aktion' }, { status: 400 }); } - const result = await prisma.anmeldung.update({ + await prisma.anmeldung.update({ where: { id }, data: updateData }); @@ -174,7 +177,7 @@ export async function PATCH({ request, url }) { return json({ success: true }); } catch (error) { console.error('Fehler beim Aktualisieren der Anmeldung:', error); - return json({ error: 'Fehler beim Aktualisieren der Anmeldung' }, { status: 500 }); + return json({ error: 'Fehler beim Aktualisieren der Anmeldung', details: error.message }, { status: 500 }); } } @@ -193,7 +196,7 @@ export async function DELETE({ url }) { return json({ success: true }); } catch (error) { console.error('Fehler beim Löschen der Anmeldung:', error); - return json({ error: 'Fehler beim Löschen der Anmeldung' }, { status: 500 }); + return json({ error: 'Fehler beim Löschen der Anmeldung', details: error.message }, { status: 500 }); } } @@ -207,16 +210,4 @@ function mapPrismaStatusToFrontend(prismaStatus) { }; return statusMap[prismaStatus] || 'pending'; -} - -// Hilfsfunktion: Frontend Status zu Prisma Status -function mapFrontendStatusToPrisma(frontendStatus) { - const statusMap = { - 'pending': 'OFFEN', - 'processing': 'BEARBEITUNG', - 'accepted': 'ANGENOMMEN', - 'rejected': 'ABGELEHNT' - }; - - return statusMap[frontendStatus] || 'OFFEN'; } \ No newline at end of file diff --git a/src/routes/api/anmelden/+server.ts b/src/routes/api/anmelden/+server.ts index 38f35c9..da784bc 100644 --- a/src/routes/api/anmelden/+server.ts +++ b/src/routes/api/anmelden/+server.ts @@ -12,6 +12,10 @@ export async function POST({ request }: RequestEvent) { // const pdfs = formData.getAll('pdfs') as File[]; const pdfFiles = formData.getAll('pdfs') as File[]; + const hasValidPdf = pdfFiles.some((file) => file.size > 0 && file.type === 'application/pdf'); + if (!hasValidPdf) { + return json({ error: 'Bitte lade das Zeugnis hoch in PDF Format.' }, { status: 400 }); + } const pdfData = []; // const gespeichertePfade: string[] = [];
+ Status + Bewerber/in + Noten - Wünsche + + Wünsche / Zuweisung - Zugewiesen - + Eingegangen - Bearbeitet - + Aktionen
+
{getStatusText(anmeldung.status || 'pending')} - {#if anmeldung.status === 'processing' && anmeldung.processedBy} -
- von {anmeldung.processedBy} -
- {/if}
+
{anmeldung.anrede} {anmeldung.vorname} {anmeldung.nachname}
-
+
{anmeldung.email}
{#if anmeldung.pdfs && anmeldung.pdfs.length > 0} -
+
{#each anmeldung.pdfs as pdf} @@ -114,14 +104,14 @@
+ {#if anmeldung.noteDeutsch || anmeldung.noteMathe}
{#if anmeldung.noteDeutsch} -
D: {anmeldung.noteDeutsch}
+
D: {anmeldung.noteDeutsch}
{/if} {#if anmeldung.noteMathe} -
M: {anmeldung.noteMathe}
+
M: {anmeldung.noteMathe}
{/if}
{:else} @@ -134,77 +124,79 @@ {/if}
-
- {#if anmeldung.wunsch1} + +
+ + {#if anmeldung.assignedDienststelle} +
- 1 - {anmeldung.wunsch1.name} + + + + Zugewiesen: +
+
+ {anmeldung.assignedDienststelle.name} +
+ {#if anmeldung.processedAt} +
+ {formatProcessedDate(anmeldung.processedAt)} + {#if anmeldung.processedBy} + von {anmeldung.processedBy} + {/if} +
+ {/if} +
+ {/if} + + +
+
Wünsche:
+ {#if anmeldung.wunsch1} +
+ 1 + {anmeldung.wunsch1.name}
{/if} {#if anmeldung.wunsch2} -
- 2 - {anmeldung.wunsch2.name} +
+ 2 + {anmeldung.wunsch2.name}
{/if} {#if anmeldung.wunsch3} -
- 3 - {anmeldung.wunsch3.name} +
+ 3 + {anmeldung.wunsch3.name}
{/if} + {#if !anmeldung.wunsch1 && !anmeldung.wunsch2 && !anmeldung.wunsch3} + Keine Wünsche angegeben + {/if}
- {#if anmeldung.assignedDienststelle} -
- - - - {anmeldung.assignedDienststelle.name} -
- {:else} - - - {/if} -
- {formatDate(anmeldung.timestamp)} - -
{formatProcessedDate(anmeldung.processedAt)}
- {#if anmeldung.processedBy && anmeldung.processedAt} -
- von {anmeldung.processedBy} -
- {/if} +
+
{formatDate(anmeldung.timestamp)}
-
+
+
{#if canBeAccepted(anmeldung.status || 'pending')} {/if} {#if canBeRejected(anmeldung.status || 'pending')} @@ -212,21 +204,11 @@
- - - {#if anmeldung.status === 'processing'} -
- - - - Wird bereits bearbeitet -
- {/if}