import { useRouter } from "next/router"; import { t } from "@lingui/core/macro"; import { useEffect, useRef, useState } from "react"; import { HiLink, HiXMark } from "react-icons/hi2"; import Badge from "~/components/Badge"; import Editor from "~/components/Editor"; import LabelIcon from "~/components/LabelIcon"; import { useModal } from "~/providers/modal"; import { usePopup } from "~/providers/popup"; import { api } from "~/utils/api"; import ActivityList from "~/views/card/components/ActivityList"; import { AttachmentThumbnails } from "~/views/card/components/AttachmentThumbnails"; import Checklists from "~/views/card/components/Checklists"; export function CardModal({ cardPublicId, workspaceSlug, boardSlug, }: { cardPublicId: string | null | undefined; workspaceSlug: string | null | undefined; boardSlug: string | null | undefined; }) { const router = useRouter(); const { closeModal, isOpen } = useModal(); const { showPopup } = usePopup(); const [showFade, setShowFade] = useState(false); const [showTopFade, setShowTopFade] = useState(false); const scrollRef = useRef(null); const handleCopyCardLink = async () => { try { await navigator.clipboard.writeText(window.location.href); showPopup({ header: t`Link copied`, icon: "success", message: t`Card URL copied to clipboard`, }); } catch (error) { console.error(error); showPopup({ header: t`Unable to copy link`, icon: "error", message: t`Please try again.`, }); } }; const { data, isLoading, error } = api.card.byId.useQuery( { cardPublicId: cardPublicId ?? "", }, { enabled: isOpen && !!cardPublicId && cardPublicId.length >= 12, }, ); // Redirect to 404 if card doesn't exist useEffect(() => { if (isOpen && cardPublicId && !isLoading) { if (error?.data?.code === "NOT_FOUND" || (!data && !isLoading && error)) { // Close modal first, then redirect closeModal(); router.replace("/404"); } } }, [isOpen, cardPublicId, isLoading, error, data, closeModal, router]); const labels = data?.labels ?? []; const handleScroll = () => { if (!scrollRef.current) return; const { scrollTop, scrollHeight, clientHeight } = scrollRef.current; const isAtBottom = scrollTop + clientHeight >= scrollHeight - 5; const isAtTop = scrollTop <= 5; setShowFade(!isAtBottom); setShowTopFade(!isAtTop); }; useEffect(() => { const scrollElement = scrollRef.current; if (!scrollElement) return; handleScroll(); scrollElement.addEventListener("scroll", handleScroll); return () => scrollElement.removeEventListener("scroll", handleScroll); }, [data]); return (
{isLoading ? (
) : ( <>

{data?.title}

)}
{labels.length > 0 && (
{labels.map((label) => ( } /> ))}
)}
{data?.description && (
)} {data?.attachments && data.attachments.length > 0 && cardPublicId && (
)} {data?.checklists && data.checklists.length > 0 && ( )}

{t`Activity`}

{cardPublicId && ( )}
{showTopFade && (
)} {showFade && (
)}
); }