feat(cv): redesign document editing with revision-safe letters and writing tools

This commit is contained in:
cesnimda
2026-10-25 22:44:14 +01:00
parent 01e10996c5
commit 2bfaf6c14b
57 changed files with 2859 additions and 118 deletions
@@ -28,6 +28,11 @@ const templateLabels = new Map<string, [TranslationKey, TranslationKey, Translat
["code", ["cvTemplateCodeName", "cvTemplateCategoryTechnical", "cvTemplateCodeDescription"]],
]);
export function getCvTemplateLabels(theme: CvTheme, language: string, t: (key: TranslationKey) => string) {
const labels = language === "nb" ? templateLabels.get(theme.id) : undefined;
return { name: labels ? t(labels[0]) : theme.name, category: labels ? t(labels[1]) : theme.category, description: labels ? t(labels[2]) : theme.description };
}
export default function CvTemplateGallery({ themes, selectedId, onSelect, previewHeight = 170, showDescriptions = true, disabled = false }: Props) {
const { t, language } = useI18n();
const id = useId();
@@ -46,8 +51,7 @@ export default function CvTemplateGallery({ themes, selectedId, onSelect, previe
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;
const { name, category, description } = getCvTemplateLabels(theme, language, t);
return (
<Paper key={theme.id} variant="outlined" role="button" tabIndex={unavailable ? -1 : 0} aria-label={name} aria-describedby={`${id}-${theme.id}-category ${showDescriptions ? `${id}-${theme.id}-description ` : ""}${id}-${theme.id}-features`} aria-disabled={unavailable} aria-pressed={active}
onClick={() => { if (!unavailable) onSelect(theme); }}
@@ -56,8 +60,8 @@ export default function CvTemplateGallery({ themes, selectedId, onSelect, previe
{active && <CheckCircleIcon aria-label={t("cvEditorSelectedTemplate")} color="primary" sx={{ position: "absolute", zIndex: 2, top: 6, right: 6, bgcolor: "background.paper", borderRadius: "50%" }} />}
<Box sx={{ mb: 1 }}><CvTemplateThumbnail theme={theme} height={previewHeight} /></Box>
<Typography variant="body2" sx={{ fontWeight: 750 }}>{name}</Typography>
<Typography id={`${id}-${theme.id}-category`} variant="caption" color="text.secondary" sx={{ display: "block" }}>{labels ? t(labels[1]) : theme.category}</Typography>
{showDescriptions && <Typography id={`${id}-${theme.id}-description`} variant="caption" color="text.secondary" sx={{ display: "block", mt: 0.25, lineHeight: 1.35 }}>{labels ? t(labels[2]) : theme.description}</Typography>}
<Typography id={`${id}-${theme.id}-category`} variant="caption" color="text.secondary" sx={{ display: "block" }}>{category}</Typography>
{showDescriptions && <Typography id={`${id}-${theme.id}-description`} variant="caption" color="text.secondary" sx={{ display: "block", mt: 0.25, lineHeight: 1.35 }}>{description}</Typography>}
<Stack id={`${id}-${theme.id}-features`} direction="row" spacing={0.5} alignItems="center" flexWrap="wrap" useFlexGap sx={{ mt: 0.75 }}>
{theme.atsFriendly && <Chip size="small" label={t("cvEditorAtsFriendly")} color="success" variant="outlined" sx={{ height: 20, fontSize: 10 }} />}
{theme.requiresPro && <Chip size="small" label={locked ? t("cvEditorPro") : t("cvEditorProUnlocked")} color="secondary" variant="outlined" sx={{ height: 20, fontSize: 10 }} />}