import React, { useId, useMemo, useState } from "react"; import CheckCircleIcon from "@mui/icons-material/CheckCircle"; import { Box, Button, Chip, Paper, Stack, Typography } from "@mui/material"; import { CvTheme, getVisibleCvThemes } from "../cvBuilder"; import { useI18n } from "../i18n/I18nProvider"; import type { TranslationKey } from "../i18n/translations"; import CvTemplateThumbnail from "./CvTemplateThumbnail"; type Props = { themes: CvTheme[]; selectedId: string; onSelect: (theme: CvTheme) => void; previewHeight?: number; showDescriptions?: boolean; disabled?: boolean; }; const templateLabels = new Map([ ["modern", ["cvTemplateModernName", "cvTemplateCategoryModern", "cvTemplateModernDescription"]], ["minimal", ["cvTemplateMinimalName", "cvTemplateCategoryMinimal", "cvTemplateMinimalDescription"]], ["executive", ["cvTemplateExecutiveName", "cvTemplateCategoryExecutive", "cvTemplateExecutiveDescription"]], ["technical", ["cvTemplateTechnicalName", "cvTemplateCategoryTechnical", "cvTemplateTechnicalDescription"]], ["ats-classic", ["cvTemplateAtsClassicName", "cvTemplateCategoryAts", "cvTemplateAtsClassicDescription"]], ["nordic", ["cvTemplateNordicName", "cvTemplateCategoryModern", "cvTemplateNordicDescription"]], ["elegant", ["cvTemplateElegantName", "cvTemplateCategoryCreative", "cvTemplateElegantDescription"]], ["creative", ["cvTemplateCreativeName", "cvTemplateCategoryCreative", "cvTemplateCreativeDescription"]], ["code", ["cvTemplateCodeName", "cvTemplateCategoryTechnical", "cvTemplateCodeDescription"]], ]); export default function CvTemplateGallery({ themes, selectedId, onSelect, previewHeight = 170, showDescriptions = true, disabled = false }: Props) { const { t, language } = useI18n(); const id = useId(); const [atsOnly, setAtsOnly] = useState(true); const visibleThemes = useMemo(() => getVisibleCvThemes(themes, atsOnly, selectedId), [atsOnly, selectedId, themes]); return ( {atsOnly && {t("cvEditorAtsTemplateHelp")}} {visibleThemes.map((theme) => { const active = theme.id === selectedId; const locked = theme.available === false; const unavailable = locked || disabled; const labels = language === "nb" ? templateLabels.get(theme.id) : undefined; const name = labels ? t(labels[0]) : theme.name; return ( { if (!unavailable) onSelect(theme); }} onKeyDown={(event) => { if (!unavailable && (event.key === "Enter" || event.key === " ")) { event.preventDefault(); onSelect(theme); } }} sx={{ p: 1, cursor: unavailable ? "not-allowed" : "pointer", position: "relative", minWidth: 0, overflowWrap: "anywhere", borderColor: active ? "primary.main" : "divider", borderWidth: active ? 2 : 1, "&:hover": unavailable ? undefined : { borderColor: "primary.main" } }}> {active && } {name} {labels ? t(labels[1]) : theme.category} {showDescriptions && {labels ? t(labels[2]) : theme.description}} {theme.atsFriendly && } {theme.requiresPro && } {theme.swatches.slice(0, 3).map((colour, index) => )} ); })} ); }