diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php index e575342..8933385 100644 --- a/app/Http/Controllers/UsersController.php +++ b/app/Http/Controllers/UsersController.php @@ -6,9 +6,17 @@ use Inertia\Response; use Influx\Models\User; use Illuminate\Http\Request; +use Illuminate\Contracts\Hashing\Hasher; class UsersController extends Controller { + /** + * UsersController constructor. + */ + public function __construct(private Hasher $hasher) + { + } + /** * Display the table holding all user accounts. */ @@ -39,10 +47,48 @@ public function store(Request $request): Response 'superuser' => ['required'], ]); + $validated['superuser'] = $validated['superuser'] === 'on' ? true : false; + $validated['password'] = $this->hasher->make($validated['password']); + + $user = User::create($validated); + + return Inertia::render('Users/Edit', ['user' => $user]); + } + + /** + * View a user already on the system. + */ + public function view(Request $request, int $id): Response + { + return Inertia::render('Users/Edit', [ + 'user' => User::findOrFail($id), + ]); + } + + /** + * Update the details of an existing user. + */ + public function update(Request $request, int $id): Response + { + $user = User::findOrFail($id); + + $validated = $request->validate([ + 'name' => ['required', 'max:50'], + 'email' => ['required', 'max:50', 'email'], + 'password' => ['nullable', 'min:8'], + 'superuser' => ['required'], + ]); + + if (!empty($validated['password'])) { + $validated['password'] = $this->hasher->make($validated['password']); + } else { + unset($validated['password']); + } + $validated['superuser'] = $validated['superuser'] === 'on' ? true : false; - User::create($validated); + $user->forceFill($validated)->saveOrFail(); - return Inertia::render('Users/Index'); + return Inertia::render('Users/Edit', ['user' => $user]); } } diff --git a/resources/js/Pages/Users/Edit.tsx b/resources/js/Pages/Users/Edit.tsx new file mode 100644 index 0000000..f79ba2a --- /dev/null +++ b/resources/js/Pages/Users/Edit.tsx @@ -0,0 +1,33 @@ +import Card from '@/Components/Card'; +import Authenticated from '@/Layouts/AuthenticatedLayout'; +import { PageProps, User } from '@/types'; +import Avatar from 'boring-avatars'; +import UserForm from './UserForm'; + +export default function Edit({ user }: PageProps<{ user: User }>) { + if (!user) return <>; + + return ( + + +
+
+
+ +
+
+ +
+
+
+ ); +} diff --git a/resources/js/Pages/Users/Index.tsx b/resources/js/Pages/Users/Index.tsx index 7e5b469..f69e248 100644 --- a/resources/js/Pages/Users/Index.tsx +++ b/resources/js/Pages/Users/Index.tsx @@ -27,7 +27,7 @@ export default function Index({ users }: PageProps<{ users: User[] }>) { >
@@ -49,12 +49,12 @@ export default function Index({ users }: PageProps<{ users: User[] }>) {
- Edit - + ))} diff --git a/resources/js/Pages/Users/New.tsx b/resources/js/Pages/Users/New.tsx index c55c85e..6c6a49b 100644 --- a/resources/js/Pages/Users/New.tsx +++ b/resources/js/Pages/Users/New.tsx @@ -1,34 +1,9 @@ import Card from '@/Components/Card'; -import PrimaryButton from '@/Components/PrimaryButton'; import Authenticated from '@/Layouts/AuthenticatedLayout'; -import { router } from '@inertiajs/react'; import Avatar from 'boring-avatars'; -import { useState } from 'react'; +import UserForm from './UserForm'; export default function New() { - const [values, setValues] = useState({ - email: '', - name: '', - password: '', - superuser: false, - }); - - function handleChange(e: { - target: { id: string; value: string | boolean }; - }) { - const key = e.target.id; - const value = e.target.value; - setValues((values) => ({ - ...values, - [key]: value, - })); - } - - function handleSubmit(e: { preventDefault: () => void }) { - e.preventDefault(); - router.post('/users/new', values); - } - return ( -
-
- - -
-
- - -
-
-
- - -
-
- - -
-
-
- - Submit - -
-
+
diff --git a/resources/js/Pages/Users/UserForm.tsx b/resources/js/Pages/Users/UserForm.tsx new file mode 100644 index 0000000..23b9bb7 --- /dev/null +++ b/resources/js/Pages/Users/UserForm.tsx @@ -0,0 +1,113 @@ +import PrimaryButton from '@/Components/PrimaryButton'; +import { User } from '@/types'; +import { router } from '@inertiajs/react'; +import { useState } from 'react'; + +export default function UserForm({ user }: { user?: User }) { + const [values, setValues] = useState({ + email: user?.email ?? '', + name: user?.name ?? '', + password: '', + superuser: user?.superuser ?? false, + }); + + function handleChange(e: { + target: { id: string; value: string | boolean }; + }) { + const key = e.target.id; + const value = e.target.value; + setValues((values) => ({ + ...values, + [key]: value, + })); + } + + function handleSubmit(e: { preventDefault: () => void }) { + e.preventDefault(); + + if (user) { + router.put(`/users/${user!.id}`, values); + } else { + router.post('/users/new', values); + } + } + + return ( +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ Submit +
+
+ ); +} diff --git a/routes/web.php b/routes/web.php index 5dd8321..5d11c58 100644 --- a/routes/web.php +++ b/routes/web.php @@ -22,8 +22,12 @@ Route::middleware('auth')->group(function () { Route::prefix('/users')->group(function () { Route::get('/', [UsersController::class, 'index'])->name('users.index'); + Route::get('/new', [UsersController::class, 'new'])->name('users.new'); Route::post('/new', [UsersController::class, 'store'])->name('users.store'); + + Route::get('/{user:id}', [UsersController::class, 'view'])->name('users.view'); + Route::put('/{user:id}', [UsersController::class, 'update'])->name('users.update'); }); Route::prefix('/profile')->group(function () {