|
| 1 | +import { Markdown } from "@/components/Markdown"; |
| 2 | +import { useAnnouncements } from "@/data/announcements/announcements"; |
| 3 | +import { |
| 4 | + Button, |
| 5 | + Dialog, |
| 6 | + DialogContent, |
| 7 | + DialogDescription, |
| 8 | + DialogTitle |
| 9 | +} from "@zenml-io/react-component-library"; |
| 10 | +import { useEffect, useState } from "react"; |
| 11 | +import { AnnouncementImage } from "../announcement-image"; |
| 12 | +import { AnnouncementLabel } from "../announcement-label"; |
| 13 | +import { AnnouncementLinks } from "../announcement-links"; |
| 14 | +import { AnnouncementVideo } from "../announcement-video"; |
| 15 | +import { announcementStore } from "../persist-announcement"; |
| 16 | +import { AnnouncementHighlightPageIndicator } from "./page-indicator"; |
| 17 | +import { useNewAnnouncementHighlights } from "./use-new-highlights"; |
| 18 | + |
| 19 | +export function AnnouncementHighlight() { |
| 20 | + const announcementsQuery = useAnnouncements(); |
| 21 | + const newFeatureHighlights = [...useNewAnnouncementHighlights(announcementsQuery.data)].reverse(); |
| 22 | + const [open, setOpen] = useState(false); |
| 23 | + const [currentPage, setCurrentPage] = useState(0); |
| 24 | + |
| 25 | + useEffect(() => { |
| 26 | + if (newFeatureHighlights.length >= 1) { |
| 27 | + setOpen(true); |
| 28 | + } |
| 29 | + }, [newFeatureHighlights]); |
| 30 | + |
| 31 | + function handleChange(open: boolean) { |
| 32 | + setOpen(open); |
| 33 | + setCurrentPage(0); |
| 34 | + if (!open) { |
| 35 | + announcementStore.setAnnouncementLastSeen("lastSeenHighlights"); |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + function handleNext() { |
| 40 | + const isLast = currentPage === newFeatureHighlights.length - 1; |
| 41 | + if (isLast) { |
| 42 | + handleChange(false); |
| 43 | + } else { |
| 44 | + setCurrentPage((prev) => prev + 1); |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + const highlightedFeatureCount = newFeatureHighlights.length; |
| 49 | + if (highlightedFeatureCount === 0) return null; |
| 50 | + |
| 51 | + const isLastPage = currentPage === highlightedFeatureCount - 1; |
| 52 | + const currentItem = newFeatureHighlights[currentPage]; |
| 53 | + |
| 54 | + return ( |
| 55 | + <Dialog open={open} onOpenChange={handleChange}> |
| 56 | + <DialogContent className="flex max-w-[600px] flex-col overflow-hidden"> |
| 57 | + {currentItem.video_url ? ( |
| 58 | + <AnnouncementVideo videoUrl={currentItem.video_url} /> |
| 59 | + ) : ( |
| 60 | + <AnnouncementImage title={currentItem.title} imageUrl={currentItem.feature_image_url} /> |
| 61 | + )} |
| 62 | + <div className="space-y-5 p-5"> |
| 63 | + <AnnouncementHighlightPageIndicator |
| 64 | + currentPage={currentPage} |
| 65 | + totalPages={highlightedFeatureCount} |
| 66 | + /> |
| 67 | + <div className="space-y-3"> |
| 68 | + <div className="space-y-1"> |
| 69 | + <DialogTitle className="text-display-xs font-semibold"> |
| 70 | + {currentItem.title} |
| 71 | + </DialogTitle> |
| 72 | + <DialogDescription className="sr-only"> |
| 73 | + Announcement Highlight: {currentItem.title} |
| 74 | + </DialogDescription> |
| 75 | + <ul className="flex flex-wrap items-center gap-0.5"> |
| 76 | + {currentItem.labels.map((label, idx) => ( |
| 77 | + <li className="inline-flex" key={idx}> |
| 78 | + <AnnouncementLabel label={label} /> |
| 79 | + </li> |
| 80 | + ))} |
| 81 | + </ul> |
| 82 | + </div> |
| 83 | + <Markdown |
| 84 | + className="prose text-theme-text-secondary" |
| 85 | + markdown={currentItem.description} |
| 86 | + /> |
| 87 | + </div> |
| 88 | + </div> |
| 89 | + <div className="flex items-center justify-end gap-2 p-5"> |
| 90 | + {(currentItem.learn_more_url || currentItem.docs_url) && ( |
| 91 | + <AnnouncementLinks |
| 92 | + docs_url={currentItem.docs_url} |
| 93 | + learn_more_url={currentItem.learn_more_url} |
| 94 | + slug={currentItem.slug} |
| 95 | + size="md" |
| 96 | + /> |
| 97 | + )} |
| 98 | + <Button size="md" onClick={handleNext}> |
| 99 | + {isLastPage ? "Got it" : "Next"} |
| 100 | + </Button> |
| 101 | + </div> |
| 102 | + </DialogContent> |
| 103 | + </Dialog> |
| 104 | + ); |
| 105 | +} |
0 commit comments