// modal.jsx — inquiry form (2 steps: 入力 → 確認 → 完了) function ConsultModal({ isOpen, onClose, initialTheme }) { const [step, setStep] = React.useState(0); const [submitting, setSubmitting] = React.useState(false); const [submitError, setSubmitError] = React.useState(''); const openedAtRef = React.useRef(0); const [data, setData] = React.useState({ theme: '', company: '', name: '', email: '', role: '', phone: '', detail: '' }); React.useEffect(() => { if (isOpen) { setStep(0); setSubmitting(false); setSubmitError(''); openedAtRef.current = Date.now(); // ボット対策(時間トラップ)の基準時刻 setData(d => ({ ...d, theme: initialTheme || '' })); } }, [isOpen, initialTheme]); React.useEffect(() => { if (isOpen) document.body.style.overflow = 'hidden'; else document.body.style.overflow = ''; return () => { document.body.style.overflow = ''; }; }, [isOpen]); const update = (k, v) => setData(d => ({ ...d, [k]: v })); const steps = ['お客様情報', '確認']; const SUCCESS = steps.length; // 2 const themeMap = { ai: { ttl: 'DX / AX 推進' }, sec: { ttl: '情報セキュリティ' }, bcp: { ttl: 'BCP対策' }, other: { ttl: '横断 / その他' } }; const themeLabel = themeMap[data.theme] ? themeMap[data.theme].ttl : ''; const canNext = (step === 0 && data.company && data.name && data.email && data.detail) || step >= 1; // 当社サーバーの contact.php 経由で info@skyidea.co.jp へ送信。 // 同一ドメインのため CORS の問題がなく、送信結果(JSON)を確実に判定できる。 const submit = async () => { if (submitting) return; setSubmitting(true); setSubmitError(''); try { const fd = new FormData(); fd.append('company', data.company); fd.append('role', data.role); fd.append('name', data.name); fd.append('email', data.email); fd.append('phone', data.phone); fd.append('detail', data.detail); if (themeLabel) fd.append('theme', themeLabel); fd.append('_gotcha', ''); // ハニーポット(人間は空のまま) // フォーム表示から送信までの経過ミリ秒(極端に速い=ボットの判定に使用) fd.append('_elapsed', String(Date.now() - (openedAtRef.current || Date.now()))); const res = await fetch('contact.php', { method: 'POST', body: fd }); const json = await res.json().catch(() => null); if (res.ok && json && json.success) { setStep(SUCCESS); } else { throw new Error((json && json.message) || ('サーバー応答エラー (HTTP ' + res.status + ')')); } } catch (e) { const detail = (e && e.message && e.message !== 'Failed to fetch') ? '(詳細:' + e.message + ')' : ''; setSubmitError('送信に失敗しました。' + detail + ' お手数ですが info@skyidea.co.jp 宛に直接メールでご連絡ください。'); } finally { setSubmitting(false); } }; return (
お問い合わせありがとうございます。
1営業日以内に、ご担当より {data.email} 宛にご連絡いたします。