// Trial booking page — the final CTA destination
function TrialBooking() {
const [step, setStep] = React.useState(1);
const [form, setForm] = React.useState({
service: 'voice',
date: '04.22 TUE',
time: '18:30',
name: '', email: '', phone: '',
experience: 'none',
goal: '',
});
const update = (k, v) => setForm({ ...form, [k]: v });
const services = [
{ id:'voice', label:'ボイストレーニング', en:'VOICE', note:'MAIN · 一番人気' },
{ id:'guitar', label:'弾き語り', en:'GUITAR & VOCAL', note:'SIDE B1' },
{ id:'dtm', label:'DTM', en:'MUSIC PRODUCTION', note:'SIDE B2' },
];
const dates = [
{ d:'04.22 TUE', avail:4 },
{ d:'04.23 WED', avail:2 },
{ d:'04.24 THU', avail:5 },
{ d:'04.25 FRI', avail:1 },
{ d:'04.26 SAT', avail:3 },
{ d:'04.27 SUN', avail:0 },
];
const times = ['11:00','12:30','14:00','15:30','17:00','18:30','20:00','21:30'];
return (
{/* breadcrumbs */}
FREE · 60 MIN · 入会金¥0
無料体験
レッスン予約
3ステップ、90秒で完了。体験当日の勧誘は一切ありません。
返信は24時間以内(営業時間内)。
{/* step indicator */}
{[1,2,3].map(n => (
= n ? 'rgba(232,237,247,0.06)' : 'transparent',
border:'1px solid ' + (step === n ? 'var(--accent)' : step > n ? 'var(--rule-strong)' : 'var(--rule)'),
borderLeft: '3px solid ' + (step >= n ? 'var(--accent)' : 'var(--rule)'),
}}>
= n ? 'var(--accent)' : 'var(--ink-4)' }}>
STEP {n}
= n ? 'var(--ink)' : 'var(--ink-3)' }}>
{n === 1 && 'コースを選ぶ'}
{n === 2 && '日時を選ぶ'}
{n === 3 && '連絡先を入力'}
))}
{step === 1 && (
STEP 1 · SELECT YOUR COURSE
)}
{step === 2 && (
STEP 2 · PICK DATE & TIME
希望日
{dates.map(d => (
update('date', d.d)}
disabled={d.avail === 0}
style={{
padding:'12px 10px',
background: form.date === d.d ? 'rgba(100,140,220,0.12)' : 'transparent',
border:'1px solid ' + (form.date === d.d ? 'var(--accent)' : 'var(--rule)'),
cursor: d.avail === 0 ? 'not-allowed' : 'pointer',
opacity: d.avail === 0 ? 0.4 : 1,
color:'var(--ink)', fontFamily:'var(--ff-mono)',
}}>
{d.d}
{d.avail === 0 ? '満席' : `空き${d.avail}`}
))}
希望時間
{times.map(t => (
update('time', t)}
style={{
padding:'12px 0',
background: form.time === t ? 'rgba(100,140,220,0.12)' : 'transparent',
border:'1px solid ' + (form.time === t ? 'var(--accent)' : 'var(--rule)'),
cursor:'pointer', color:'var(--ink)',
fontFamily:'var(--ff-mono)', fontSize:13,
}}>
{t}
))}
)}
{step === 3 && (
STEP 3 · YOUR INFO
update('name', v)} />
update('email', v)} />
update('phone', v)} />
音楽経験
{[
{ v:'none', l:'まったく初心者' },
{ v:'some', l:'少しだけ' },
{ v:'hobby', l:'趣味で続けている' },
{ v:'returning', l:'ブランクあり' },
].map(o => (
update('experience', o.v)}
style={{
padding:'8px 14px', fontSize:13,
background: form.experience === o.v ? 'rgba(100,140,220,0.15)' : 'transparent',
border:'1px solid ' + (form.experience === o.v ? 'var(--accent)' : 'var(--rule)'),
color:'var(--ink)', cursor:'pointer',
}}>{o.l}
))}
)}
setStep(Math.max(1, step - 1))}
disabled={step === 1}
className="btn btn-ghost"
style={{ padding:'14px 20px', fontSize:13,
opacity: step === 1 ? 0.4 : 1,
cursor: step === 1 ? 'not-allowed' : 'pointer' }}>
← 戻る
{step < 3 ? (
setStep(step + 1)} className="btn btn-primary"
style={{ padding:'14px 22px', fontSize:13 }}>
次へ →
) : (
alert('体験レッスンのご予約を受け付けました!24時間以内にメールでご連絡します。')}
className="btn btn-primary" style={{ padding:'14px 22px', fontSize:13 }}>
予約を確定する →
)}
{/* Sidebar summary */}
BOOKING SUMMARY
ご予約内容
s.id === form.service)?.label} />
¥0} />
● 手ぶらでOK(筆記用具も不要)
● 服装自由(スーツでも可)
● 当日入会の義務はなし
● キャンセル無料(前日まで)
QUESTIONS?
📞 03-0000-0000
平日 12:00–22:00 / 土日 10:00–20:00
);
}
function Field({ label, ph, val, onChange }) {
return (
);
}
function Row({ k, v }) {
return (
{k}
{v}
);
}
function addMin(t, m) {
const [h, mm] = t.split(':').map(Number);
const total = h * 60 + mm + m;
return `${String(Math.floor(total/60)).padStart(2,'0')}:${String(total%60).padStart(2,'0')}`;
}
window.TrialBooking = TrialBooking;