feature(customer profile): add show and edit page for customer profile
This commit is contained in:
parent
193913dfad
commit
4f34c5b595
@ -7,7 +7,7 @@
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\StoreRegisterdUser;
|
use App\Http\Requests\StoreRegisterdUser;
|
||||||
use App\Models\Broker;
|
use App\Models\Broker;
|
||||||
use App\Models\User;
|
use App\Models\Customer;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
@ -23,16 +23,24 @@ public function store(StoreRegisterdUser $request)
|
|||||||
$data = $request->validated();
|
$data = $request->validated();
|
||||||
try {
|
try {
|
||||||
DB::transaction(function () use ($data) {
|
DB::transaction(function () use ($data) {
|
||||||
if ($data['role'] === UserTypes::Broker->value) {
|
switch ($data['role']) {
|
||||||
$data['status'] = UserStatus::Pending->value;
|
case UserTypes::Broker->value:
|
||||||
|
{
|
||||||
|
$data['status'] = UserStatus::Pending->value;
|
||||||
|
|
||||||
// Create Broker first, then the User linked to it
|
// Create Broker first, then link the user
|
||||||
$broker = Broker::create();
|
$broker = Broker::create();
|
||||||
$broker->user()->create($data);
|
$broker->user()->create($data);
|
||||||
} else {
|
break;
|
||||||
$data['status'] = UserStatus::Active->value;
|
}
|
||||||
|
case UserTypes::User->value:
|
||||||
|
{
|
||||||
|
$data['status'] = UserStatus::Active->value;
|
||||||
|
|
||||||
User::create($data);
|
$customer = Customer::create();
|
||||||
|
$customer->user()->create($data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ protected function profileLink(): string
|
|||||||
|
|
||||||
return match ($user->role) {
|
return match ($user->role) {
|
||||||
UserTypes::Broker->value => route('broker.profile.show', $user),
|
UserTypes::Broker->value => route('broker.profile.show', $user),
|
||||||
UserTypes::User->value => route('user.profile.show', $user),
|
UserTypes::User->value => route('customer.profile.show', $user),
|
||||||
default => ''
|
default => ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,7 +100,6 @@ public function redirect(Deal $deal)
|
|||||||
|
|
||||||
public function view(Deal $deal)
|
public function view(Deal $deal)
|
||||||
{
|
{
|
||||||
ds('hi');
|
|
||||||
try {
|
try {
|
||||||
$interaction = $deal->interactions()->firstOrCreate([
|
$interaction = $deal->interactions()->firstOrCreate([
|
||||||
'type' => InteractionType::View,
|
'type' => InteractionType::View,
|
||||||
@ -110,7 +109,6 @@ public function view(Deal $deal)
|
|||||||
if (! $interaction->wasRecentlyCreated) {
|
if (! $interaction->wasRecentlyCreated) {
|
||||||
$interaction->increment('count');
|
$interaction->increment('count');
|
||||||
}
|
}
|
||||||
ds($interaction);
|
|
||||||
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::error('Error when view a deal',
|
Log::error('Error when view a deal',
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\StoreBrokerProfileRequest;
|
use App\Http\Requests\StoreBrokerProfileRequest;
|
||||||
|
use App\Http\Requests\StoreCustomerProfileRequest;
|
||||||
use App\Models\Broker;
|
use App\Models\Broker;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Services\ProfileInitialsService;
|
use App\Services\ProfileInitialsService;
|
||||||
@ -24,11 +25,11 @@ public function show(User $profile, ProfileInitialsService $service)
|
|||||||
$initials = $service->create($profile->name);
|
$initials = $service->create($profile->name);
|
||||||
|
|
||||||
return view('dashboards.user.profile.show')
|
return view('dashboards.user.profile.show')
|
||||||
|
->with('user', $profile)
|
||||||
->with('name', $profile->name)
|
->with('name', $profile->name)
|
||||||
->with('joinDate', $profile->created_at->format('F Y'))
|
->with('joinDate', $profile->created_at->format('F Y'))
|
||||||
->with('email', $profile->email)
|
->with('email', $profile->email)
|
||||||
->with('initials', $initials)
|
->with('initials', $initials)
|
||||||
->with('verified', $user->verified)
|
|
||||||
->with('location', $user->location)
|
->with('location', $user->location)
|
||||||
->with('bio', $user->bio)
|
->with('bio', $user->bio)
|
||||||
->with('phone', $user->phone);
|
->with('phone', $user->phone);
|
||||||
@ -39,7 +40,7 @@ public function show(User $profile, ProfileInitialsService $service)
|
|||||||
*/
|
*/
|
||||||
public function edit(User $profile)
|
public function edit(User $profile)
|
||||||
{
|
{
|
||||||
return view('dashboards.broker.profile.edit')
|
return view('dashboards.user.profile.edit')
|
||||||
->with('profile', $profile)
|
->with('profile', $profile)
|
||||||
->with('broker', $profile->type);
|
->with('broker', $profile->type);
|
||||||
}
|
}
|
||||||
@ -47,7 +48,7 @@ public function edit(User $profile)
|
|||||||
/**
|
/**
|
||||||
* Update the specified resource in storage.
|
* Update the specified resource in storage.
|
||||||
*/
|
*/
|
||||||
public function update(StoreBrokerProfileRequest $request, User $profile)
|
public function update(StoreCustomerProfileRequest $request, User $profile)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Separate the user fields from the broker fields
|
* Separate the user fields from the broker fields
|
||||||
@ -58,19 +59,16 @@ public function update(StoreBrokerProfileRequest $request, User $profile)
|
|||||||
$userData = $data->except($userFields)->toArray();
|
$userData = $data->except($userFields)->toArray();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DB::transaction(function () use ($profile, $userData) {
|
DB::transaction(function () use ($profileData, $profile, $userData) {
|
||||||
$profile->update($userData);
|
$profile->update($profileData);
|
||||||
$user = $profile->type;
|
$user = $profile->type;
|
||||||
|
|
||||||
Broker::unguard();
|
|
||||||
$user->update($userData);
|
$user->update($userData);
|
||||||
Broker::reguard();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return to_route('broker.profile.show', $profile)
|
return to_route('customer.profile.show', $profile)
|
||||||
->with('success', 'Profile updated successfully.');
|
->with('success', 'Profile updated successfully.');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::error('Broker Profile Update Failed: '.$e->getMessage(), $e->getTrace());
|
Log::error('Customer Profile Update Failed: '.$e->getMessage(), $e->getTrace());
|
||||||
|
|
||||||
return back()->withInput()->with('error', 'Something went wrong.');
|
return back()->withInput()->with('error', 'Something went wrong.');
|
||||||
}
|
}
|
||||||
|
|||||||
33
app/Http/Requests/StoreCustomerProfileRequest.php
Normal file
33
app/Http/Requests/StoreCustomerProfileRequest.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class StoreCustomerProfileRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return $this->user()->isCustomer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|string|min:3|max:255',
|
||||||
|
'bio' => 'required|string|min:10|max:255',
|
||||||
|
'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($this->user()->id)],
|
||||||
|
'phone' => 'required|string|min:10|max:255',
|
||||||
|
'location' => 'required|string|min:3|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/Models/Customer.php
Normal file
15
app/Models/Customer.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||||
|
|
||||||
|
class Customer extends Model
|
||||||
|
{
|
||||||
|
protected $fillable = ['bio', 'location', 'phone'];
|
||||||
|
public function user(): MorphOne
|
||||||
|
{
|
||||||
|
return $this->morphOne(User::class, 'role');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
@ -78,4 +77,9 @@ public function recentSearches(): HasMany
|
|||||||
{
|
{
|
||||||
return $this->hasMany(RecentSearch::class);
|
return $this->hasMany(RecentSearch::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isCustomer(): bool
|
||||||
|
{
|
||||||
|
return $this->type instanceof Customer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('customers', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->text('bio')->nullable();
|
||||||
|
$table->string('location')->nullable();
|
||||||
|
$table->string('phone')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('customers');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,15 +1,13 @@
|
|||||||
<x-dashboard.broker.layout title="Edit Broker Profile">
|
<x-layout title="Edit Broker Profile">
|
||||||
<x-slot:heading>
|
<x-dashboard.page-heading
|
||||||
<x-dashboard.page-heading
|
title="Edit Profile"
|
||||||
title="Edit Profile"
|
description="Modify your profile details"
|
||||||
description="Modify your profile details"
|
:back-link="route('customer.profile.show', $profile)"
|
||||||
:back-link="route('broker.profile.show', $profile)"
|
/>
|
||||||
/>
|
<div class="flex items-center justify-center mt-4 md:mt-8 px-4 pb-4 pt-0 md:px-8 md:pb-8">
|
||||||
</x-slot:heading>
|
|
||||||
<div class="flex items-center justify-center px-4 pb-4 pt-0 md:px-8 md:pb-8">
|
|
||||||
<x-dashboard.card class="w-full">
|
<x-dashboard.card class="w-full">
|
||||||
<h3 class="text-md font-bold">Profile Information</h3>
|
<h3 class="text-md font-bold">Profile Information</h3>
|
||||||
<form method="post" enctype="multipart/form-data" action="{{route('broker.profile.update', $profile)}}"
|
<form method="post" enctype="multipart/form-data" action="{{route('customer.profile.update', $profile)}}"
|
||||||
class="flex flex-col space-y-8 mt-4">
|
class="flex flex-col space-y-8 mt-4">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PATCH')
|
@method('PATCH')
|
||||||
@ -36,4 +34,4 @@ class=" border border-accent-600/20 md:col-span-2">Cancel
|
|||||||
</form>
|
</form>
|
||||||
</x-dashboard.card>
|
</x-dashboard.card>
|
||||||
</div>
|
</div>
|
||||||
</x-dashboard.broker.layout>
|
</x-layout>
|
||||||
|
|||||||
@ -1,22 +1,21 @@
|
|||||||
<x-dashboard.broker.layout title="Profile">
|
<x-layout title="Profile">
|
||||||
|
<x-dashboard.page-heading
|
||||||
<x-slot:heading>
|
title="Your Profile"
|
||||||
<x-dashboard.page-heading
|
description="Your public information"
|
||||||
title="Broker Profile"
|
:back-link="route('explore')"
|
||||||
description="Public profile information"
|
>
|
||||||
:back-link="route('broker.dashboard')"
|
<x-slot:end>
|
||||||
>
|
<div class="flex">
|
||||||
<x-slot:end>
|
<x-ui.button :link="route('customer.profile.edit', auth()->user()->id)"
|
||||||
<x-ui.button :link="route('broker.profile.edit', auth()->user()->id)"
|
|
||||||
class="border border-accent-600/40">
|
class="border border-accent-600/40">
|
||||||
<p class="hidden sm:block">Edit profile</p>
|
<p class="hidden sm:block">Edit profile</p>
|
||||||
<x-heroicon-o-pencil-square class="w-4 stroke-2 sm:hidden"/>
|
<x-heroicon-o-pencil-square class="w-4 stroke-2 sm:hidden"/>
|
||||||
</x-ui.button>
|
</x-ui.button>
|
||||||
</x-slot:end>
|
</div>
|
||||||
</x-dashboard.page-heading>
|
</x-slot:end>
|
||||||
</x-slot:heading>
|
</x-dashboard.page-heading>
|
||||||
|
|
||||||
<div class="flex items-center justify-center px-4 pb-4 pt-0 md:px-8 md:pb-8">
|
<div class="flex items-center justify-center mt-4 md:mt-8 px-4 pb-4 pt-0 md:px-8 md:pb-8">
|
||||||
<div class="flex items-center justify-center w-full">
|
<div class="flex items-center justify-center w-full">
|
||||||
<x-dashboard.card class="w-full">
|
<x-dashboard.card class="w-full">
|
||||||
<div class="grid grid-cols-8 gap-6">
|
<div class="grid grid-cols-8 gap-6">
|
||||||
@ -33,12 +32,6 @@ class="w-25 h-25 rounded-xl bg-linear-150 from-[#305afc] to-[#941dfb] text-5xl t
|
|||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<p class="text-3xl font-bold">{{$name ?? 'Name'}}</p>
|
<p class="text-3xl font-bold">{{$name ?? 'Name'}}</p>
|
||||||
<div class="flex space-x-1 mt-2">
|
|
||||||
<x-ui.button-sm
|
|
||||||
variant="neutral">{{$verified ? 'Verified Broker' : 'Not Verified'}}</x-ui.button-sm>
|
|
||||||
<x-heroicon-s-star class="ml-2 w-4 fill-amber-300"/>
|
|
||||||
<p>4.8</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wrap-break-word">
|
<div class="wrap-break-word">
|
||||||
@ -68,4 +61,4 @@ class="w-25 h-25 rounded-xl bg-linear-150 from-[#305afc] to-[#941dfb] text-5xl t
|
|||||||
</x-dashboard.card>
|
</x-dashboard.card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-dashboard.broker.layout>
|
</x-layout>
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
require __DIR__.'/web/auth.php';
|
require __DIR__.'/web/auth.php';
|
||||||
require __DIR__.'/web/broker.php';
|
require __DIR__.'/web/broker.php';
|
||||||
require __DIR__.'/web/interaction.php';
|
require __DIR__.'/web/interaction.php';
|
||||||
require __DIR__.'/web/user.php';
|
require __DIR__.'/web/customer.php';
|
||||||
|
|
||||||
Route::get('/', HomeController::class)->name('home');
|
Route::get('/', HomeController::class)->name('home');
|
||||||
Route::middleware('auth')->group(function () {
|
Route::middleware('auth')->group(function () {
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
use App\Http\Controllers\User\UserProfileController;
|
use App\Http\Controllers\User\UserProfileController;
|
||||||
use App\Http\Middleware\HasRole;
|
use App\Http\Middleware\HasRole;
|
||||||
|
|
||||||
Route::prefix('/user')
|
Route::prefix('/customer')
|
||||||
->name('user.')
|
->name('customer.')
|
||||||
->middleware([HasRole::class.':'.UserTypes::User->value, 'auth'])
|
->middleware([HasRole::class.':'.UserTypes::User->value, 'auth'])
|
||||||
->group(function () {
|
->group(function () {
|
||||||
Route::resource('profile', UserProfileController::class)->except('index', 'store', 'create');
|
Route::resource('profile', UserProfileController::class)->except('index', 'store', 'create');
|
||||||
Loading…
x
Reference in New Issue
Block a user