feature (stats in broker dashboard):
show individual brokers total likes, view and click per deal andin stats
This commit is contained in:
parent
3cd2644582
commit
9e7fda4ea2
22
app/Actions/GetBrokerStatsAction.php
Normal file
22
app/Actions/GetBrokerStatsAction.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions;
|
||||
|
||||
use App\Enums\InteractionType;
|
||||
use App\Models\User;
|
||||
|
||||
final readonly class GetBrokerStatsAction
|
||||
{
|
||||
/**
|
||||
* @return array<string, int>
|
||||
*/
|
||||
public function execute(User $user): array
|
||||
{
|
||||
return [
|
||||
'listings' => $user->deals()->count(),
|
||||
'likes' => $user->dealsInteractions()->where('type', InteractionType::Like)->count(),
|
||||
'views' => $user->dealsInteractions()->where('type', InteractionType::View)->sum('count'),
|
||||
'clicks' => $user->dealsInteractions()->where('type', InteractionType::Redirection)->sum('count'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -2,15 +2,17 @@
|
||||
|
||||
namespace App\Http\Controllers\Broker;
|
||||
|
||||
use App\Actions\GetBrokerStatsAction;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class BrokerDashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(GetBrokerStatsAction $getBrokerStatsAction)
|
||||
{
|
||||
return view('dashboards.broker.index')
|
||||
->with('deals', $this->deals());
|
||||
->with('deals', $this->deals())
|
||||
->with('stats', $getBrokerStatsAction->execute(Auth::user()));
|
||||
}
|
||||
|
||||
protected function deals()
|
||||
@ -28,6 +30,9 @@ protected function deals()
|
||||
'deal_category_id',
|
||||
])
|
||||
->with('category:id,name')
|
||||
->WithLikePerDeal()
|
||||
->WithRedirectionPerDeal()
|
||||
->withViewPerDeal()
|
||||
->latest()
|
||||
->paginate();
|
||||
}
|
||||
|
||||
@ -99,7 +99,6 @@ public function redirect(Deal $deal)
|
||||
|
||||
public function view(Deal $deal)
|
||||
{
|
||||
ds('hi');
|
||||
try {
|
||||
$interaction = $deal->interactions()->firstOrCreate([
|
||||
'type' => InteractionType::View,
|
||||
@ -109,7 +108,6 @@ public function view(Deal $deal)
|
||||
if (! $interaction->wasRecentlyCreated) {
|
||||
$interaction->increment('count');
|
||||
}
|
||||
ds($interaction);
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Error when view a deal',
|
||||
|
||||
@ -86,6 +86,19 @@ public function WithRedirectionPerDeal(Builder $query): Builder
|
||||
], 'count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to get a view count per deal
|
||||
*/
|
||||
#[Scope]
|
||||
public function withViewPerDeal(Builder $query): Builder
|
||||
{
|
||||
return $query->withSum([
|
||||
'interactions as total_views' => function ($query) {
|
||||
$query->where('type', InteractionType::View);
|
||||
},
|
||||
], 'count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a search in a query
|
||||
*/
|
||||
@ -105,4 +118,5 @@ public function filterByCategory(Builder $query, string $category): Builder
|
||||
{
|
||||
return $query->where('deal_category_id', $category);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
@ -78,4 +79,9 @@ public function recentSearches(): HasMany
|
||||
{
|
||||
return $this->hasMany(RecentSearch::class);
|
||||
}
|
||||
|
||||
public function dealsInteractions(): HasManyThrough
|
||||
{
|
||||
return $this->hasManyThrough(Interaction::class, Deal::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
@props(['deal'])
|
||||
|
||||
<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 items-start">
|
||||
@ -27,7 +26,7 @@ class="text-xs underline text-accent-601 mt-1">
|
||||
<div class="flex flex-col space-y-4">
|
||||
<p class="text-accent-600">{{$deal->category->name}}</p>
|
||||
|
||||
<x-dashboard.broker.listing-stats impression="0" likes="0" clicks="0"/>
|
||||
<x-dashboard.broker.listing-stats :views="$deal->total_views ?? 0" :likes="$deal->total_likes ?? 0" :clicks="$deal->total_redirection ?? 0"/>
|
||||
|
||||
<div class="flex justify-between space-x-4">
|
||||
<x-ui.button :link="route('broker.deals.edit', $deal->id)" class="w-full border border-accent-600/30"
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@props(['impression' => 0, 'likes' => 0, 'clicks' => 0])
|
||||
@props(['views' => 0, 'likes' => 0, 'clicks' => 0])
|
||||
<div class="flex items-center justify-between">
|
||||
<div class=" text-accent-600 flex space-x-2">
|
||||
<x-heroicon-o-eye class="w-4"/>
|
||||
<p class="text-sm">{{$impression}}</p>
|
||||
<p class="text-sm">{{$views}}</p>
|
||||
</div>
|
||||
|
||||
<div class=" text-accent-600 flex space-x-2">
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
@props(['list_count' => 0])
|
||||
@props(['stats' => []])
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 wrapper gap-y-4 gap-x-8">
|
||||
<x-dashboard.stats-card title="My Listings" :score="$list_count">
|
||||
<x-dashboard.stats-card title="My Listings" :score="$stats['listings']">
|
||||
<x-icon-square variant="blue">
|
||||
<x-heroicon-o-document-text class="w-8" />
|
||||
</x-icon-square>
|
||||
</x-dashboard.stats-card>
|
||||
|
||||
<x-dashboard.stats-card title="Total Views" score="12,483">
|
||||
<x-dashboard.stats-card title="Total Views" :score="$stats['views'] ?? 0">
|
||||
<x-icon-square variant="purple">
|
||||
<x-heroicon-o-eye class="w-8" />
|
||||
</x-icon-square>
|
||||
</x-dashboard.stats-card>
|
||||
<x-dashboard.stats-card title="Total Likes" score="1,847">
|
||||
<x-dashboard.stats-card title="Total Likes" :score="$stats['likes'] ?? 0">
|
||||
<x-icon-square variant="pink">
|
||||
<x-heroicon-o-heart class="w-8" />
|
||||
</x-icon-square>
|
||||
</x-dashboard.stats-card>
|
||||
<x-dashboard.stats-card title="Total Clicks" score="3,246">
|
||||
<x-dashboard.stats-card title="Total Clicks" :score="$stats['clicks'] ?? 0">
|
||||
<x-icon-square variant="green">
|
||||
<x-heroicon-o-cursor-arrow-rays class="w-8" />
|
||||
</x-icon-square>
|
||||
|
||||
@ -2,6 +2,6 @@
|
||||
<x-slot:heading>
|
||||
<x-dashboard.broker.navbar/>
|
||||
</x-slot:heading>
|
||||
<x-dashboard.broker.stats :list_count="$deals->count()"/>
|
||||
<x-dashboard.broker.stats :stats="$stats"/>
|
||||
<x-dashboard.broker.listing :deals="$deals"/>
|
||||
</x-dashboard.broker.layout>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user