mirror of
https://github.com/r-freeman/portfolio.git
synced 2024-11-22 19:45:40 +00:00
Refactored views component
This commit is contained in:
parent
d5c320c88a
commit
126b66ac09
@ -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,13 +11,13 @@ 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) {
|
||||||
|
// subscribe to analytics table and react to updates at row level
|
||||||
const sub = supabase
|
const sub = supabase
|
||||||
.channel('any')
|
.channel('any')
|
||||||
.on('postgres_changes', {
|
.on('postgres_changes', {
|
||||||
@ -24,30 +25,21 @@ export function Views({as: Component = 'span', slug, className, shouldUpdateView
|
|||||||
schema: 'public',
|
schema: 'public',
|
||||||
table: 'analytics',
|
table: 'analytics',
|
||||||
filter: `slug=eq.${slug}`
|
filter: `slug=eq.${slug}`
|
||||||
}, payload => {
|
}, () => {
|
||||||
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>
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user