feat(api): extend registration endpoints with dynamic fields and section preferences
- PublicRegistrationData now returns registration_fields (portal-visible only), form toggles, and available_tags for tag_picker fields - Volunteer registration accepts field_values and section_preferences with festival_section_id, processed via existing services - PortalMe eager-loads fieldValues and sectionPreferences - Section preferences now use the proper relational table instead of custom_fields JSON Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
42
api/app/Http/Controllers/Api/V1/PortalMeController.php
Normal file
42
api/app/Http/Controllers/Api/V1/PortalMeController.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
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 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');
|
||||
}
|
||||
|
||||
return $this->success(new PersonResource($person));
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ namespace App\Http\Controllers\Api\V1;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Event;
|
||||
use App\Models\FestivalSection;
|
||||
use App\Models\PersonTag;
|
||||
use App\Models\RegistrationFormField;
|
||||
use App\Models\TimeSlot;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -52,6 +54,13 @@ final class PublicRegistrationDataController extends Controller
|
||||
->where('person_type', 'VOLUNTEER')
|
||||
->values();
|
||||
|
||||
$registrationFields = RegistrationFormField::where('event_id', $festivalEvent->id)
|
||||
->portalVisible()
|
||||
->ordered()
|
||||
->get();
|
||||
|
||||
$organisationId = $festivalEvent->organisation_id;
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'event' => [
|
||||
@@ -59,10 +68,12 @@ final class PublicRegistrationDataController extends Controller
|
||||
'name' => $festivalEvent->name,
|
||||
'start_date' => $festivalEvent->start_date->toDateString(),
|
||||
'end_date' => $festivalEvent->end_date->toDateString(),
|
||||
'organisation_id' => $festivalEvent->organisation_id,
|
||||
'organisation_id' => $organisationId,
|
||||
'registration_banner_url' => $festivalEvent->registration_banner_url,
|
||||
'registration_welcome_text' => $festivalEvent->registration_welcome_text,
|
||||
'registration_logo_url' => $festivalEvent->registration_logo_url,
|
||||
'registration_show_section_preferences' => (bool) $festivalEvent->registration_show_section_preferences,
|
||||
'registration_show_availability' => (bool) $festivalEvent->registration_show_availability,
|
||||
],
|
||||
'sections' => $sections->map(fn (FestivalSection $section) => [
|
||||
'id' => $section->id,
|
||||
@@ -79,6 +90,38 @@ final class PublicRegistrationDataController extends Controller
|
||||
'end_time' => $slot->end_time,
|
||||
'duration_hours' => $slot->duration_hours,
|
||||
]),
|
||||
'registration_fields' => $registrationFields->map(function (RegistrationFormField $field) use ($organisationId) {
|
||||
$data = [
|
||||
'id' => $field->id,
|
||||
'label' => $field->label,
|
||||
'slug' => $field->slug,
|
||||
'field_type' => $field->field_type->value,
|
||||
'options' => $field->options,
|
||||
'tag_category' => $field->tag_category,
|
||||
'is_required' => $field->is_required,
|
||||
'section' => $field->section,
|
||||
'help_text' => $field->help_text,
|
||||
];
|
||||
|
||||
if ($field->field_type === \App\Enums\RegistrationFieldType::TAG_PICKER) {
|
||||
$query = PersonTag::where('organisation_id', $organisationId)
|
||||
->where('is_active', true);
|
||||
|
||||
if ($field->tag_category) {
|
||||
$query->where('category', $field->tag_category);
|
||||
}
|
||||
|
||||
$data['available_tags'] = $query->orderBy('sort_order')
|
||||
->get()
|
||||
->map(fn (PersonTag $tag) => [
|
||||
'id' => $tag->id,
|
||||
'name' => $tag->name,
|
||||
'category' => $tag->category,
|
||||
]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user