feat(cv): redesign document editing with revision-safe letters and writing tools
This commit is contained in:
@@ -18,7 +18,7 @@ type Props = CvAiCallbacks & {
|
||||
targetId: string;
|
||||
};
|
||||
|
||||
const SECTION_ACTIONS = new Set(["improve", "professional", "shorten", "grammar", "impact", "bullets"]);
|
||||
const SECTION_ACTIONS = new Set(["improve", "suggest", "professional", "shorten", "grammar", "impact", "bullets"]);
|
||||
|
||||
export default function AiSectionAssistant({ sectionName, text, context, documentLanguage, targetId, onGenerate, onAccept }: Props) {
|
||||
const { t } = useI18n();
|
||||
@@ -42,7 +42,7 @@ export default function AiSectionAssistant({ sectionName, text, context, documen
|
||||
setBusy(false);
|
||||
setApplying(false);
|
||||
return () => { requestId.current += 1; };
|
||||
}, [text, targetId, normalizedLanguage, canUseAi]);
|
||||
}, [text, targetId, normalizedLanguage, targetLanguage, canUseAi]);
|
||||
|
||||
const discard = () => {
|
||||
requestId.current += 1;
|
||||
@@ -52,13 +52,13 @@ export default function AiSectionAssistant({ sectionName, text, context, documen
|
||||
setApplying(false);
|
||||
};
|
||||
|
||||
const run = async () => {
|
||||
const run = async (requestedAction = action) => {
|
||||
if (!text.trim() || !canUseAi || busy) return;
|
||||
const request = ++requestId.current;
|
||||
setBusy(true);
|
||||
try {
|
||||
const response = await onGenerate({
|
||||
action,
|
||||
action: requestedAction,
|
||||
text,
|
||||
targetId,
|
||||
language: targetLanguage,
|
||||
@@ -94,9 +94,17 @@ export default function AiSectionAssistant({ sectionName, text, context, documen
|
||||
|
||||
if (!open) {
|
||||
return (
|
||||
<Stack direction="row" gap={0.5} flexWrap="wrap" aria-label={t("cvAiSuggestions")}>
|
||||
{(["improve", "suggest", "grammar", "shorten"] as const).map(key => (
|
||||
<Button key={key} size="small" disabled={!canUseAi || (key !== "suggest" && !text.trim())}
|
||||
onClick={() => { setAction(key); setOpen(true); void run(key); }}>
|
||||
{key === "suggest" ? t("cvAiSuggestContent") : key === "grammar" ? t("cvAiGrammarCheck") : key === "shorten" ? t("cvAiShorter") : t("cvAiImprove")}
|
||||
</Button>
|
||||
))}
|
||||
<Button size="small" variant="outlined" startIcon={<AutoFixHighIcon />} disabled={!text.trim()} onClick={() => setOpen(true)}>
|
||||
{t("cvAiSuggestions")}
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -114,6 +122,7 @@ export default function AiSectionAssistant({ sectionName, text, context, documen
|
||||
return (
|
||||
<Paper variant="outlined" sx={{ p: 1.25, borderColor: "primary.main", bgcolor: "action.hover" }}>
|
||||
<Stack spacing={1}>
|
||||
{!text.trim() && <Alert severity="info">{t("cvAiNeedSource")}</Alert>}
|
||||
<Stack direction={{ xs: "column", sm: "row" }} spacing={1} alignItems={{ sm: "center" }}>
|
||||
<TextField select size="small" disabled={busy} label={t("cvAiAction")} value={action} onChange={(event) => setAction(event.target.value)} sx={{ minWidth: 190 }}>
|
||||
{AI_ACTIONS.filter((item) => SECTION_ACTIONS.has(item.key)).map((item) => <MenuItem key={item.key} value={item.key}>{actionLabel(item.key, item.label, t)}</MenuItem>)}
|
||||
@@ -146,6 +155,7 @@ type Translate = ReturnType<typeof useI18n>["t"];
|
||||
|
||||
function actionLabel(key: string, fallback: string, t: Translate) {
|
||||
const labels: Record<string, string> = {
|
||||
suggest: t("cvAiSuggestContent"),
|
||||
improve: t("cvAiImprove"), professional: t("cvAiProfessional"), shorten: t("cvAiShorten"),
|
||||
grammar: t("cvAiGrammar"), impact: t("cvAiImpact"), bullets: t("cvAiBullets"),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user