폼전송 기능 수정
This commit is contained in:
@@ -150,6 +150,7 @@ function EditorPageInner() {
|
||||
const [projectMessage, setProjectMessage] = useState("");
|
||||
// 멀티 선택(MVP)을 위한 로컬 선택 상태: 단일 선택(selectedBlockId)과 병행 사용한다.
|
||||
const [selectedBlockIds, setSelectedBlockIds] = useState<string[]>([]);
|
||||
const [initializedNewProjectFromQuery, setInitializedNewProjectFromQuery] = useState(false);
|
||||
|
||||
const historyLength = useEditorStore((state) => (state as any).history?.length ?? 0);
|
||||
const futureLength = useEditorStore((state) => (state as any).future?.length ?? 0);
|
||||
@@ -176,6 +177,75 @@ function EditorPageInner() {
|
||||
}
|
||||
}, [initialSlugFromQuery, projectConfig?.slug, updateProjectConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams) return;
|
||||
|
||||
if (initializedNewProjectFromQuery) return;
|
||||
|
||||
const newParam = searchParams.get("new");
|
||||
if (newParam !== "1") return;
|
||||
|
||||
if (blocks.length > 0) {
|
||||
replaceBlocks([]);
|
||||
}
|
||||
|
||||
updateProjectConfig({
|
||||
title: "새 페이지",
|
||||
slug: "my-landing",
|
||||
canvasPreset: "full",
|
||||
canvasBgColorHex: "#020617",
|
||||
bodyBgColorHex: "#020617",
|
||||
headHtml: "",
|
||||
trackingScript: "",
|
||||
seoTitle: "",
|
||||
seoDescription: "",
|
||||
seoOgImageUrl: "",
|
||||
seoCanonicalUrl: "",
|
||||
seoNoIndex: false,
|
||||
} as ProjectConfig);
|
||||
|
||||
resetHistory();
|
||||
setInitializedNewProjectFromQuery(true);
|
||||
}, [searchParams, initializedNewProjectFromQuery, blocks.length, replaceBlocks, updateProjectConfig, resetHistory]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!searchParams) return;
|
||||
|
||||
const slugParam = searchParams.get("slug");
|
||||
if (slugParam && slugParam.trim().length > 0) {
|
||||
// URL 에 slug 쿼리 파라미터가 있으면 기존 프로젝트 편집 중이므로,
|
||||
// 자동 슬러그 생성은 동작시키지 않는다.
|
||||
return;
|
||||
}
|
||||
|
||||
const currentSlugRaw = projectConfig?.slug;
|
||||
const currentSlug = typeof currentSlugRaw === "string" ? currentSlugRaw.trim() : "";
|
||||
|
||||
// 초기 상태("my-landing") 또는 비어 있는 경우에만 자동 슬러그를 한 번 생성한다.
|
||||
if (currentSlug && currentSlug !== "my-landing") {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const datePart = [
|
||||
now.getFullYear().toString().padStart(4, "0"),
|
||||
(now.getMonth() + 1).toString().padStart(2, "0"),
|
||||
now.getDate().toString().padStart(2, "0"),
|
||||
].join("");
|
||||
|
||||
const timePart = [
|
||||
now.getHours().toString().padStart(2, "0"),
|
||||
now.getMinutes().toString().padStart(2, "0"),
|
||||
now.getSeconds().toString().padStart(2, "0"),
|
||||
].join("");
|
||||
|
||||
const randomPart = Math.random().toString(36).slice(2, 6);
|
||||
|
||||
const generatedSlug = `page-${datePart}-${timePart}-${randomPart}`;
|
||||
|
||||
updateProjectConfig({ slug: generatedSlug });
|
||||
}, [searchParams, projectConfig?.slug, updateProjectConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!authChecked) return;
|
||||
if (!initialSlugFromQuery) return;
|
||||
@@ -817,6 +887,51 @@ function EditorPageInner() {
|
||||
}
|
||||
}, [blocks, projectConfig, authUserId, authChecked]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!authChecked) return;
|
||||
if (!authUserId) return;
|
||||
if (typeof window === "undefined") return;
|
||||
|
||||
const slugRaw = projectConfig?.slug;
|
||||
const slug = typeof slugRaw === "string" ? slugRaw.trim() : "";
|
||||
if (!slug || slug === "my-landing") return;
|
||||
|
||||
const titleRaw = projectConfig?.title;
|
||||
const title = (typeof titleRaw === "string" ? titleRaw.trim() : "") || "제목 없음";
|
||||
|
||||
const intervalMs = 20000;
|
||||
let cancelled = false;
|
||||
|
||||
const saveOnce = async () => {
|
||||
if (cancelled) return;
|
||||
|
||||
try {
|
||||
await fetch("/api/projects", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
title,
|
||||
slug,
|
||||
contentJson: blocks,
|
||||
}),
|
||||
});
|
||||
} catch {
|
||||
// 서버 자동 저장 실패는 치명적이지 않으므로 조용히 무시한다.
|
||||
}
|
||||
};
|
||||
|
||||
const id = window.setInterval(() => {
|
||||
void saveOnce();
|
||||
}, intervalMs);
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
window.clearInterval(id);
|
||||
};
|
||||
}, [authChecked, authUserId, projectConfig?.slug, projectConfig?.title, blocks]);
|
||||
|
||||
// 에디터 전역에서 Undo/Redo 단축키(Cmd/Ctrl+Z, Cmd/Ctrl+Shift+Z),
|
||||
// Delete/Backspace 기반 삭제, Cmd/Ctrl+D 기반 복제,
|
||||
// ArrowUp/ArrowDown을 이용한 선택 블록 이동을 처리한다.
|
||||
|
||||
Reference in New Issue
Block a user