143 lines
5.1 KiB
PHP
143 lines
5.1 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;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Validation\Rules\Password;
|
|
|
|
final class PortalMeController extends Controller
|
|
{
|
|
public function index(PortalMeRequest $request): JsonResponse
|
|
{
|
|
$event = Event::withoutGlobalScope(\App\Models\Scopes\OrganisationScope::class)
|
|
->findOrFail($request->validated('event_id'));
|
|
|
|
if ($event->isSubEvent()) {
|
|
$event = $event->parent;
|
|
}
|
|
|
|
// Verify user has a person record for this event (scopes access)
|
|
$person = Person::withoutGlobalScope(\App\Models\Scopes\OrganisationScope::class)
|
|
->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);
|
|
}
|
|
|
|
public function updateProfile(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'event_id' => ['required', 'ulid'],
|
|
'first_name' => ['sometimes', 'string', 'max:255'],
|
|
'last_name' => ['sometimes', 'string', 'max:255'],
|
|
'phone' => ['sometimes', 'nullable', 'string', 'max:50'],
|
|
'date_of_birth' => ['sometimes', 'nullable', 'date', 'before:today'],
|
|
'remarks' => ['sometimes', 'nullable', 'string', 'max:5000'],
|
|
]);
|
|
|
|
$user = $request->user();
|
|
|
|
$event = Event::withoutGlobalScope(\App\Models\Scopes\OrganisationScope::class)
|
|
->findOrFail($validated['event_id']);
|
|
|
|
if ($event->isSubEvent()) {
|
|
$event = $event->parent;
|
|
}
|
|
|
|
// Verify user has a person record for this event (scopes access)
|
|
$person = Person::withoutGlobalScope(\App\Models\Scopes\OrganisationScope::class)
|
|
->where('user_id', $user->id)
|
|
->where('event_id', $event->id)
|
|
->firstOrFail();
|
|
|
|
// Update user record (name fields)
|
|
$userFields = Arr::only($validated, ['first_name', 'last_name']);
|
|
if (!empty($userFields)) {
|
|
$user->update($userFields);
|
|
}
|
|
|
|
// Update person record (phone, date_of_birth, remarks)
|
|
$personFields = Arr::only($validated, ['first_name', 'last_name', 'phone', 'date_of_birth', 'remarks']);
|
|
if (!empty($personFields)) {
|
|
$person->update($personFields);
|
|
}
|
|
|
|
return $this->success(['message' => 'Profiel bijgewerkt.']);
|
|
}
|
|
|
|
public function updatePassword(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'current_password' => ['required', 'string', 'current_password'],
|
|
'password' => ['required', 'string', Password::min(8), 'confirmed'],
|
|
]);
|
|
|
|
$request->user()->update([
|
|
'password' => Hash::make($validated['password']),
|
|
]);
|
|
|
|
return $this->success(['message' => 'Wachtwoord gewijzigd.']);
|
|
}
|
|
}
|