From bef910b126f5c4b48546919fb0e90e1ce802e3e6 Mon Sep 17 00:00:00 2001 From: Thorsten Bus Date: Mon, 2 Mar 2026 23:02:19 +0100 Subject: [PATCH] feat(slides): add sort_order column, bulk delete, and reorder endpoints Add sort_order to slides table with migration and model fillable. Add destroyBulk() for batch soft-delete by type/service_id and reorder() for drag-and-drop slide ordering. Auto-assign sort_order on image and zip uploads. --- app/Http/Controllers/SlideController.php | 57 ++++++++++++++++++- app/Models/Slide.php | 1 + ..._140000_add_sort_order_to_slides_table.php | 22 +++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 database/migrations/2026_03_02_140000_add_sort_order_to_slides_table.php diff --git a/app/Http/Controllers/SlideController.php b/app/Http/Controllers/SlideController.php index 0e7574d..aefdb3d 100644 --- a/app/Http/Controllers/SlideController.php +++ b/app/Http/Controllers/SlideController.php @@ -76,6 +76,50 @@ public function destroy(Slide $slide): JsonResponse ]); } + public function destroyBulk(Request $request): JsonResponse + { + $validated = $request->validate([ + 'type' => ['required', Rule::in(['information', 'moderation', 'sermon'])], + 'service_id' => ['nullable', 'exists:services,id'], + ]); + + $query = Slide::where('type', $validated['type']); + + if ($validated['service_id']) { + $query->where('service_id', $validated['service_id']); + } else { + // Information slides without service_id (global) + $query->whereNull('service_id'); + } + + $count = $query->count(); + $query->delete(); // soft-delete via SoftDeletes trait + + return response()->json([ + 'success' => true, + 'message' => $count.' Folien wurden gelöscht.', + 'count' => $count, + ]); + } + + public function reorder(Request $request): JsonResponse + { + $validated = $request->validate([ + 'slides' => ['required', 'array', 'min:1'], + 'slides.*.id' => ['required', 'integer', 'exists:slides,id'], + 'slides.*.sort_order' => ['required', 'integer', 'min:0'], + ]); + + foreach ($validated['slides'] as $item) { + Slide::where('id', $item['id'])->update(['sort_order' => $item['sort_order']]); + } + + return response()->json([ + 'success' => true, + 'message' => 'Reihenfolge wurde aktualisiert.', + ]); + } + public function updateExpireDate(Request $request, Slide $slide): JsonResponse { if ($slide->type !== 'information') { @@ -97,6 +141,13 @@ public function updateExpireDate(Request $request, Slide $slide): JsonResponse ]); } + private function nextSortOrder(string $type, ?int $serviceId): int + { + return (int) Slide::where('type', $type) + ->when($serviceId, fn ($q) => $q->where('service_id', $serviceId), fn ($q) => $q->whereNull('service_id')) + ->max('sort_order') + 1; + } + private function handleImage( UploadedFile $file, FileConversionService $conversionService, @@ -117,6 +168,7 @@ private function handleImage( 'expire_date' => $expireDate, 'uploader_name' => $uploaderName, 'uploaded_at' => now(), + 'sort_order' => $this->nextSortOrder($type, $serviceId), ]); return response()->json([ @@ -144,7 +196,7 @@ private function handlePowerPoint( try { $jobId = $conversionService->convertPowerPoint( - storage_path('app/' . $storedPath) + storage_path('app/'.$storedPath) ); return response()->json([ @@ -179,6 +231,8 @@ private function handleZip( $results = $conversionService->processZip($file); $slides = []; + $sortOrder = $this->nextSortOrder($type, $serviceId); + foreach ($results as $result) { // Skip PPT job results (they are handled asynchronously) if (isset($result['job_id'])) { @@ -194,6 +248,7 @@ private function handleZip( 'expire_date' => $expireDate, 'uploader_name' => $uploaderName, 'uploaded_at' => now(), + 'sort_order' => $sortOrder++, ]); } diff --git a/app/Models/Slide.php b/app/Models/Slide.php index f4056d9..4702923 100644 --- a/app/Models/Slide.php +++ b/app/Models/Slide.php @@ -21,6 +21,7 @@ class Slide extends Model 'expire_date', 'uploader_name', 'uploaded_at', + 'sort_order', ]; protected function casts(): array diff --git a/database/migrations/2026_03_02_140000_add_sort_order_to_slides_table.php b/database/migrations/2026_03_02_140000_add_sort_order_to_slides_table.php new file mode 100644 index 0000000..2ca2aa4 --- /dev/null +++ b/database/migrations/2026_03_02_140000_add_sort_order_to_slides_table.php @@ -0,0 +1,22 @@ +unsignedInteger('sort_order')->default(0)->after('uploaded_at'); + }); + } + + public function down(): void + { + Schema::table('slides', function (Blueprint $table) { + $table->dropColumn('sort_order'); + }); + } +};