I have a method for adding likes to a page
blade.php
<a href="/article/{{ $article->id }}?type=heart" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_heart }}
</div>
<a href="/article/{{ $article->id }}?type=finger" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_finger }}
</div>
Adding a like on click
js
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
});
$('.like-button').on('click', function(event) {
event.preventDefault();
let href = $(this).attr('href');
$.ajax({
url: href,
type: 'POST',
success: function() {
window.location.reload();
},
});
});
});
Next, I made an active class with styles, and when I click on the like to the class class="comments-sub-header__item like-button" this class should be added active
But there is one more thing, my likes are stored in cookies, and 24 hours after clicking we can put a new like, that is, the active class should also be disabled after 24 hours
This is how I implemented it adding a like to cookies
Route::post('article/{id}', 'App\Http\Controllers\ArticleController@postLike');
public function postLike($id, Request $request) {
$article = Article::find($id);
if(!$article){
return abort(404);
}
$type = $request->input('type');
if ($article->hasLikedToday($type)) {
return response()
->json([
'message' => 'You have already liked the Article '.$article->id.' with '.$type.'.',
]);
}
$cookie = $article->setLikeCookie($type);
$article->increment("like_{$type}");
return response()
->json([
'message' => 'Liked the Article '.$article->id.' with '.$type.'.',
'cookie_json' => $cookie->getValue(),
])
->withCookie($cookie);
}
public function hasLikedToday(string $type)
{
$articleLikesJson = Cookie::get('article_likes', '{}');
$articleLikes = json_decode($articleLikesJson, true);
if (!array_key_exists($this->id, $articleLikes)) {
return false;
}
if (!array_key_exists($type, $articleLikes[$this->id])) {
return false;
}
$likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$this->id][$type]);
return ! $likeDatetime->addDay()->lt(now());
}
public function setLikeCookie(string $type)
{
$articleLikesJson = Cookie::get('article_likes', '[]');
$articleLikes = json_decode($articleLikesJson, true);
$articleLikes[$this->id][$type] = now()->format('Y-m-d H:i:s');
$articleLikesJson = json_encode($articleLikes);
return cookie()->forever('article_likes', $articleLikesJson);
}
As I understand it, all this should be done in js, but I still do not really understand it, so I ask for a hint
Simply share a variable in the view where you show the "like" buttons somewhere in your controller:
// Your controller
public function show(Request $request, $postId)
{
$post = Post::find($postId);
$hasLikedToday = $post->hasLikedToday('heart');
return view('your.view.file', [
'article' => $article,
'hasLikedToday' => $hasLikedToday, // share this variable to check if you've liked today
]);
}
After sending the hasLikedToday variable to your blade where the like buttons are defined, you simply check if the variable is true, if so, show the active class. Now every time you refresh that page, it will check if the active class must be shown, no need for javascript to do that.
<a href="/article/{{ $article->id }}?type=heart" class=" ... {{ $hasLikedToday ? 'active' : '' }}">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_heart }}
</div>