"use client"; import { useEffect, useRef, useState, type ReactNode } from "react"; import { AlertTriangle, Code2, Download, ExternalLink, KeyRound, Loader2, } from "lucide-react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { analytics } from "@/lib/analytics"; import { getXuluxTemplateAnalyticsId, trackXuluxDownload, useXuluxAnalytics, withXuluxContext, } from "@/lib/xulux/analytics-context"; import { cn } from "@/lib/utils"; import { XuluxPreviewFrame } from "../canvas/XuluxPreviewFrame"; import type { XuluxTemplate } from "../templates/types"; import { Thumbnail } from "./Thumbnail"; type Props = { template: XuluxTemplate | null; allTemplates: XuluxTemplate[]; onClose: () => void; onSelect: (template: XuluxTemplate) => void; }; export function TemplateDetailModal({ template, allTemplates, onClose, onSelect, }: Props) { const analyticsCtx = useXuluxAnalytics(); const [current, setCurrent] = useState(template); const [iframeLoaded, setIframeLoaded] = useState(false); const scrollRef = useRef(null); useEffect(() => { setCurrent(template); setIframeLoaded(false); }, [template]); const others = allTemplates .filter((candidate) => candidate.id !== current?.id) .slice(0, 4); const handleOther = (nextTemplate: XuluxTemplate) => { if (current) { analytics.xulux.templateSelected( withXuluxContext(analyticsCtx, { template_id: getXuluxTemplateAnalyticsId(current), template_kind: current.kind, surface: "detail_modal", action: "other_template", other_template_id: getXuluxTemplateAnalyticsId(nextTemplate), }), ); } setCurrent(nextTemplate); setIframeLoaded(false); scrollRef.current?.scrollTo({ top: 0, behavior: "smooth" }); }; if (!current) return null; const hasPreview = Boolean(current.previewUrl); const hasDownload = Boolean(current.downloadUrl); const requiredEnv = current.env.filter((item) => item.required); const startLabel = current.kind === "template" ? "Spin up app" : "Use this example"; const previewLabel = current.previewStatus === "live" ? "Hosted preview" : current.previewStatus === "stale" ? "Stale preview" : current.screenshotUrl ? "Screenshot only" : "No preview"; return ( !open && onClose()}> {current.title}
{hasPreview ? ( <> {!iframeLoaded && (
Loading preview...
)}