import React, { useEffect, useId, useRef, useState } from "react"; import { Alert, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Skeleton, Stack, Typography } from "@mui/material"; import { cvBuilderApi, CvRender, CvTheme, getCvPageMetrics, getCvPreviewFitZoom } from "../../cvBuilder"; import { useI18n } from "../../i18n/I18nProvider"; import { getCvTemplateLabels } from "../CvTemplateGallery"; type Props = { theme: CvTheme; onClose: () => void; onApply: (theme: CvTheme) => void }; export default function CvTemplatePreviewDialog({ theme, onClose, onApply }: Props) { const { t, language } = useI18n(); const labels = getCvTemplateLabels(theme, language, t); const id = useId(); const host = useRef(null); const [sample, setSample] = useState(null); const [failed, setFailed] = useState(false); const [attempt, setAttempt] = useState(0); const [zoom, setZoom] = useState(0.5); const metrics = getCvPageMetrics("a4"); const locked = theme.available === false; const currentSample = sample?.themeId === theme.id ? sample : null; useEffect(() => { let alive = true; setSample(null); setFailed(false); if (!locked) cvBuilderApi.themePreview(theme.id).then(render => { if (alive) setSample(render); }).catch(() => { if (alive) setFailed(true); }); return () => { alive = false; }; }, [theme.id, locked, attempt]); useEffect(() => { const element = host.current; if (!element) return; const fit = () => setZoom(getCvPreviewFitZoom(element.clientWidth, metrics.widthPx, 16, 0.2)); fit(); const observer = new ResizeObserver(fit); observer.observe(element); return () => observer.disconnect(); }, [metrics.widthPx, currentSample]); return {t("cvEditorPreviewDesign")} ยท {labels.name} {t("cvEditorTemplateSampleHelp")} {labels.description} {t("cvEditorTemplateApplyHelp")} {locked ? {t("cvEditorPro")} : failed ? setAttempt(value => value + 1)}>{t("cvEditorRetryPreview")}}>{t("cvEditorTemplatePreviewFailed")} : null} {currentSample ?