Refactored views component

This commit is contained in:
r-freeman 2023-04-10 23:58:18 +01:00
parent d5c320c88a
commit 126b66ac09

View File

@ -1,7 +1,8 @@
import {ElementType, useEffect, useState} from 'react' import {ElementType, useEffect} from 'react'
import fetcher from '@/lib/fetcher' import fetcher from '@/lib/fetcher'
import {numberFormat} from '@/lib/numberFormat' import {numberFormat} from '@/lib/numberFormat'
import {supabase} from '@/lib/supabase' import {supabase} from '@/lib/supabase'
import useSWR, {useSWRConfig} from 'swr'
type ViewsProps = { type ViewsProps = {
as?: ElementType as?: ElementType
@ -10,44 +11,35 @@ type ViewsProps = {
shouldUpdateViews?: boolean shouldUpdateViews?: boolean
} }
const NEXT_PUBLIC_SITE_URL = process.env.NEXT_PUBLIC_SITE_URL
export function Views({as: Component = 'span', slug, className, shouldUpdateViews = false}: ViewsProps) { export function Views({as: Component = 'span', slug, className, shouldUpdateViews = false}: ViewsProps) {
const [views, setViews] = useState(0) const {data} = useSWR(`/api/views/${slug}`, fetcher) as { data: { views: number } }
const {mutate} = useSWRConfig()
useEffect(() => { useEffect(() => {
// subscribe to view updates at the row level if (shouldUpdateViews) {
const sub = supabase // subscribe to analytics table and react to updates at row level
.channel('any') const sub = supabase
.on('postgres_changes', { .channel('any')
event: 'UPDATE', .on('postgres_changes', {
schema: 'public', event: 'UPDATE',
table: 'analytics', schema: 'public',
filter: `slug=eq.${slug}` table: 'analytics',
}, payload => { filter: `slug=eq.${slug}`
setViews(payload.new.views) }, () => {
}) mutate(`/api/views/${slug}`)
.subscribe() })
.subscribe();
return () => { return () => {
sub.unsubscribe() sub.unsubscribe()
}
} }
}, []) }, [])
useEffect(() => {
const getViews = async () => {
const {views} = await fetcher(`${NEXT_PUBLIC_SITE_URL}/api/views/${slug}`)
setViews(views)
};
getViews()
}, [])
useEffect(() => { useEffect(() => {
if (shouldUpdateViews) { if (shouldUpdateViews) {
const registerView = async () => { const registerView = async () => {
const {views} = await fetcher(`${NEXT_PUBLIC_SITE_URL}/api/views/${slug}`, await fetcher(`/api/views/${slug}`,
{ {
method: 'POST' method: 'POST'
} }
@ -60,7 +52,7 @@ export function Views({as: Component = 'span', slug, className, shouldUpdateView
return ( return (
<Component className={className}> <Component className={className}>
{` · ${views > 0 ? numberFormat(views) : '—'} views`} {` · ${data?.views > 0 ? numberFormat(data.views) : '—'} views`}
</Component> </Component>
) )
} }