Add live show moderation queue
This commit is contained in:
144
app/Http/Controllers/Api/Tenant/LiveShowPhotoController.php
Normal file
144
app/Http/Controllers/Api/Tenant/LiveShowPhotoController.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Tenant;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Tenant\LiveShowApproveRequest;
|
||||
use App\Http\Requests\Tenant\LiveShowQueueRequest;
|
||||
use App\Http\Requests\Tenant\LiveShowRejectRequest;
|
||||
use App\Http\Resources\Tenant\PhotoResource;
|
||||
use App\Models\Event;
|
||||
use App\Models\Photo;
|
||||
use App\Support\ApiError;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class LiveShowPhotoController extends Controller
|
||||
{
|
||||
public function index(LiveShowQueueRequest $request, string $eventSlug): AnonymousResourceCollection
|
||||
{
|
||||
$tenantId = $request->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)
|
||||
->where('status', 'approved')
|
||||
->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 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),
|
||||
]);
|
||||
}
|
||||
}
|
||||
28
app/Http/Requests/Tenant/LiveShowApproveRequest.php
Normal file
28
app/Http/Requests/Tenant/LiveShowApproveRequest.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Tenant;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class LiveShowApproveRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'priority' => ['nullable', 'integer', 'min:0', 'max:100'],
|
||||
];
|
||||
}
|
||||
}
|
||||
34
app/Http/Requests/Tenant/LiveShowQueueRequest.php
Normal file
34
app/Http/Requests/Tenant/LiveShowQueueRequest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Tenant;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class LiveShowQueueRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'live_status' => [
|
||||
'nullable',
|
||||
'string',
|
||||
Rule::in(['pending', 'approved', 'rejected', 'none', 'expired', 'all']),
|
||||
],
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:50'],
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Http/Requests/Tenant/LiveShowRejectRequest.php
Normal file
28
app/Http/Requests/Tenant/LiveShowRejectRequest.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Tenant;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class LiveShowRejectRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'reason' => ['nullable', 'string', 'max:64'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,11 @@ class PhotoResource extends JsonResource
|
||||
'is_featured' => (bool) ($this->is_featured ?? false),
|
||||
'status' => $showSensitive ? $this->status : 'approved',
|
||||
'moderation_notes' => $showSensitive ? $this->moderation_notes : null,
|
||||
'live_status' => $showSensitive ? $this->live_status?->value ?? $this->live_status : null,
|
||||
'live_approved_at' => $showSensitive ? $this->live_approved_at?->toISOString() : null,
|
||||
'live_reviewed_at' => $showSensitive ? $this->live_reviewed_at?->toISOString() : null,
|
||||
'live_rejection_reason' => $showSensitive ? $this->live_rejection_reason : null,
|
||||
'live_priority' => $showSensitive ? (int) ($this->live_priority ?? 0) : null,
|
||||
'likes_count' => (int) ($this->likes_count ?? $this->likes()->count()),
|
||||
'is_liked' => false,
|
||||
'uploaded_at' => $this->created_at->toISOString(),
|
||||
|
||||
Reference in New Issue
Block a user