Files
anwar-pi-website/web/src/app/(frontend)/posts/[slug]/engagement.tsx
T
2026-10-09 16:20:55 +03:00

54 lines
1.7 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
/* Views ping — counts one view per browser session per post (global counter
on the backend). */
export function ViewPing({ slug }: { slug: string }) {
useEffect(() => {
const key = `anw-viewed:${slug}`
try {
if (sessionStorage.getItem(key)) return
sessionStorage.setItem(key, '1')
} catch { /* private mode — count anyway */ }
fetch(`/api/posts/${slug}/view`, { method: 'POST', keepalive: true }).catch(() => null)
}, [slug])
return null
}
/* Like toggle — login required; one like per user per post. */
export function LikeButton({ slug, loggedIn, initialLiked, initialCount }: { slug: string; loggedIn: boolean; initialLiked: boolean; initialCount: number }) {
const [liked, setLiked] = useState(initialLiked)
const [count, setCount] = useState(initialCount)
const [busy, setBusy] = useState(false)
async function toggle() {
if (!loggedIn) {
location.href = `/login?next=/posts/${slug}`
return
}
setBusy(true)
const res = await fetch(`/api/posts/${slug}/like`, { method: 'POST' })
if (res.ok) {
const data = await res.json()
setLiked(data.liked)
setCount(data.likes)
}
setBusy(false)
}
return (
<button
className="like"
type="button"
onClick={toggle}
disabled={busy}
aria-pressed={liked}
aria-label={liked ? 'ألغِ الإعجاب' : 'أعجبني'}
>
<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M8 13.5 2.6 8.3a3.2 3.2 0 0 1 4.5-4.6L8 4.6l.9-.9a3.2 3.2 0 0 1 4.5 4.6Z" fill="none" stroke="currentColor" strokeWidth="1.4" /></svg>
<span>{count}</span>
</button>
)
}