폼전송 기능 수정
CI / test (push) Failing after 4m53s
CI / e2e (push) Has been skipped
CI / pr_and_merge (push) Has been skipped

This commit is contained in:
2025-12-07 19:11:06 +09:00
parent 96fa34cd86
commit 243083261f
27 changed files with 1025 additions and 5 deletions
@@ -0,0 +1,114 @@
"use client";
import { useEffect, useState } from "react";
interface PublicProjectPageClientProps {
html: string;
}
export default function PublicProjectPageClient({ html }: PublicProjectPageClientProps) {
const [toastMessage, setToastMessage] = useState<string | null>(null);
useEffect(() => {
if (typeof document === "undefined" || typeof window === "undefined") return;
let toastTimeout: number | null = null;
const showToast = (message: string) => {
setToastMessage(message);
if (toastTimeout !== null) {
window.clearTimeout(toastTimeout);
}
toastTimeout = window.setTimeout(() => {
setToastMessage(null);
}, 4000);
};
const forms = document.querySelectorAll<HTMLFormElement>(
'form.pb-form-controller, form[action="/api/forms/submit"]',
);
if (!forms || forms.length === 0) return;
forms.forEach((form) => {
if (form.dataset.pbInitialized === "1") return;
form.dataset.pbInitialized = "1";
form.addEventListener("submit", (event) => {
if (!form) return;
if (event && typeof event.preventDefault === "function") {
event.preventDefault();
}
const formData = new FormData(form);
const configInput = form.querySelector<HTMLInputElement>('input[name="__config"]');
let config: any = null;
if (configInput && configInput.value) {
try {
config = JSON.parse(configInput.value);
} catch {
config = null;
}
}
const action = form.getAttribute("action") || "/api/forms/submit";
fetch(action, { method: "POST", body: formData })
.then((res) => res.json().catch(() => ({})))
.then((data: any) => {
const ok = data && data.ok;
const message = data && data.message;
if (ok) {
const success =
message || (config && config.successMessage) || "성공적으로 전송되었습니다.";
showToast(success);
try {
form.reset();
} catch {}
} else {
const errorMsg =
message || (config && config.errorMessage) || "전송 중 오류가 발생했습니다.";
showToast(errorMsg);
}
})
.catch(() => {
const errorMsg =
(config && config.errorMessage) || "전송 중 오류가 발생했습니다.";
showToast(errorMsg);
});
});
});
return () => {
if (toastTimeout !== null) {
window.clearTimeout(toastTimeout);
}
};
}, []);
return (
<>
<div dangerouslySetInnerHTML={{ __html: html }} />
{toastMessage ? (
<div
style={{
position: "fixed",
right: "16px",
bottom: "16px",
zIndex: 50,
maxWidth: "320px",
padding: "12px 16px",
borderRadius: "8px",
backgroundColor: "rgba(15, 23, 42, 0.95)",
color: "#e5e7eb",
fontSize: "14px",
lineHeight: "1.4",
boxShadow: "0 10px 25px rgba(15, 23, 42, 0.6)",
pointerEvents: "none",
}}
>
{toastMessage}
</div>
) : null}
</>
);
}