Add per-user Like (پسندیدن) with a liked page and counts
Logged-in users can like a listing (job/shift/talent); dislike is removed per request — only likes.
- Like model (polymorphic by TargetType+TargetId) + EF migration; unique per (user, listing).
- POST /like toggles the like (auth required) and returns {liked, count}.
- Detail pages: the old ♡ Save / ✕ Dismiss buttons are replaced by a single heart Like button that
shows the live count and toggles in place; clicking while logged out redirects to login.
- New «❤️ پسندیدهها» page (/Me/Liked) lists everything the user liked (open listings only), with a
nav entry shown only when authenticated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -112,6 +112,10 @@
|
||||
<nav class="main-nav">
|
||||
<a asp-page="/Index" class="@(path == "/" ? "active" : null)">خانه</a>
|
||||
<a asp-page="/Recommendations/Index" class="@(path.StartsWith("/Recommendations") ? "active" : null)">✨ پیشنهادها</a>
|
||||
@if (User.Identity?.IsAuthenticated == true)
|
||||
{
|
||||
<a asp-page="/Me/Liked" class="@(path.StartsWith("/Me/Liked") ? "active" : null)">❤️ پسندیدهها</a>
|
||||
}
|
||||
<a href="/Shifts" data-tour="shifts" class="@(path.StartsWith("/Shifts") ? "active" : null)">شیفتها</a>
|
||||
<a href="/Jobs" data-tour="jobs" class="@(path.StartsWith("/Jobs") ? "active" : null)">استخدام</a>
|
||||
<a asp-page="/Talent/Index" class="@(path.StartsWith("/Talent") ? "active" : null)">آماده به کار</a>
|
||||
@@ -290,6 +294,36 @@
|
||||
<div id="contactModalBody" class="contact-modal-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
@* Like («پسندیدن») toggle — login-gated, updates the button state + count in place. *@
|
||||
<script>
|
||||
(function () {
|
||||
function fa(n) { return String(n).replace(/[0-9]/g, function (d) { return '۰۱۲۳۴۵۶۷۸۹'[+d]; }); }
|
||||
document.addEventListener('click', function (e) {
|
||||
var b = e.target.closest('.like-trigger');
|
||||
if (!b) return;
|
||||
e.preventDefault();
|
||||
if (document.body.dataset.authed !== '1') {
|
||||
location.href = '/Account/Login?returnUrl=' + encodeURIComponent(location.pathname);
|
||||
return;
|
||||
}
|
||||
var fd = new FormData();
|
||||
fd.append('type', b.dataset.likeType);
|
||||
fd.append('id', b.dataset.likeId);
|
||||
b.disabled = true;
|
||||
fetch('/like', { method: 'POST', body: fd })
|
||||
.then(function (r) { return r.ok ? r.json() : Promise.reject(); })
|
||||
.then(function (d) {
|
||||
b.dataset.liked = d.liked ? 'true' : 'false';
|
||||
b.classList.toggle('btn-accent', d.liked);
|
||||
b.classList.toggle('btn-outline', !d.liked);
|
||||
var ico = b.querySelector('.like-ico'); if (ico) ico.textContent = d.liked ? '♥' : '♡';
|
||||
var c = b.querySelector('.like-count'); if (c) c.textContent = fa(d.count);
|
||||
})
|
||||
.catch(function () {})
|
||||
.finally(function () { b.disabled = false; });
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function () {
|
||||
var modal = document.getElementById('contactModal');
|
||||
|
||||
Reference in New Issue
Block a user