feat(registration): User registration

- add validation, and prepare the model.
- show errors in form components
- refactor route file to make register route as resource
This commit is contained in:
kusowl 2026-01-09 14:00:42 +05:30
parent 372610065d
commit ec7ae434c4
10 changed files with 81 additions and 7 deletions

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers;
use App\Enums\UserStatus;
use App\Enums\UserTypes;
use App\Http\Requests\StoreRegisterdUser;
use App\Models\User;
use Illuminate\Http\Request;
class RegisteredUserController extends Controller
{
public function create()
{
return view('auth.register');
}
public function store(StoreRegisterdUser $request){
$data = $request->validated();
$status = UserStatus::Active->value;
if ($request->role === UserTypes::Broker){
$status = UserStatus::Pending->value;
}
$data['status'] = $status;
User::create($data);
return to_route('login')->with('success', 'User registered successfully.');
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use App\Enums\UserTypes;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;
class StoreRegisterdUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'password' => ['required', 'confirmed', Password::min(8)->letters()->mixedCase()->numbers()->symbols()],
'email' => 'required|string|email|max:255|unique:users',
'role' => ['required', Rule::in(UserTypes::values()), Rule::notIn(UserTypes::Admin->value)],
];
}
}

View File

@ -21,6 +21,8 @@ class User extends Authenticatable
'name', 'name',
'email', 'email',
'password', 'password',
'status',
'role',
]; ];
/** /**

View File

@ -26,7 +26,7 @@
</form> </form>
<p class="text-center text-accent-600 text-xs">Don't have an account? <p class="text-center text-accent-600 text-xs">Don't have an account?
<a href="{{route('register')}}" class="text-blue-500 font-bold">Sign Up</a> <a href="{{route('register.create')}}" class="text-blue-500 font-bold">Sign Up</a>
</p> </p>
</x-card> </x-card>
</section> </section>

View File

@ -19,10 +19,11 @@ class="bg-linear-135 flex-1 overflow-y-scroll wrapper py-12 from-[#EFF6FF] to-[#
<p class=" text-accent-600 text-sm">Join {{config('app.name')}} and start discovering great <p class=" text-accent-600 text-sm">Join {{config('app.name')}} and start discovering great
deals</p> deals</p>
</div> </div>
<form action="" class="flex flex-col space-y-5"> <form action="{{route('register.store')}}" method="post" class="flex flex-col space-y-5">
@csrf
<x-input label="Full Name" name="name" placeholder="Jhon Doe"/> <x-input label="Full Name" name="name" placeholder="Jhon Doe"/>
<x-input label="Email" name="email" type="email" placeholder="you@example.com"/> <x-input label="Email" name="email" type="email" placeholder="you@example.com"/>
<x-select :options="$options" value-key="value" label-key="label" label="Account Type"/> <x-select name="role" :options="$options" value-key="value" label-key="label" label="Account Type"/>
<x-input label="Password" name="password" type="password"/> <x-input label="Password" name="password" type="password"/>
<x-input label="Confirm Password" name="password_confirmation" type="password"/> <x-input label="Confirm Password" name="password_confirmation" type="password"/>

View File

@ -0,0 +1,4 @@
@props(['name' => ''])
@error($name)
<span class="text-xs text-red-500">{{ $message }}</span>
@enderror

View File

@ -6,5 +6,5 @@
@endif @endif
<input class="bg-[#F3F3F5] py-2 px-4 rounded-lg" type="{{$type}}" placeholder="{{$placeholder}}" <input class="bg-[#F3F3F5] py-2 px-4 rounded-lg" type="{{$type}}" placeholder="{{$placeholder}}"
name="{{$name}}"> name="{{$name}}">
<x-inline-error :name="$name" />
</div> </div>

View File

@ -16,7 +16,7 @@
<div class="nav-buttons space-x-4 font-medium hidden md:block "> <div class="nav-buttons space-x-4 font-medium hidden md:block ">
<a href="{{route('login')}}">Login</a> <a href="{{route('login')}}">Login</a>
<a href="{{route('register')}}" class="ui-btn ui-btn-neutral">Register</a> <a href="{{route('register.create')}}" class="ui-btn ui-btn-neutral">Register</a>
</div> </div>
<!-- mobile menu btn--> <!-- mobile menu btn-->
@ -41,7 +41,7 @@
<x-nav-links :link="route('home')" name="About"/> <x-nav-links :link="route('home')" name="About"/>
<x-nav-links :link="route('home')" name="Contact"/> <x-nav-links :link="route('home')" name="Contact"/>
<a href="{{route('login')}}">Login</a> <a href="{{route('login')}}">Login</a>
<a href="{{route('register')}}" class="ui-btn ui-btn-neutral w-fit">Register</a> <a href="{{route('register.create')}}" class="ui-btn ui-btn-neutral w-fit">Register</a>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -10,3 +10,4 @@
<option value="{{$option[$valueKey]}}"> {{$option[$labelKey]}} </option> <option value="{{$option[$valueKey]}}"> {{$option[$labelKey]}} </option>
@endforeach @endforeach
</select> </select>
<x-inline-error :name="$name" />

View File

@ -1,10 +1,11 @@
<?php <?php
use App\Http\Controllers\HomeController; use App\Http\Controllers\HomeController;
use App\Http\Controllers\RegisteredUserController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::get('/', HomeController::class)->name('home'); Route::get('/', HomeController::class)->name('home');
Route::view('/login', 'auth.login')->name('login'); Route::view('/login', 'auth.login')->name('login');
Route::view('/register', 'auth.register')->name('register'); Route::resource('/register', RegisteredUserController::class)->only(['create', 'store']);