diff --git a/landing/app/components/sections/contact.tsx b/landing/app/components/sections/contact.tsx
index 5b4e377..c8579df 100644
--- a/landing/app/components/sections/contact.tsx
+++ b/landing/app/components/sections/contact.tsx
@@ -175,9 +175,9 @@ export function Contact() {
- 도입 문의 신청이 접수되었습니다
+ 메일 앱에서 문의 내용을 전송해 주세요
- {formData.contactName} 님께 영업일 기준 하루 안에 연락드리겠습니다.
+ 도입 문의 메일 작성 창을 열었습니다. 내용을 확인하고 전송해 주시면, {formData.contactName} 님께 영업일 기준 하루 안에 연락드리겠습니다.
- 데모 신청이 접수되었습니다
+ 메일 앱에서 요청을 전송해 주세요
- {/* 폼에서 "Demo를 보내드립니다"라고 약속했으므로 성공 화면도 같은 약속을 지킨다.
- 여기서 "일정을 잡아 연락드립니다"로 새면 방문자가 무엇을 기다려야 하는지 모른다. */}
- 입력하신 이메일로 사용해보실 수 있는 Demo를 보내드립니다.
+ 데모 요청 메일 작성 창을 열었습니다. 전송해 주시면 입력하신 이메일로 사용해보실 수 있는 Demo를 보내드립니다.
) : (
diff --git a/landing/app/lib/lead.ts b/landing/app/lib/lead.ts
index c2b89ae..a992b93 100644
--- a/landing/app/lib/lead.ts
+++ b/landing/app/lib/lead.ts
@@ -1,16 +1,13 @@
/*
* 리드 전송 — 데모 요청 모달과 상담 신청 폼이 함께 쓴다.
*
- * 목적지는 같은 오리진의 서버리스 함수(api/lead.ts)다. 랜딩은 ssr:false 정적 빌드지만
- * Vercel 의 /api 디렉터리 함수는 별개로 배포되므로 서버 없이도 POST 를 받을 수 있다.
- * 같은 오리진이라 엔드포인트 환경변수도, CORS 도 필요 없다.
- *
- * 성공을 위조하지 않는다. 예전 상담 신청 폼은 1.2초 뒤 성공 화면만 띄우고 아무 데도
- * 보내지 않았다 — 화면은 "접수되었습니다"인데 영업이 받을 리드는 없었다.
- * 여기서는 서버가 리드를 확보했을 때만 ok 를 돌려준다.
+ * [임시] 백엔드/서버리스 연결 전까지는 mailto 로 방문자의 메일 앱을 열어 문의를 보내게 한다.
+ * 메일 앱이 '열릴' 뿐 실제 전송 여부는 알 수 없으므로, UI 도 "접수 완료"가 아니라
+ * "메일 앱을 열었습니다 — 전송해 주세요"로 정직하게 안내한다(fake success 금지). 나중에 API/시트로 교체.
*/
-const ENDPOINT = "/api/lead"
+// 리드 수신 주소 — 임시. 실제 영업 주소로 바꾸고, 이후 API 붙이면 mailto 자체를 교체할 것.
+const LEAD_EMAIL = "o2odev@o2o.kr"
export type LeadSource = "demo-request" | "contact"
@@ -36,15 +33,26 @@ export function isEmailLike(value: string) {
export async function submitLead(lead: Lead): Promise {
if (!lead.name.trim() || !isEmailLike(lead.email)) return { ok: false, reason: "invalid" }
- try {
- const res = await fetch(ENDPOINT, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(lead),
- })
- return res.ok ? { ok: true } : { ok: false, reason: "rejected" }
- } catch {
- // 로컬 dev(react-router dev)에는 /api 가 없어서 여기로 온다. 확인은 `vercel dev` 로.
- return { ok: false, reason: "network" }
+ const label = lead.source === "demo-request" ? "데모 요청" : "도입 문의"
+ const body = [
+ `[${label}]`,
+ `회사명: ${lead.company || "-"}`,
+ `담당자: ${lead.name}`,
+ `이메일: ${lead.email}`,
+ `연락처: ${lead.phone || "-"}`,
+ `내용: ${lead.message || "-"}`,
+ ].join("\n")
+ const href = `mailto:${LEAD_EMAIL}?subject=${encodeURIComponent(`[${label}] ${lead.company || lead.name}`)}&body=${encodeURIComponent(body)}`
+
+ // 방문자의 메일 앱을 연다 — 앵커 클릭이 location.href 할당보다 핸들러 발동이 확실하다.
+ // 실제 전송은 방문자가 하므로 성공을 단정하지 않는다(호출부 UI 는 안내 문구).
+ if (typeof document !== "undefined") {
+ const a = document.createElement("a")
+ a.href = href
+ a.style.display = "none"
+ document.body.appendChild(a)
+ a.click()
+ a.remove()
}
+ return { ok: true }
}
diff --git a/landing/public/gifs/negotiation.gif b/landing/public/gifs/negotiation.gif
index 28fbb20..e48d445 100644
Binary files a/landing/public/gifs/negotiation.gif and b/landing/public/gifs/negotiation.gif differ
diff --git a/landing/public/gifs/negotiation.jpg b/landing/public/gifs/negotiation.jpg
new file mode 100644
index 0000000..9e6d295
Binary files /dev/null and b/landing/public/gifs/negotiation.jpg differ
diff --git a/landing/public/gifs/negotiation.mp4 b/landing/public/gifs/negotiation.mp4
index a42482d..d7d40bc 100644
Binary files a/landing/public/gifs/negotiation.mp4 and b/landing/public/gifs/negotiation.mp4 differ
diff --git a/landing/public/gifs/negotiation_result.gif b/landing/public/gifs/negotiation_result.gif
index 985e950..f4ae101 100644
Binary files a/landing/public/gifs/negotiation_result.gif and b/landing/public/gifs/negotiation_result.gif differ
diff --git a/landing/public/gifs/negotiation_result.jpg b/landing/public/gifs/negotiation_result.jpg
index 885727f..dc6aba6 100644
Binary files a/landing/public/gifs/negotiation_result.jpg and b/landing/public/gifs/negotiation_result.jpg differ
diff --git a/landing/public/gifs/negotiation_result.mp4 b/landing/public/gifs/negotiation_result.mp4
index 543a602..797f66d 100644
Binary files a/landing/public/gifs/negotiation_result.mp4 and b/landing/public/gifs/negotiation_result.mp4 differ
diff --git a/landing/public/gifs/quote_generation.gif b/landing/public/gifs/quote_generation.gif
index 646b6e2..77c30d3 100644
Binary files a/landing/public/gifs/quote_generation.gif and b/landing/public/gifs/quote_generation.gif differ
diff --git a/landing/public/gifs/quote_generation.jpg b/landing/public/gifs/quote_generation.jpg
index 79d1cfc..98c7e45 100644
Binary files a/landing/public/gifs/quote_generation.jpg and b/landing/public/gifs/quote_generation.jpg differ
diff --git a/landing/public/gifs/quote_generation.mp4 b/landing/public/gifs/quote_generation.mp4
index 3e82e61..feba69e 100644
Binary files a/landing/public/gifs/quote_generation.mp4 and b/landing/public/gifs/quote_generation.mp4 differ