Query next approved shift assignment with future time slot, ordered by date and start time, and return formatted shift data in the portal me response for the dashboard "Komende shift" card. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
2.7 KiB
PHP
81 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api\V1;
|
|
|
|
use App\Enums\ShiftAssignmentStatus;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Api\V1\PortalMeRequest;
|
|
use App\Http\Resources\Api\V1\PersonResource;
|
|
use App\Models\Event;
|
|
use App\Models\Person;
|
|
use App\Models\TimeSlot;
|
|
use Illuminate\Http\JsonResponse;
|
|
|
|
final class PortalMeController extends Controller
|
|
{
|
|
public function index(PortalMeRequest $request): JsonResponse
|
|
{
|
|
$event = Event::findOrFail($request->validated('event_id'));
|
|
|
|
if ($event->isSubEvent()) {
|
|
$event = $event->parent;
|
|
}
|
|
|
|
$person = Person::where('user_id', $request->user()->id)
|
|
->where('event_id', $event->id)
|
|
->with([
|
|
'crowdType',
|
|
'shiftAssignments.shift.festivalSection',
|
|
'shiftAssignments.shift.timeSlot',
|
|
'volunteerAvailabilities.timeSlot',
|
|
'fieldValues.registrationFormField',
|
|
'sectionPreferences.festivalSection',
|
|
])
|
|
->first();
|
|
|
|
if (! $person) {
|
|
return $this->notFound('No registration found for this event');
|
|
}
|
|
|
|
$upcomingShift = $person->shiftAssignments()
|
|
->where('status', ShiftAssignmentStatus::APPROVED)
|
|
->whereHas('shift.timeSlot', fn ($q) => $q->where('date', '>=', now()->toDateString()))
|
|
->with([
|
|
'shift:id,title,festival_section_id,time_slot_id,location_id',
|
|
'shift.timeSlot:id,name,date,start_time,end_time',
|
|
'shift.festivalSection:id,name',
|
|
'shift.location:id,name',
|
|
])
|
|
->orderBy(
|
|
TimeSlot::select('date')
|
|
->whereColumn('time_slots.id', 'shift_assignments.time_slot_id')
|
|
->limit(1)
|
|
)
|
|
->orderBy(
|
|
TimeSlot::select('start_time')
|
|
->whereColumn('time_slots.id', 'shift_assignments.time_slot_id')
|
|
->limit(1)
|
|
)
|
|
->first();
|
|
|
|
$formattedShift = null;
|
|
if ($upcomingShift) {
|
|
$timeSlot = $upcomingShift->shift->timeSlot;
|
|
$formattedShift = [
|
|
'date' => $timeSlot->date->toDateString(),
|
|
'time' => substr($timeSlot->start_time, 0, 5) . ' - ' . substr($timeSlot->end_time, 0, 5),
|
|
'title' => $upcomingShift->shift->title,
|
|
'section' => $upcomingShift->shift->festivalSection?->name,
|
|
'location' => $upcomingShift->shift->location?->name,
|
|
];
|
|
}
|
|
|
|
$data = (new PersonResource($person))->resolve();
|
|
$data['upcoming_shift'] = $formattedShift;
|
|
|
|
return $this->success($data);
|
|
}
|
|
}
|