Announcement.tsx77 lines · main
1'use client'
2
3import { X } from 'lucide-react'
4import { usePathname } from 'next/navigation'
5import { PropsWithChildren, useEffect, useState } from 'react'
6import { cn } from 'ui'
7
8export interface AnnouncementProps {
9 show: boolean
10 text: string
11 launchDate: string
12 link: string
13 badge?: string
14}
15
16interface AnnouncementComponentProps {
17 show?: boolean
18 dismissable?: boolean
19 className?: string
20 announcementKey: `announcement_${string}`
21}
22
23export const Announcement = ({
24 show = true,
25 dismissable = true,
26 className,
27 children,
28 announcementKey,
29}: PropsWithChildren<AnnouncementComponentProps>) => {
30 const [hidden, setHidden] = useState(true)
31
32 const pathname = usePathname()
33 const isLaunchWeekSection = pathname?.includes('launch-week') ?? false
34
35 // override to hide announcement
36 if (!show) return null
37
38 // construct the key for the announcement, based on the title text
39 const announcementKeyNoSpaces = announcementKey.replace(/ /g, '')
40
41 // window.localStorage is kept inside useEffect
42 // to prevent error
43 useEffect(function () {
44 if (window.localStorage.getItem(announcementKeyNoSpaces) === 'hidden') {
45 setHidden(true)
46 }
47
48 if (!window.localStorage.getItem(announcementKeyNoSpaces)) {
49 setHidden(false)
50 }
51 }, [])
52
53 function handleClose(event: any) {
54 event.stopPropagation()
55
56 window.localStorage.setItem(announcementKeyNoSpaces, 'hidden')
57 return setHidden(true)
58 }
59
60 if (!isLaunchWeekSection && hidden) {
61 return null
62 } else {
63 return (
64 <div className={cn('relative z-40 w-full', className)}>
65 {dismissable && !isLaunchWeekSection && (
66 <div
67 className="absolute z-50 right-4 flex h-full items-center opacity-100 text-foreground-contrast dark:text-foreground transition-opacity hover:opacity-80 hover:cursor-pointer"
68 onClick={handleClose}
69 >
70 <X size={16} />
71 </div>
72 )}
73 {children}
74 </div>
75 )
76 }
77}