Adds two new API endpoints to quickly add organisation members as event
persons with user_id pre-linked and status approved:
- GET /organisations/{org}/members/available-for-event/{event}
- POST /organisations/{org}/events/{event}/persons/from-member
Includes frontend dialog with member search, crowd type selection, and
click-to-add behavior in the Personen tab.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
144 lines
4.4 KiB
PHP
144 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api\V1;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Api\V1\UpdateMemberRequest;
|
|
use App\Http\Resources\Api\V1\MemberCollection;
|
|
use App\Http\Resources\Api\V1\MemberResource;
|
|
use App\Models\Event;
|
|
use App\Models\Organisation;
|
|
use App\Models\Person;
|
|
use App\Models\User;
|
|
use App\Services\EmailChangeService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Gate;
|
|
|
|
final class MemberController extends Controller
|
|
{
|
|
public function index(Organisation $organisation): MemberCollection
|
|
{
|
|
Gate::authorize('view', $organisation);
|
|
|
|
$members = $organisation->users()->get();
|
|
|
|
return new MemberCollection($members);
|
|
}
|
|
|
|
public function update(UpdateMemberRequest $request, Organisation $organisation, User $user): JsonResponse
|
|
{
|
|
Gate::authorize('invite', $organisation);
|
|
|
|
if ($request->user()->id === $user->id) {
|
|
return $this->error('Je kunt je eigen rol niet wijzigen.', 422);
|
|
}
|
|
|
|
$currentRole = $organisation->users()
|
|
->where('user_id', $user->id)
|
|
->first()?->pivot?->role;
|
|
|
|
if ($currentRole === 'org_admin' && $request->validated('role') !== 'org_admin') {
|
|
$adminCount = $organisation->users()
|
|
->wherePivot('role', 'org_admin')
|
|
->count();
|
|
|
|
if ($adminCount <= 1) {
|
|
return $this->error('De laatste org_admin kan niet worden gedegradeerd.', 422);
|
|
}
|
|
}
|
|
|
|
$organisation->users()->updateExistingPivot($user->id, [
|
|
'role' => $request->validated('role'),
|
|
]);
|
|
|
|
return $this->success(
|
|
new MemberResource($organisation->users()->where('user_id', $user->id)->first()),
|
|
);
|
|
}
|
|
|
|
public function destroy(Organisation $organisation, User $user): JsonResponse
|
|
{
|
|
Gate::authorize('invite', $organisation);
|
|
|
|
if (request()->user()->id === $user->id) {
|
|
return $this->error('Je kunt je eigen account niet verwijderen uit de organisatie.', 422);
|
|
}
|
|
|
|
$currentRole = $organisation->users()
|
|
->where('user_id', $user->id)
|
|
->first()?->pivot?->role;
|
|
|
|
if ($currentRole === 'org_admin') {
|
|
$adminCount = $organisation->users()
|
|
->wherePivot('role', 'org_admin')
|
|
->count();
|
|
|
|
if ($adminCount <= 1) {
|
|
return $this->error('De laatste org_admin kan niet worden verwijderd.', 422);
|
|
}
|
|
}
|
|
|
|
$organisation->users()->detach($user->id);
|
|
|
|
return response()->json(null, 204);
|
|
}
|
|
|
|
public function availableForEvent(Organisation $organisation, Event $event): JsonResponse
|
|
{
|
|
if ($event->organisation_id !== $organisation->id) {
|
|
abort(404);
|
|
}
|
|
|
|
Gate::authorize('viewAny', [Person::class, $event]);
|
|
|
|
$existingUserIds = Person::withoutGlobalScopes()
|
|
->where('event_id', $event->id)
|
|
->whereNotNull('user_id')
|
|
->pluck('user_id');
|
|
|
|
$members = $organisation->users()
|
|
->whereNotIn('users.id', $existingUserIds)
|
|
->select('users.id', 'users.first_name', 'users.last_name', 'users.email')
|
|
->orderBy('users.first_name')
|
|
->get()
|
|
->map(fn (User $user) => [
|
|
'id' => $user->id,
|
|
'first_name' => $user->first_name,
|
|
'last_name' => $user->last_name,
|
|
'full_name' => $user->full_name,
|
|
'email' => $user->email,
|
|
]);
|
|
|
|
return response()->json(['data' => $members]);
|
|
}
|
|
|
|
/**
|
|
* POST /api/v1/organisations/{organisation}/members/{user}/change-email
|
|
* Admin changes a member's email (sends verification to new address).
|
|
*/
|
|
public function changeEmail(Request $request, Organisation $organisation, User $user): JsonResponse
|
|
{
|
|
Gate::authorize('invite', $organisation);
|
|
|
|
$validated = $request->validate([
|
|
'new_email' => ['required', 'email', 'max:255'],
|
|
]);
|
|
|
|
$frontendUrl = config('app.frontend_app_url');
|
|
|
|
app(EmailChangeService::class)->requestChange(
|
|
$user,
|
|
$validated['new_email'],
|
|
$request->user(),
|
|
$frontendUrl,
|
|
);
|
|
|
|
return $this->success(
|
|
message: 'Er is een verificatiemail verstuurd naar ' . $validated['new_email'] . '.',
|
|
);
|
|
}
|
|
}
|