/* * 데모 요청 리드 전송. * * 기존 문의 폼(contact.tsx)은 1.2초 뒤 성공 화면만 띄우고 아무 데도 보내지 않는다. * 리드 제너레이션에서 그 방식은 최악이다 — 화면은 "접수되었습니다"라고 하는데 * 영업이 받을 리드는 존재하지 않고, 아무도 그 사실을 모른다. * * 그래서 여기서는 성공을 위조하지 않는다. 엔드포인트가 없으면 없다고 돌려주고, * 호출부는 그걸 실패로 처리해 방문자에게 다른 경로(상담 신청)를 안내한다. * * 엔드포인트는 VITE_LEAD_ENDPOINT 로 주입한다. 랜딩은 ssr:false 정적 빌드라 * 서버 라우트가 없으므로, 폼 백엔드(Formspree 류)나 Vercel 서버리스 함수 URL 을 넣는다. */ export type LeadResult = { ok: true } | { ok: false; reason: "not-configured" | "network" | "rejected" } export type Lead = { name: string; email: string } /** 아주 느슨한 형식 검사. 정규식으로 이메일을 엄밀히 검증하려는 시도는 늘 진짜 주소를 막는다. */ export function isEmailLike(value: string) { const v = value.trim() return v.length >= 5 && v.includes("@") && !v.startsWith("@") && !v.endsWith("@") && !/\s/.test(v) } export async function submitLead(lead: Lead): Promise { const endpoint = import.meta.env.VITE_LEAD_ENDPOINT as string | undefined if (!endpoint) { console.warn( "[lead] VITE_LEAD_ENDPOINT 가 설정되지 않아 데모 요청이 저장되지 않습니다. " + "폼 백엔드 URL 을 환경변수로 넣어주세요.", ) return { ok: false, reason: "not-configured" } } try { const res = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ name: lead.name.trim(), email: lead.email.trim(), // 어느 CTA 에서 들어온 리드인지 남긴다. 유입 경로별 전환율을 나중에 못 재면 개선할 수 없다. source: "landing:demo-request", submittedAt: new Date().toISOString(), }), }) return res.ok ? { ok: true } : { ok: false, reason: "rejected" } } catch { return { ok: false, reason: "network" } } }