Merge branch 'feature/user-feed' into bugfix/dealhub

This commit is contained in:
kusowl 2026-01-14 17:43:48 +05:30
commit d402ef4071
19 changed files with 202 additions and 14 deletions

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use App\Models\Deal;
class UserDashboardController extends Controller
{
public function index()
{
return view('dashboards.user.index')
->with('deals', $this->deals());
}
protected function deals()
{
return Deal::query()
->where('active', true)
->select([
'id',
'title',
'description',
'image',
'active',
'slug',
'link',
'deal_category_id',
'user_id',
])
->with([
'category:id,name',
'broker' => function ($query) {
$query->select('id', 'name', 'email', 'role_type', 'role_id')
->with('type');
},
])
->latest()
->paginate();
}
}

View File

@ -7,9 +7,9 @@
class Deal extends Model
{
public function User(): BelongsTo
public function broker(): BelongsTo
{
return $this->belongsTo(User::class);
return $this->belongsTo(User::class, 'user_id');
}
public function category(): BelongsTo

View File

@ -27,7 +27,7 @@ class="text-xs underline text-accent-601 mt-1">
<div class="flex flex-col space-y-4">
<p class="text-accent-600">{{$category}}</p>
<x-dashboard.listing-stats :impression="$impressions" :likes="$likes" :clicks="$clicks"/>
<x-dashboard.broker.listing-stats :impression="$impressions" :likes="$likes" :clicks="$clicks"/>
<div class="flex justify-between space-x-4">
<x-ui.button :link="route('broker.deals.edit', $id)" class="w-full border border-accent-600/30"

View File

@ -4,7 +4,7 @@
<p class="font-bold mb-6">My Listings</p>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
@forelse($deals as $deal)
<x-dashboard.listing-card
<x-dashboard.broker.listing-card
:id="$deal->id"
:image="asset('storage/'.$deal->image)"
:title="$deal->title"

View File

@ -0,0 +1,13 @@
<div class="">
<x-ui.button-sm class="text-accent-600">
<x-heroicon-o-heart class="w-4"/>
</x-ui.button-sm>
<x-ui.button-sm class="text-accent-600">
<x-heroicon-o-star class="w-4"/>
</x-ui.button-sm>
<x-ui.button-sm class="text-accent-600">
<x-heroicon-o-exclamation-circle class="w-4"/>
</x-ui.button-sm>
</div>

View File

@ -0,0 +1,10 @@
@props(['broker'])
<div class="p-4 text-sm">
<p class="font-bold mb-2">Broker Contact</p>
<div class="text-accent-600 space-y-1">
<p>{{$broker->name}}</p>
<p>{{$broker->email}}</p>
<p>{{$broker->role->phone}}</p>
</div>
</div>

View File

@ -0,0 +1,33 @@
@props(['deal' => '', 'broker' => ''])
<x-ui.image-card :image="asset('storage/'.$deal->image)">
<div class="bg-white pt-8 p-4 h-full space-y-4 flex flex-col justify-between">
<div class="flex justify-between">
<x-ui.button-sm variant="neutral">
{{$deal->category->name}}
</x-ui.button-sm>
<x-dashboard.user.action-toolbar />
</div>
<p class="font-bold text-lg ">{{$deal->title}}</p>
<p class="text-sm text-accent-600 wrap-break-word">{{$deal->description}}</p>
<x-dashboard.user.broker-contact :broker="$broker"/>
<div class="flex justify-between items-center">
<div class="flex space-x-3">
<x-dashboard.user.stat-badge :count="200">
<x-heroicon-o-heart class="w-4"/>
</x-dashboard.user.stat-badge>
<x-dashboard.user.stat-badge :count="433">
<x-heroicon-o-arrow-top-right-on-square class="w-4"/>
</x-dashboard.user.stat-badge>
</div>
<x-ui.button variant="neutral" class="flex space-x-2 items-center">
<p>View Deal</p>
<x-heroicon-o-arrow-top-right-on-square class="w-5 ml-1"/>
</x-ui.button>
</div>
</div>
</x-ui.image-card>

View File

@ -0,0 +1,9 @@
@props(['deals' => []])
<div class="grid md:grid-cols-2 gap-6">
@forelse($deals as $deal)
@ds($deal)
<x-dashboard.user.listing-card :deal="$deal" :broker="$deal->broker"/>
@empty
<p class="col-span-2 text-sm text-center text-accent-600">No Deals found till now !</p>
@endforelse
</div>

View File

@ -0,0 +1,5 @@
@props(['count' => 0])
<div class="flex text-accent-600 space-x-1">
{{$slot}}
<p>{{$count}}</p>
</div>

View File

@ -1,5 +1,5 @@
@props(['label' => '', 'name' => '', 'placeholder' => '', 'type' => 'text', 'description' => '', 'required' => false, 'value' => ''])
<div class="flex flex-col space-y-2">
<div {{$attributes->merge(['class' => 'flex flex-col space-y-2'])}}>
@if($label !== '')
<label class="text-sm font-bold" for="{{$name}}">
{{$label}}

View File

@ -23,7 +23,7 @@
<select
name="{{$name}}"
required="{{$required?'required':''}}"
class="bg-[#F3F3F5] py-2 px-4 rounded-lg text-sm font-bold invalid:text-accent-600 text-black"
class="bg-[#F3F3F5] py-2 px-4 rounded-lg text-sm font-bold invalid:text-accent-600 text-black h-full"
>
@if($placeholder !== '')
<option {{old($name) === ''? 'selected' : ''}} disabled>{{$placeholder}}</option>

View File

@ -0,0 +1,4 @@
@props(['activeColor' => 'bg-white'])
<div {{$attributes->merge(['class' => 'flex bg-[#ececf0] p-1 rounded-full w-fit'])}}>
{{$slot}}
</div>

View File

@ -0,0 +1,8 @@
@props(['active' => false])
@aware(['activeColor' => 'bg-white'])
<div
{{$attributes}}
{{$attributes->class(["rounded-full", $activeColor => $active])}}
>
{{ $slot }}
</div>

View File

@ -1,6 +1,6 @@
<x-layout title="Broker Dashboard">
<section class="flex flex-col space-y-8 bg-[#F9FAFB]">
<x-dashboard.navbar/>
<x-dashboard.broker.navbar/>
<div class="wrapper">
@session('success')
@ -12,8 +12,8 @@
@endsession
</div>
<x-dashboard.stats :list_count="$deals->count()"/>
<x-dashboard.listing :deals="$deals"/>
<x-dashboard.broker.stats :list_count="$deals->count()"/>
<x-dashboard.broker.listing :deals="$deals"/>
</section>
@vite('resources/js/nav-menu.js')
</x-layout>

View File

@ -1,3 +1,64 @@
<x-layout title="User Dashboard">
@php
$categories = [0 => ['name' => 'All Categories', 'value' => '0']];
@endphp
<x-layout title="Deals">
<x-dashboard.page-heading
title="Explore Deals"
description="Discover trusted recommendation"
>
<x-slot:end>
<form method="post" action="{{route('logout')}}">
@csrf
@method('delete')
<x-ui.button class="flex space-x-3 hover:bg-gray-100 hover:border-gray-300 hover:border">
<x-heroicon-o-arrow-right-start-on-rectangle class="w-4 stroke-2 mr-2"/>
<p class="hidden sm:block">Logout</p>
</x-ui.button>
</form>
</x-slot:end>
</x-dashboard.page-heading>
<section class="flex flex-col space-y-8 bg-[#F9FAFB] wrapper mt-2 pb-6">
<div>
@session('success')
<x-ui.alert variant="success">{{$value}}</x-ui.alert>
@endsession
@session('error')
<x-ui.alert variant="error">{{$value}}</x-ui.alert>
@endsession
</div>
<x-dashboard.card>
<div class="flex space-x-4">
<x-ui.input class="flex-1" name="search" placeholder="Search deals, services, places"/>
<x-ui.select name="category" :options="$categories" value-key="value" label-key="name" />
</div>
</x-dashboard.card>
<x-ui.toggle-button-group>
<x-ui.toggle-button active>
<a href="" class="flex items-center px-2 py-1 space-x-2">
<x-heroicon-o-clock class="w-4 stroke-2" />
<p class="font-bold">All Deals</p>
</a>
</x-ui.toggle-button>
<x-ui.toggle-button>
<a href="" class="flex items-center px-2 py-1 space-x-2">
<x-heroicon-o-arrow-trending-up class="w-4 stroke-2" />
<p class="font-bold">Most Liked</p>
</a>
</x-ui.toggle-button>
<x-ui.toggle-button>
<a href="" class="flex items-center px-2 py-1 space-x-2">
<x-heroicon-o-star class="w-4 stroke-2" />
<p class="font-bold">Most Clicked</p>
</a>
</x-ui.toggle-button>
</x-ui.toggle-button-group>
<x-dashboard.user.listing :deals="$deals" />
</section>
</x-layout>

View File

@ -7,6 +7,7 @@
use App\Http\Controllers\BrokerDealController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\RegisteredUserController;
use App\Http\Controllers\User\UserDashboardController;
use App\Http\Middleware\HasRole;
use Illuminate\Support\Facades\Route;
@ -20,14 +21,17 @@
Route::middleware('auth')->group(function () {
Route::delete('/logout', [AuthenticatedUserController::class, 'destroy'])->name('logout');
Route::view('/user/dashboard', 'dashboards.user.index')
->middleware(HasRole::class.':'.UserTypes::User->value)
->name('user.dashboard');
Route::view('/admin/dashboard', 'dashboards.admin.index')
->middleware(HasRole::class.':'.UserTypes::Admin->value)
->name('admin.dashboard');
Route::prefix('/user')
->name('user.')
->middleware(HasRole::class.':'.UserTypes::User->value)
->group(function () {
Route::get('dashboard', [UserDashboardController::class, 'index'])->name('dashboard');
});
Route::prefix('/broker')
->name('broker.')
->middleware(HasRole::class.':'.UserTypes::Broker->value)