feature (external link redirection count of deal):

bind the link with the view deal button
show the total redirection count
reflect the total redirect count immediately
add arch test so that dump statements are not left out
This commit is contained in:
kusowl 2026-01-19 16:39:49 +05:30
parent af6d629b68
commit e5ebe21ed1
9 changed files with 52 additions and 22 deletions

View File

@ -35,6 +35,7 @@ protected function deals()
// Check if the current user interacted with the deal // Check if the current user interacted with the deal
->withCurrentUserInteractions() ->withCurrentUserInteractions()
->withLikes() ->withLikes()
->withRedirections()
->latest() ->latest()
->paginate(); ->paginate();
} }

View File

@ -18,7 +18,7 @@ class InteractionController extends Controller
*/ */
public function togglesState(Deal $deal, InteractionType $type) public function togglesState(Deal $deal, InteractionType $type)
{ {
if (!in_array($type, [InteractionType::Like, InteractionType::Favorite])) { if (! in_array($type, [InteractionType::Like, InteractionType::Favorite])) {
return response()->json(['error' => 'This interaction is not supported'], 400); return response()->json(['error' => 'This interaction is not supported'], 400);
} }
@ -77,7 +77,7 @@ public function redirect(Deal $deal)
'user_id' => Auth::id(), 'user_id' => Auth::id(),
]); ]);
if (!$interaction->wasRecentlyCreated) { if (! $interaction->wasRecentlyCreated) {
$interaction->increment('count'); $interaction->increment('count');
} }

View File

@ -61,6 +61,15 @@ public function scopeWithLikes(Builder $query): Builder
]); ]);
} }
public function scopeWithRedirections(Builder $query): Builder
{
return $query->withSum([
'interactions as total_redirection' => function ($query) {
$query->where('type', InteractionType::Redirection);
},
], 'count');
}
public function reports(): BelongsToMany public function reports(): BelongsToMany
{ {
return $this->belongsToMany(Report::class); return $this->belongsToMany(Report::class);

View File

@ -11,6 +11,9 @@
<testsuite name="Feature"> <testsuite name="Feature">
<directory>tests/Feature</directory> <directory>tests/Feature</directory>
</testsuite> </testsuite>
<testsuite name="Architecture">
<directory>tests/Arch</directory>
</testsuite>
</testsuites> </testsuites>
<source> <source>
<include> <include>

View File

@ -66,5 +66,22 @@ function updateLikeCount(badge, change){
} }
} }
function redirect(url, id){
window.open(url, '_blank');
let redirectBadge = document.getElementById("redirectBadge".concat(id));
updateRedirectCount(redirectBadge, 1);
// increment the count in ui
}
function updateRedirectCount(badge, change){
try{
let likeCount = Math.max(parseInt( badge.dataset.count) + change, 0)
badge.querySelector('p').innerText = likeCount;
badge.dataset.count = likeCount.toString();
}
catch(e) {
console.error(e);
}
}
document.like = like; document.like = like;
document.favorite = favorite; document.favorite = favorite;
document.redirect = redirect;

View File

@ -1,15 +1,5 @@
@props(['deal_id', 'deal_title', 'like' => false, 'favourite' => false, 'deal_link' => '']) @props(['deal_id', 'deal_title', 'like' => false, 'favourite' => false])
<div class=""> <div class="">
@if(filled($deal_link))
<x-ui.button-sm @class(["text-accent-600"]) external="true" :link="\Illuminate\Support\Facades\URL::signedRoute('redirect', $deal_id)">
<x-heroicon-o-arrow-top-right-on-square
@class([
"w-4",
])
/>
</x-ui.button-sm>
@endif
<x-ui.button-sm @class(["text-accent-600", 'liked' => $like]) onclick="like(this, {{$deal_id}})"> <x-ui.button-sm @class(["text-accent-600", 'liked' => $like]) onclick="like(this, {{$deal_id}})">
<x-heroicon-o-heart <x-heroicon-o-heart
@class([ @class([

View File

@ -5,8 +5,7 @@
<x-ui.button-sm variant="neutral"> <x-ui.button-sm variant="neutral">
{{$deal->category->name}} {{$deal->category->name}}
</x-ui.button-sm> </x-ui.button-sm>
@ds($deal) <x-dashboard.user.action-toolbar :deal_title="$deal->title" :deal_id="$deal->id" :like="$deal->is_liked" :favourite="$deal->is_favorite" />
<x-dashboard.user.action-toolbar :deal_link="$deal->link" :deal_title="$deal->title" :deal_id="$deal->id" :like="$deal->is_liked" :favourite="$deal->is_favorite" />
</div> </div>
<p class="font-bold text-lg ">{{$deal->title}}</p> <p class="font-bold text-lg ">{{$deal->title}}</p>
@ -21,14 +20,16 @@
<x-heroicon-o-heart class="w-4"/> <x-heroicon-o-heart class="w-4"/>
</x-dashboard.user.stat-badge> </x-dashboard.user.stat-badge>
<x-dashboard.user.stat-badge :count="433"> <x-dashboard.user.stat-badge id="{{'redirectBadge'.$deal->id}}" :count="$deal->total_redirection">
<x-heroicon-o-arrow-top-right-on-square class="w-4"/> <x-heroicon-o-arrow-top-right-on-square class="w-4"/>
</x-dashboard.user.stat-badge> </x-dashboard.user.stat-badge>
</div> </div>
<x-ui.button variant="neutral" class="flex space-x-2 items-center"> @if(filled($deal->link))
<p>View Deal</p> <x-ui.button onclick="redirect('{{\Illuminate\Support\Facades\URL::signedRoute('redirect', $deal->id)}}', {{$deal->id}})" variant="neutral" class="flex space-x-2 items-center">
<x-heroicon-o-arrow-top-right-on-square class="w-5 ml-1"/> <p>View Deal</p>
</x-ui.button> <x-heroicon-o-arrow-top-right-on-square class="w-5 ml-1"/>
</x-ui.button>
@endif
</div> </div>
</div> </div>
</x-ui.image-card> </x-ui.image-card>

View File

@ -1,4 +1,4 @@
@props(['variant' => '', 'icon' => '', 'link' => '']) @props(['variant' => '', 'icon' => '', 'link' => '', 'external' => false])
@php @php
$variants = [ $variants = [
'neutral' => 'bg-primary-600 text-white', 'neutral' => 'bg-primary-600 text-white',
@ -9,7 +9,11 @@
$variantClass = $variants[$variant] ?? ''; $variantClass = $variants[$variant] ?? '';
@endphp @endphp
@if($link !== '') @if($link !== '')
<a {{$attributes->merge(['class' => "block px-4 py-2 rounded-lg font-medium hover:opacity-80 active:scale-80 transition-all ease-in-out duration-300 $variantClass", 'href' => $link])}}> <a
@if($external)
target="_blank"
@endif
{{$attributes->merge(['class' => "block px-4 py-2 rounded-lg font-medium hover:opacity-80 active:scale-80 transition-all ease-in-out duration-300 $variantClass", 'href' => $link])}}>
<div class="flex justify-center items-center space-x-2"> <div class="flex justify-center items-center space-x-2">
@if($icon !=='') @if($icon !=='')
@svg("heroicon-o-$icon", 'w-5 h-5') @svg("heroicon-o-$icon", 'w-5 h-5')

5
tests/Arch/ArchTest.php Normal file
View File

@ -0,0 +1,5 @@
<?php
arch('does not use debug functions')
->expect(['ds', 'dsd', 'dsq', 'dd', 'ddd', 'dump', 'ray', 'die', 'var_dump', 'sleep', 'exit'])
->not->toBeUsed();