2023-01-26 22:07:11 +00:00
|
|
|
import useSWR from 'swr'
|
2023-01-17 21:24:16 +00:00
|
|
|
import {ElementType, useEffect} from 'react'
|
|
|
|
import fetcher from '@/lib/fetcher'
|
2023-01-26 22:07:11 +00:00
|
|
|
import {numberFormat} from '@/lib/numberFormat'
|
2023-01-17 21:24:16 +00:00
|
|
|
|
2023-01-30 16:30:44 +00:00
|
|
|
type ViewsResponse = {
|
2023-01-19 12:56:26 +00:00
|
|
|
views: string
|
|
|
|
}
|
2023-01-18 21:36:47 +00:00
|
|
|
|
2023-01-26 23:29:39 +00:00
|
|
|
type ViewsProps = {
|
|
|
|
as?: ElementType
|
|
|
|
slug: string
|
|
|
|
className?: string
|
|
|
|
shouldUpdateViews?: boolean
|
|
|
|
}
|
|
|
|
|
2023-01-18 21:36:47 +00:00
|
|
|
const updateViews = (slug: string) => fetcher(`/api/views/${slug}`, {method: 'POST'})
|
2023-01-17 21:24:16 +00:00
|
|
|
|
2023-01-26 23:29:39 +00:00
|
|
|
export function Views({as: Component = 'span', slug, className, shouldUpdateViews = true}: ViewsProps) {
|
2023-01-30 16:30:44 +00:00
|
|
|
const {data} = useSWR<ViewsResponse>(`/api/views/${slug}`, fetcher, {
|
2023-01-19 12:56:26 +00:00
|
|
|
revalidateOnFocus: false,
|
|
|
|
revalidateOnMount: true
|
|
|
|
})
|
2023-01-17 21:24:16 +00:00
|
|
|
const views = Number(data?.views)
|
|
|
|
|
|
|
|
useEffect(() => {
|
2023-01-26 23:29:39 +00:00
|
|
|
if (shouldUpdateViews) {
|
|
|
|
updateViews(slug).then(r => r);
|
|
|
|
}
|
2023-01-26 23:50:25 +00:00
|
|
|
}, [slug, shouldUpdateViews])
|
2023-01-17 21:24:16 +00:00
|
|
|
|
|
|
|
return (
|
2023-01-26 23:29:39 +00:00
|
|
|
<Component className={className}>
|
2023-01-19 12:56:26 +00:00
|
|
|
{` · ${views > 0 ? numberFormat(views) : '—'} views`}
|
2023-01-17 21:24:16 +00:00
|
|
|
</Component>
|
|
|
|
)
|
|
|
|
}
|