From 02b2b8b72d97d9288954a60a3f12b6391b37649d Mon Sep 17 00:00:00 2001 From: Geriano Date: Mon, 18 Jul 2022 18:33:06 +0700 Subject: [PATCH] create user crud --- .../Controllers/Superuser/UserController.php | 205 +++++++++++ app/Models/User.php | 1 + resources/js/Pages/Superuser/User/Index.vue | 337 ++++++++++++++++++ routes/api.php | 1 + routes/web.php | 7 + 5 files changed, 551 insertions(+) create mode 100644 app/Http/Controllers/Superuser/UserController.php create mode 100644 resources/js/Pages/Superuser/User/Index.vue diff --git a/app/Http/Controllers/Superuser/UserController.php b/app/Http/Controllers/Superuser/UserController.php new file mode 100644 index 0000000..0c9dd87 --- /dev/null +++ b/app/Http/Controllers/Superuser/UserController.php @@ -0,0 +1,205 @@ +with([ + 'roles' => Role::get(), + 'permissions' => Permission::get(), + ]); + } + + /** + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function paginate(Request $request) + { + $request->validate([ + 'search' => 'nullable|string', + 'per_page' => 'nullable|integer|max:1000', + 'order.key' => 'nullable|string', + 'order.dir' => 'nullable|in:asc,desc', + ]); + + return User::where(function (Builder $query) use ($request) { + $search = '%' . $request->input('search') . '%'; + $columns = ['name', 'username', 'email', 'email_verified_at', 'created_at', 'updated_at']; + + foreach ($columns as $column) + $query->orWhere($column, 'like', $search); + + $query->orWhereRelation('permissions', 'name', 'like', $search); + $query->orWhereRelation('roles', 'name', 'like', $search); + }) + ->orderBy($request->input('order.key') ?: 'name', $request->input('order.dir') ?: 'asc') + ->with(['permissions', 'roles']) + ->paginate($request->per_page ?: 10); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $post = $request->validate([ + 'name' => 'required|string', + 'username' => 'required|string|unique:users', + 'email' => 'required|email|unique:users', + 'password' => 'required|string|min:8', + 'password_confirmation' => 'required|same:password', + 'roles.*' => 'nullable|integer|exists:roles,id', + 'permissions.*' => 'nullable|integer|exists:permissions,id', + ]); + + $post['password'] = Hash::make($post['password']); + + if ($user = User::create($post)) { + $user->permissions()->sync($request->input('permissions', [])); + $user->roles()->sync($request->input('roles', [])); + $user->email_verified_at = now(); + $user->save(); + + return redirect()->back()->with('success', __( + 'user `:name` has been created', [ + 'name' => $user->name, + ], + )); + } + + return redirect()->back()->with('error', __( + 'can\'t create user' + )); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param \App\Models\User $user + * @return \Illuminate\Http\Response + */ + public function update(Request $request, User $user) + { + $request->validate([ + 'name' => ['required', 'string'], + 'username' => ['required', 'string', Rule::unique('users')->ignore($user->id)], + 'email' => ['required', 'email', Rule::unique('users')->ignore($user->id)], + 'password' => ['nullable', 'string', 'min:8'], + 'password_confirmation' => ['nullable', 'same:password'], + 'roles.*' => ['nullable', 'integer', 'exists:roles,id'], + 'permissions.*' => ['nullable', 'integer', 'exists:permissions,id'], + ]); + + if ($user->update($request->only(['name', 'username', 'email']))) { + $user->permissions()->sync($request->input('permissions', [])); + $user->roles()->sync($request->input('roles', [])); + + if ($password = $request->input('password')) { + $user->update([ + 'password' => Hash::make($password), + ]); + } + + return redirect()->back()->with('success', __( + 'user `:name` has been updated', [ + 'name' => $user->name, + ], + )); + } + + return redirect()->back()->with('error', __( + 'can\'t update user' + )); + } + + /** + * Remove the specified resource from storage. + * + * @param \App\Models\User $user + * @return \Illuminate\Http\Response + */ + public function destroy(User $user) + { + if ($user->delete()) { + return redirect()->back()->with('success', __( + 'user `:name` has been deleted', [ + 'name' => $user->name, + ], + )); + } + + return redirect()->back()->with('error', __( + 'can\'t delete user' + )); + } + + /** + * @param \App\Models\User $user + * @param \App\Models\Permission $permission + * @return \Illuminate\Http\Response + */ + public function detachPermission(User $user, Permission $permission) + { + if ($user->permissions()->detach([$permission->id])) { + return redirect()->back()->with('success', __( + 'permission `:permission from user `:user` has been detached`', [ + 'permission' => $permission->name, + 'user' => $user->name, + ] + )); + } + + return redirect()->back()->with('error', __( + 'can\'t detach permission `:permission` from user `:user`', [ + 'permission' => $permission->name, + 'user' => $user->name, + ] + )); + } + + /** + * @param \App\Models\User $user + * @param \App\Models\Role $role + * @return \Illuminate\Http\Response + */ + public function detachRole(User $user, Role $role) + { + if ($user->roles()->detach([$role->id])) { + return redirect()->back()->with('success', __( + 'role `:role from user `:user` has been detached`', [ + 'role' => $role->name, + 'user' => $user->name, + ] + )); + } + + return redirect()->back()->with('error', __( + 'can\'t detach role `:role` from user `:user`', [ + 'role' => $role->name, + 'user' => $user->name, + ] + )); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 2e0ecba..79d639e 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -30,6 +30,7 @@ class User extends Authenticatable */ protected $fillable = [ 'name', + 'username', 'email', 'password', ]; diff --git a/resources/js/Pages/Superuser/User/Index.vue b/resources/js/Pages/Superuser/User/Index.vue new file mode 100644 index 0000000..1f344fd --- /dev/null +++ b/resources/js/Pages/Superuser/User/Index.vue @@ -0,0 +1,337 @@ + + + + + \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index ed522f0..acd8ba7 100644 --- a/routes/api.php +++ b/routes/api.php @@ -21,5 +21,6 @@ Route::prefix('/v1')->name('api.v1.')->group(function () { Route::get('/superuser/permission', [App\Http\Controllers\Superuser\PermissionController::class, 'get'])->name('permission'); Route::get('/superuser/role', [App\Http\Controllers\Superuser\RoleController::class, 'get'])->name('role'); Route::post('/superuser/role/paginate', [App\Http\Controllers\Superuser\RoleController::class, 'paginate'])->name('role.paginate'); + Route::post('/superuser/user/paginate', [App\Http\Controllers\Superuser\UserController::class, 'paginate'])->name('user.paginate'); }); }); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 6238d66..570a4cb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -30,5 +30,12 @@ Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified'] ]); Route::patch('/role/{role}/detach/{permission}', [App\Http\Controllers\Superuser\RoleController::class, 'detach'])->name('role.detach'); + + Route::resource('user', App\Http\Controllers\Superuser\UserController::class)->only([ + 'index', 'store', 'update', 'destroy', + ]); + + Route::patch('/user/{user}/role/{role}/detach', [App\Http\Controllers\Superuser\UserController::class, 'detachRole'])->name('user.role.detach'); + Route::patch('/user/{user}/permission/{permission}/detach', [App\Http\Controllers\Superuser\UserController::class, 'detachPermission'])->name('user.permission.detach'); }); }); \ No newline at end of file