attributes->get('tenant_id'); $event = Event::where('slug', $eventSlug) ->where('tenant_id', $tenantId) ->firstOrFail(); $liveStatus = $request->string('live_status', 'pending')->toString(); $perPage = (int) $request->input('per_page', 20); $perPage = max(1, min($perPage, 50)); $query = Photo::query() ->where('event_id', $event->id) ->with('event') ->withCount('likes'); if ($liveStatus !== '' && $liveStatus !== 'all') { $query->where('live_status', $liveStatus); } $photos = $query ->orderByDesc('live_submitted_at') ->orderByDesc('created_at') ->paginate($perPage); return PhotoResource::collection($photos); } public function approve(LiveShowApproveRequest $request, string $eventSlug, Photo $photo): JsonResponse { $tenantId = $request->attributes->get('tenant_id'); $event = Event::where('slug', $eventSlug) ->where('tenant_id', $tenantId) ->firstOrFail(); if ($photo->event_id !== $event->id) { return ApiError::response( 'photo_not_found', 'Photo not found', 'The specified photo could not be located for this event.', Response::HTTP_NOT_FOUND, ['photo_id' => $photo->id] ); } if ($photo->status !== 'approved') { return ApiError::response( 'photo_not_approved', 'Photo not approved', 'Only approved photos can be added to the Live Show.', Response::HTTP_UNPROCESSABLE_ENTITY, ['photo_id' => $photo->id] ); } $photo->approveForLiveShow($request->user()); if ($request->filled('priority')) { $photo->forceFill([ 'live_priority' => $request->integer('priority'), ])->save(); } $photo->refresh()->load('event')->loadCount('likes'); return response()->json([ 'message' => 'Photo approved for Live Show', 'data' => new PhotoResource($photo), ]); } public function approveAndLive(LiveShowApproveRequest $request, string $eventSlug, Photo $photo): JsonResponse { $tenantId = $request->attributes->get('tenant_id'); $event = Event::where('slug', $eventSlug) ->where('tenant_id', $tenantId) ->firstOrFail(); if ($photo->event_id !== $event->id) { return ApiError::response( 'photo_not_found', 'Photo not found', 'The specified photo could not be located for this event.', Response::HTTP_NOT_FOUND, ['photo_id' => $photo->id] ); } if (in_array($photo->status, ['rejected', 'hidden'], true)) { return ApiError::response( 'photo_not_eligible', 'Photo not eligible', 'Rejected or hidden photos cannot be approved for Live Show.', Response::HTTP_UNPROCESSABLE_ENTITY, ['photo_id' => $photo->id] ); } if ($photo->status !== 'approved') { $photo->forceFill([ 'status' => 'approved', 'moderated_at' => now(), 'moderated_by' => $request->user()?->id, 'moderation_notes' => null, ])->save(); } $photo->approveForLiveShow($request->user()); if ($request->filled('priority')) { $photo->forceFill([ 'live_priority' => $request->integer('priority'), ])->save(); } $photo->refresh()->load('event')->loadCount('likes'); return response()->json([ 'message' => 'Photo approved and added to Live Show', 'data' => new PhotoResource($photo), ]); } public function reject(LiveShowRejectRequest $request, string $eventSlug, Photo $photo): JsonResponse { $tenantId = $request->attributes->get('tenant_id'); $event = Event::where('slug', $eventSlug) ->where('tenant_id', $tenantId) ->firstOrFail(); if ($photo->event_id !== $event->id) { return ApiError::response( 'photo_not_found', 'Photo not found', 'The specified photo could not be located for this event.', Response::HTTP_NOT_FOUND, ['photo_id' => $photo->id] ); } $reason = $request->string('reason')->toString(); $photo->rejectForLiveShow($request->user(), $reason !== '' ? $reason : null); $photo->refresh()->load('event')->loadCount('likes'); return response()->json([ 'message' => 'Photo rejected for Live Show', 'data' => new PhotoResource($photo), ]); } public function clear(Request $request, string $eventSlug, Photo $photo): JsonResponse { $tenantId = $request->attributes->get('tenant_id'); $event = Event::where('slug', $eventSlug) ->where('tenant_id', $tenantId) ->firstOrFail(); if ($photo->event_id !== $event->id) { return ApiError::response( 'photo_not_found', 'Photo not found', 'The specified photo could not be located for this event.', Response::HTTP_NOT_FOUND, ['photo_id' => $photo->id] ); } $photo->clearFromLiveShow($request->user()); $photo->refresh()->load('event')->loadCount('likes'); return response()->json([ 'message' => 'Photo removed from Live Show', 'data' => new PhotoResource($photo), ]); } }