/
Item.tsx
72 lines (65 loc) · 2.13 KB
/
Item.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'use client'
import useOnScreen from './useOnScreen'
import { useEffect, useRef } from 'react'
import { useRouter } from 'next/navigation'
import { prefetch } from '@edgio/prefetch/window'
const fallbackImage =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAACmCAMAAADAp3D7AAAAA1BMVEWAgICQdD0xAAAAK0lEQVR4nO3BMQEAAADCoPVP7W8GoAAAAAAAAAAAAAAAAAAAAAAAAAAAeANRtAABpXaWUQAAAABJRU5ErkJggg=='
interface TVMazeProps {
name?: string
id?: string | number
image?: { medium?: string; original?: string }
}
interface TMDBProps {
title?: string
id?: string | number
poster_path?: string
original_title?: string
}
interface ItemProps extends TMDBProps, TVMazeProps {}
const Item = (itemProps: ItemProps) => {
const router = useRouter()
const id = itemProps?.id ?? -1
const name = itemProps?.name ?? itemProps?.original_title ?? itemProps?.title ?? 'Placeholder'
const image = itemProps?.image
? itemProps?.image?.medium ?? itemProps?.image?.original
: itemProps?.poster_path
? `/l0-opt?quality=10&img=https://image.tmdb.org/t/p/original${itemProps?.poster_path}`
: fallbackImage
const ref = useRef<HTMLAnchorElement>(null)
const isVisible = useOnScreen(ref)
useEffect(() => {
if (isVisible) {
if (id !== -1) {
prefetch(`/l0-themoviedb-api/movie/${id}`, 'fetch', { includeCacheMisses: true })
prefetch(`/l0-themoviedb-api/movie/${id}/credits`, 'fetch', { includeCacheMisses: true })
}
}
}, [isVisible])
return (
<a
ref={ref}
href={`/show/${id}`}
onClick={(e) => {
e.preventDefault()
router.push(`/show/${id}`)
}}
className="flex flex-col min-w-[150px]"
>
<img
alt={name}
src={image}
width="150px"
height="225px"
loading="lazy"
className={['object-cover object-center min-h-[225px] rounded', image === fallbackImage && 'animate-pulse'].filter((i) => i).join(' ')}
/>
{name ? (
<h3 className="mt-3 max-w-[150px] text-gray-300">{name}</h3>
) : (
<div className="mt-3 w-[150px] h-[20px] bg-white/25 animate-pulse"></div>
)}
</a>
)
}
export default Item