diff --git a/app/Domains/Admin/Controllers/UserDetailGetController.php b/app/Domains/Admin/Controllers/UserDetailGetController.php new file mode 100644 index 0000000..9e013e7 --- /dev/null +++ b/app/Domains/Admin/Controllers/UserDetailGetController.php @@ -0,0 +1,35 @@ +toArray(); + + unset($userData['password'], $userData['remember_token'], $userData['activation_token'], $userData['activation_token_expires_at']); + + $tenantNames = Tenant::pluck('name', 'slug'); + $userData['nicename'] = $user->getNicename(); + $userData['fullname'] = $user->getFullName(); + $userData['local_group_name'] = $tenantNames[$user->local_group] ?? $user->local_group; + + return response()->json([ + 'user' => $userData, + 'isOwnUser' => auth()->id() === $user->id, + 'isLvTenant' => $this->tenant->slug === 'lv', + 'userRoles' => UserRole::all()->map(fn($role) => ['slug' => $role->slug, 'name' => $role->name]), + 'localGroups' => Tenant::where('is_active_local_group', true)->get()->map(fn($t) => ['slug' => $t->slug, 'name' => $t->name]), + ]); + } +} diff --git a/app/Domains/Admin/Controllers/UserListApiController.php b/app/Domains/Admin/Controllers/UserListApiController.php new file mode 100644 index 0000000..e4aa5dc --- /dev/null +++ b/app/Domains/Admin/Controllers/UserListApiController.php @@ -0,0 +1,40 @@ +tenant->slug === 'lv') { + $query->orderBy('lastname')->orderBy('firstname'); + } else { + $query->where('local_group', $this->tenant->slug) + ->orderBy('lastname')->orderBy('firstname'); + } + + $users = $query->get()->map(function ($user) use ($tenantNames) { + return [ + 'id' => $user->id, + 'firstname' => $user->firstname, + 'lastname' => $user->lastname, + 'nickname' => $user->nickname, + 'local_group' => $user->local_group, + 'local_group_name' => $tenantNames[$user->local_group] ?? $user->local_group, + 'active' => $user->active, + ]; + }); + + return response()->json(['users' => $users]); + } +} diff --git a/app/Domains/Admin/Controllers/UserListPageController.php b/app/Domains/Admin/Controllers/UserListPageController.php new file mode 100644 index 0000000..1ebc516 --- /dev/null +++ b/app/Domains/Admin/Controllers/UserListPageController.php @@ -0,0 +1,19 @@ + $this->tenant->slug === 'lv', + ]); + return $inertiaProvider->render(); + } +} diff --git a/app/Domains/Admin/Controllers/UserResetPasswordController.php b/app/Domains/Admin/Controllers/UserResetPasswordController.php new file mode 100644 index 0000000..253034f --- /dev/null +++ b/app/Domains/Admin/Controllers/UserResetPasswordController.php @@ -0,0 +1,32 @@ +email) { + return response()->json([ + 'status' => 'error', + 'message' => 'Benutzer*in hat keine E-Mail-Adresse hinterlegt.', + ]); + } + + $command = new GenerateActivationTokenCommand($user); + $command->execute(); + + return response()->json([ + 'status' => 'success', + 'message' => 'Passwort-Reset-Mail wurde gesendet.', + ]); + } +} diff --git a/app/Domains/Admin/Controllers/UserToggleActiveController.php b/app/Domains/Admin/Controllers/UserToggleActiveController.php new file mode 100644 index 0000000..4c5ffe5 --- /dev/null +++ b/app/Domains/Admin/Controllers/UserToggleActiveController.php @@ -0,0 +1,33 @@ +id() === $user->id) { + return response()->json([ + 'status' => 'error', + 'message' => 'Du kannst dich nicht selbst deaktivieren.', + ]); + } + + $user->update(['active' => !$user->active]); + + $status = $user->active ? 'aktiviert' : 'deaktiviert'; + + return response()->json([ + 'status' => 'success', + 'message' => 'Benutzer*in wurde ' . $status . '.', + 'active' => $user->active, + ]); + } +} diff --git a/app/Domains/Admin/Controllers/UserUpdateController.php b/app/Domains/Admin/Controllers/UserUpdateController.php new file mode 100644 index 0000000..de85b97 --- /dev/null +++ b/app/Domains/Admin/Controllers/UserUpdateController.php @@ -0,0 +1,42 @@ +id() === $user->id; + $isLvTenant = $this->tenant->slug === 'lv'; + + $allowedFields = [ + 'firstname', 'lastname', 'nickname', 'email', 'phone', 'birthday', + 'membership_id', 'address_1', 'address_2', 'postcode', 'city', + 'eating_habits', 'swimming_permission', 'first_aid_permission', + 'bank_account_owner', 'bank_account_iban', + 'medications', 'allergies', 'intolerances', + 'user_role_local_group', + ]; + + if ($isLvTenant) { + $allowedFields[] = 'local_group'; + if (!$isOwnUser) { + $allowedFields[] = 'user_role_main'; + } + } + + $data = $request->only($allowedFields); + $user->update($data); + + return response()->json([ + 'status' => 'success', + 'message' => 'Benutzerdaten wurden gespeichert.', + ]); + } +} diff --git a/app/Domains/Admin/Routes/api.php b/app/Domains/Admin/Routes/api.php index d31a421..2d1337d 100644 --- a/app/Domains/Admin/Routes/api.php +++ b/app/Domains/Admin/Routes/api.php @@ -1,5 +1,10 @@ Route::post('/gdpr', TenantGdprUpdateController::class); }); + Route::prefix('api/v1/admin/users')->group(function () { + Route::get('/list', UserListApiController::class); + Route::get('/{id}', UserDetailGetController::class); + Route::post('/{id}', UserUpdateController::class); + Route::post('/{id}/toggle-active', UserToggleActiveController::class); + Route::post('/{id}/reset-password', UserResetPasswordController::class); + }); + Route::middleware(LvOnlyMiddleware::class)->group(function () { Route::prefix('api/v1/admin/tenants')->group(function () { Route::get('/list', TenantListApiController::class); diff --git a/app/Domains/Admin/Routes/web.php b/app/Domains/Admin/Routes/web.php index 9846e40..793962f 100644 --- a/app/Domains/Admin/Routes/web.php +++ b/app/Domains/Admin/Routes/web.php @@ -4,6 +4,7 @@ use App\Domains\Admin\Controllers\AdminDashboardController; use App\Domains\Admin\Controllers\TenantEditPageController; use App\Domains\Admin\Controllers\TenantListPageController; use App\Domains\Admin\Controllers\TenantPageController; +use App\Domains\Admin\Controllers\UserListPageController; use App\Middleware\AdminRoleMiddleware; use App\Middleware\IdentifyTenant; use App\Middleware\LvOnlyMiddleware; @@ -13,6 +14,7 @@ Route::middleware([IdentifyTenant::class, 'auth', AdminRoleMiddleware::class])-> Route::prefix('admin')->group(function () { Route::get('/', AdminDashboardController::class); Route::get('/tenant', TenantPageController::class); + Route::get('/users', UserListPageController::class); Route::middleware(LvOnlyMiddleware::class)->group(function () { Route::get('/tenants', TenantListPageController::class); diff --git a/app/Domains/Admin/Views/Partials/UserDetail.vue b/app/Domains/Admin/Views/Partials/UserDetail.vue new file mode 100644 index 0000000..2a0106d --- /dev/null +++ b/app/Domains/Admin/Views/Partials/UserDetail.vue @@ -0,0 +1,331 @@ + + + + + diff --git a/app/Domains/Admin/Views/UserList.vue b/app/Domains/Admin/Views/UserList.vue new file mode 100644 index 0000000..a325bf9 --- /dev/null +++ b/app/Domains/Admin/Views/UserList.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/resources/js/layouts/AdminAppLayout.vue b/resources/js/layouts/AdminAppLayout.vue index b4a1235..f0e4370 100644 --- a/resources/js/layouts/AdminAppLayout.vue +++ b/resources/js/layouts/AdminAppLayout.vue @@ -109,6 +109,9 @@ const props = defineProps({
  • Stämme
  • +
  • + Benutzer*innen +