feat(lesson-preparation): v3 锚点失效提示 banner

This commit is contained in:
SpecialX
2026-07-04 11:41:24 +08:00
parent 6dd3b1fecd
commit e29f30d278

View File

@@ -0,0 +1,73 @@
"use client";
import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { useLessonPlanEditor } from "../hooks/use-lesson-plan-editor";
/**
* V4v3 锚点失效提示 banner。
* 当文档含旧锚点invalid: true 或含 start/end 字段)且未 dismiss 时显示。
* dismiss 状态记录到 localStorage按 planId
*/
export function AnchorMigrationBanner() {
const t = useTranslations("lessonPreparation");
const doc = useLessonPlanEditor((s) => s.doc);
const planId = useLessonPlanEditor((s) => s.planId);
const [dismissed, setDismissed] = useState(false);
useEffect(() => {
if (planId) {
const stored = localStorage.getItem(`lp-legacy-anchor-dismissed-${planId}`);
setDismissed(stored === "true");
} else {
setDismissed(false);
}
}, [planId]);
// 检测是否有旧锚点invalid: true 或含 start/end 字段)
const hasLegacyAnchors = doc.anchors.some(
(a) => a.invalid === true || a.start !== undefined,
);
if (!hasLegacyAnchors || dismissed) return null;
const onDismiss = () => {
setDismissed(true);
if (planId) {
localStorage.setItem(`lp-legacy-anchor-dismissed-${planId}`, "true");
}
};
return (
<div
style={{
background: "#fef3c7",
borderBottom: "1px solid #fcd34d",
padding: "8px 20px",
display: "flex",
alignItems: "center",
gap: 12,
fontSize: 12.5,
color: "#92400e",
}}
>
<strong style={{ fontWeight: 600 }}>{t("v4.migration.legacyAnchorTitle")}</strong>
<span style={{ flex: 1 }}>{t("v4.migration.legacyAnchorBody")}</span>
<button
type="button"
onClick={onDismiss}
style={{
background: "transparent",
border: "1px solid #fcd34d",
borderRadius: 3,
padding: "3px 10px",
fontSize: 11,
color: "#92400e",
cursor: "pointer",
}}
>
{t("v4.migration.legacyAnchorDismiss")}
</button>
</div>
);
}