diff --git a/app/Http/Controllers/Broker/BrokerProfileController.php b/app/Http/Controllers/Broker/BrokerProfileController.php
index b01dec1..cf74a8b 100644
--- a/app/Http/Controllers/Broker/BrokerProfileController.php
+++ b/app/Http/Controllers/Broker/BrokerProfileController.php
@@ -3,8 +3,10 @@
namespace App\Http\Controllers\Broker;
use App\Http\Controllers\Controller;
+use App\Models\Broker;
use App\Models\User;
use Illuminate\Http\Request;
+use Illuminate\Support\Str;
class BrokerProfileController extends Controller
{
@@ -13,10 +15,31 @@ class BrokerProfileController extends Controller
*/
public function show(User $profile)
{
+ // Get the broker profile
+ $broker = $profile->type;
+
+ // TODO: move this to middleware
+ if (! $broker instanceof Broker) {
+ abort(403, 'This user is not a broker.');
+ }
+
+ /**
+ * Create the initials from a full name (e.g. John Doe, Alex Mark, jane clerk)
+ * to display on profile page (e.g. JD, AM, JC).
+ */
+ $initials = Str::of($profile->name)
+ ->explode(' ')
+ ->map(fn ($word) => Str::substr(ucfirst($word), 0, 1))
+ ->join('');
+
return view('dashboards.broker.profile.show')
->with('name', $profile->name)
->with('joinDate', $profile->created_at->format('F Y'))
- ->with('email', $profile->email);
+ ->with('email', $profile->email)
+ ->with('initials', $initials)
+ ->with('verified', $broker->verified)
+ ->with('location', $broker->location)
+ ->with('phone', $broker->phone);
}
/**
diff --git a/app/Http/Controllers/RegisteredUserController.php b/app/Http/Controllers/RegisteredUserController.php
index 0723eee..c432273 100644
--- a/app/Http/Controllers/RegisteredUserController.php
+++ b/app/Http/Controllers/RegisteredUserController.php
@@ -5,7 +5,10 @@
use App\Enums\UserStatus;
use App\Enums\UserTypes;
use App\Http\Requests\StoreRegisterdUser;
+use App\Models\Broker;
use App\Models\User;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
class RegisteredUserController extends Controller
{
@@ -18,17 +21,30 @@ public function store(StoreRegisterdUser $request)
{
$data = $request->validated();
- $status = UserStatus::Active->value;
+ try {
+ DB::transaction(function () use ($data) {
+ if ($data['role'] === UserTypes::Broker->value) {
+ $data['status'] = UserStatus::Pending->value;
- if ($data['role'] === UserTypes::Broker->value) {
- $status = UserStatus::Pending->value;
+ // Create Broker first, then the User linked to it
+ $broker = Broker::create();
+ $broker->user()->create($data);
+ } else {
+ $data['status'] = UserStatus::Active->value;
+
+ User::create($data);
+ }
+ });
+
+ return to_route('login.create')
+ ->with('userRegistered', 'User registered successfully.');
+
+ } catch (\Throwable $e) {
+ Log::error('Registration Failed: '.$e->getMessage());
+
+ return back()
+ ->withInput()
+ ->with('error', 'Something went wrong during registration.');
}
-
- $data['status'] = $status;
-
- User::create($data);
-
- return to_route('login.create')
- ->with('userRegistered', 'User registered successfully.');
}
}
diff --git a/app/Models/Broker.php b/app/Models/Broker.php
index 06e0055..8ac4408 100644
--- a/app/Models/Broker.php
+++ b/app/Models/Broker.php
@@ -11,12 +11,11 @@ protected function casts(): array
{
return [
'verified' => 'boolean',
- 'active' => 'boolean',
];
}
public function user(): MorphOne
{
- return $this->morphOne(User::class, 'type');
+ return $this->morphOne(User::class, 'role');
}
}
diff --git a/app/Models/User.php b/app/Models/User.php
index bde7e60..a33dccb 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -63,10 +63,10 @@ public function deals(): HasMany
}
/**
- * Returns model of User's type
+ * Returns model of User's role type
*/
public function type(): MorphTo
{
- return $this->morphTo();
+ return $this->morphTo('role');
}
}
diff --git a/app/Services/FileService.php b/app/Services/FileService.php
index 9b7f134..d1f2c53 100644
--- a/app/Services/FileService.php
+++ b/app/Services/FileService.php
@@ -9,7 +9,10 @@ class FileService
{
public function upload(UploadedFile $file, string $folder, string $filename): string
{
- return $file->storeAs($folder, $filename.'.'.$file->extension(), 'public');
+ // This prevents overriding of same image name
+ $filename = time().$filename.'.'.$file->extension();
+
+ return $file->storeAs($folder, $filename, 'public');
}
public function delete(?string $path): void
diff --git a/bootstrap/app.php b/bootstrap/app.php
index c183276..4c0d9a9 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -11,7 +11,7 @@
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
- //
+ $middleware->redirectGuestsTo(fn () => route('login.create'));
})
->withExceptions(function (Exceptions $exceptions): void {
//
diff --git a/database/migrations/2026_01_13_103047_create_brokers_table.php b/database/migrations/2026_01_13_103047_create_brokers_table.php
index 5d9502c..ad9c5ca 100644
--- a/database/migrations/2026_01_13_103047_create_brokers_table.php
+++ b/database/migrations/2026_01_13_103047_create_brokers_table.php
@@ -13,11 +13,10 @@ public function up(): void
{
Schema::create('brokers', function (Blueprint $table) {
$table->id();
- $table->text('bio');
- $table->string('location');
+ $table->text('bio')->nullable();
+ $table->string('location')->nullable();
$table->string('phone')->nullable();
$table->boolean('verified')->default(false);
- $table->boolean('active')->default(true);
$table->timestamps();
});
}
diff --git a/database/migrations/2026_01_13_105915_add_morph_relationiship_role.php b/database/migrations/2026_01_13_105915_add_morph_relationiship_role.php
index d91cf1e..ecfcc8f 100644
--- a/database/migrations/2026_01_13_105915_add_morph_relationiship_role.php
+++ b/database/migrations/2026_01_13_105915_add_morph_relationiship_role.php
@@ -12,7 +12,7 @@
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
- $table->nullableMorphs('type');
+ $table->nullableMorphs('role');
});
}
@@ -22,7 +22,7 @@ public function up(): void
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
- $table->dropMorphs('type');
+ $table->dropMorphs('role');
});
}
};
diff --git a/resources/js/alert.js b/resources/js/alert.js
new file mode 100644
index 0000000..7eb3a27
--- /dev/null
+++ b/resources/js/alert.js
@@ -0,0 +1,5 @@
+function removeAlert(child){
+ const parentAlert = child.closest('.alert');
+ parentAlert.style.display = "none";
+}
+document.removeAlert = removeAlert;
diff --git a/resources/js/image-input.js b/resources/js/image-input.js
index 5f31410..0cd1f83 100644
--- a/resources/js/image-input.js
+++ b/resources/js/image-input.js
@@ -31,6 +31,7 @@ function upload(size) {
closeModalBtn.addEventListener('click', () => {
// this closes then modal and sets the preview image
previewImage.src = imageUrl;
+ previewImage.style.display = "block";
modal.close();
})
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php
index ea385c3..9a70de9 100644
--- a/resources/views/auth/login.blade.php
+++ b/resources/views/auth/login.blade.php
@@ -15,15 +15,15 @@ class="bg-linear-135 h-screen from-[#EFF6FF] to-[#FCF3F8] flex flex-col justify-
@session('error')
-
{{$name ?? 'Name'}}
4.8