index.tsx104 lines · main
1import { useBreakpoint } from 'common'
2import { Play } from 'lucide-react'
3import Image from 'next/image'
4import React, { ReactNode } from 'react'
5import { Dialog, DialogContent, DialogTrigger } from 'ui'
6
7interface ExpandableVideoProps {
8 videoId: string
9 imgUrl?: string
10 imgOverlayText?: string
11 triggerContainerClassName?: string
12 imgAltText?: string
13 trigger?: ReactNode
14 onOpenCallback?: any
15 priority?: boolean
16}
17
18export function ExpandableVideo({
19 imgUrl,
20 videoId,
21 imgOverlayText,
22 triggerContainerClassName = '',
23 imgAltText,
24 trigger,
25 onOpenCallback,
26 priority = false,
27}: ExpandableVideoProps) {
28 const [expandVideo, setExpandVideo] = React.useState(false)
29 const isMobile = useBreakpoint(768)
30
31 React.useEffect(() => {
32 if (isMobile) setExpandVideo(false)
33 }, [isMobile])
34
35 const CliccablePreview = () => (
36 <div className="video-container overflow-hidden rounded-sm hover:cursor-pointer">
37 <div
38 className="
39 absolute inset-0 z-10
40 text-white
41 flex flex-col gap-3
42 items-center justify-center
43 bg-alternative
44 before:content['']
45 before:absolute
46 before:inset-0
47 before:bg-black
48 before:opacity-30
49 before:-z-10
50 hover:before:opacity-50
51 before:transition-opacity
52 "
53 >
54 <Play strokeWidth={2} className="w-5 h-5" />
55 <p className="text-sm">{imgOverlayText ?? 'Watch video guide'}</p>
56 </div>
57 <Image
58 src={imgUrl ?? '/images/blur.png'}
59 alt={imgAltText ?? 'Video guide preview'}
60 fill
61 sizes="100%"
62 priority={priority}
63 className="absolute inset-0 object-cover blur-xs scale-105"
64 />
65 </div>
66 )
67
68 return (
69 <>
70 <Dialog open={expandVideo} onOpenChange={(open) => setExpandVideo(open)}>
71 <DialogTrigger asChild>
72 <button
73 onClick={() => {
74 if (onOpenCallback) onOpenCallback()
75 setExpandVideo(true)
76 }}
77 className={['w-full', triggerContainerClassName].join(' ').trim()}
78 >
79 {trigger ?? <CliccablePreview />}
80 </button>
81 </DialogTrigger>
82 <DialogContent size="xxlarge">
83 <div className="w-full! flex items-center justify-center">
84 <div className="relative w-full">
85 <button
86 onClick={() => setExpandVideo(false)}
87 className="text-foreground-light hover:text-foreground absolute -top-8 right-0"
88 >
89 <p className="text-xs">Close</p>
90 </button>
91 <div className="video-container rounded-lg! border-none! overflow-hidden!">
92 <iframe
93 src={`https://www.youtube-nocookie.com/embed/${videoId}`}
94 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
95 allowFullScreen
96 />
97 </div>
98 </div>
99 </div>
100 </DialogContent>
101 </Dialog>
102 </>
103 )
104}