diff --git a/src/components/Events.tsx b/src/components/Events.tsx index b47043bf..4ca0057c 100644 --- a/src/components/Events.tsx +++ b/src/components/Events.tsx @@ -1,14 +1,15 @@ -import { useContext, useEffect, useState } from "react"; +import { useContext, useEffect, useRef, useState } from "react"; import { Dialog, DialogContent, DialogActions } from "@mui/material"; import { hasMeaningfulDescription, primaryEventLink, type EventItem } from "../store/eventsClient"; import { displayTitle, getUpcomingEvents, groupIntoSections, + isEventPast, type EventSection, type UpcomingEvent, } from "../utils/eventSections"; -import { copyAnchorLink } from "../utils/copyAnchorLink"; +import { copyAnchorLink, copyEventLink } from "../utils/copyAnchorLink"; import { formatSpeakerList, getDescriptionExcerpt, @@ -22,6 +23,7 @@ import { ChevronDown, CloseIcon, EventModalContext, + ShareIcon, useCarouselScroll, useEventDate, type SelectedEvent, @@ -171,6 +173,14 @@ function EventDetailsDialogBody({ } = useEventDate(event); const { link: infoLink, label: infoLabel } = primaryEventLink(event, isPast); const title = displayTitle(event); + const [copied, setCopied] = useState(false); + + const handleCopyLink = async () => { + const ok = await copyEventLink(event.id); + if (!ok) return; + setCopied(true); + window.setTimeout(() => setCopied(false), COPIED_FEEDBACK_MS); + }; // MUI Dialog is kept for its focus trap, escape handling, and scroll lock; // everything inside the paper is plain markup. @@ -194,6 +204,24 @@ function EventDetailsDialogBody({ alt={title} className="max-h-[70vh] w-auto max-w-full object-contain" /> + + + {copied && ( + + Copied! + + )} + + {copied && ( + + Copied! + + )} +