// Owner Onboarding — 5-step pet-owner registration flow. // Reuses the shared register field helpers but with owner-side content. const Field = window.RegField; const inputCss = window.regInputCss; function OwnerRegister({ initialStep = 0 }) { const [step, setStep] = React.useState(initialStep); const [form, setForm] = React.useState({ pets: [ { name: '', species: 'dog', breed: '', age: '', sex: '', weight: '', traits: [], allergies: '', meds: '', likes: '' }, ], services: ['visit'], frequency: 'occasional', keyMethod: 'smart-lock', reportFreq: 'every-visit', emergency: '', }); const set = (k,v) => setForm(f => ({...f, [k]:v})); const toggle = (k,v) => setForm(f => ({...f, [k]: f[k].includes(v) ? f[k].filter(x=>x!==v) : [...f[k],v]})); const updatePet = (i,patch) => setForm(f => ({...f, pets: f.pets.map((p,idx)=>idx===i?{...p,...patch}:p)})); const togglePetTrait = (i,trait) => setForm(f => ({...f, pets: f.pets.map((p,idx)=>idx===i?{...p, traits: p.traits.includes(trait)?p.traits.filter(t=>t!==trait):[...p.traits,trait]}:p)})); const steps = [ ['ようこそ','01'], ['ペットの基本情報','02'], ['性格・健康','03'], ['希望のお世話','04'], ['お留守番の希望','05'], ]; const next = () => setStep(s => Math.min(s+1, steps.length-1)); const prev = () => setStep(s => Math.max(s-1, 0)); // 送信状態 const [submitState, setSubmitState] = React.useState({ phase:'idle', message:'' }); const submit = async () => { setSubmitState({ phase:'loading', message:'送信中…' }); const p = form.pets[0] || {}; const data = { ownerName: form.ownerName || '', email: form.email || '', phone: form.phone || '', address: form.address || '', petName: p.name || '', petKind: p.species || '', petAge: p.age || '', petBreed: p.breed || '', petWeight: p.weight || '', petTemperament: (p.traits || []).join('・'), petHealth: [p.allergies && `アレルギー: ${p.allergies}`, p.meds && `投薬: ${p.meds}`].filter(Boolean).join(' / '), services: form.services || [], reportFreq: form.frequency || '', keyHandling: form.keyMethod || '', reportFreqDetail: form.reportFreq || '', emergency: form.emergency || '', }; const res = await window.palpetSubmitRegistration({ type: 'customer', data, photos: [ ['petPhoto', p.photo], ], }); if (res.ok) { setSubmitState({ phase:'success', message: res.demo ? 'デモ送信が完了しました(実際の通知は走っていません)。次は「シッターを探す」へどうぞ。' : `登録完了。受付ID: ${res.row?.id || '—'}。コンシェルジュより1〜2営業日でご案内します。`, res, }); } else { setSubmitState({ phase:'error', message: res.message || res.error || '送信に失敗しました。', res, }); } }; return (
palpet
はじめまして! ペットの登録をお願いします
あとで設定する
{/* Stepper rail */} {/* Main */}
{step === 0 && } {step === 1 && } {step === 2 && } {step === 3 && } {step === 4 && } {submitState.phase !== 'idle' && (() => { const SF = window.SubmitFeedback; return SF ? setSubmitState({phase:'idle',message:''})}/> : null; })()}
{/* Pet preview */}
); } // ----- step bodies ----- function OwnerWelcome() { return (
STEP 01

はじめまして 🐾
うちの子のこと、教えてください。

ペットの性格や好きなこと、お留守番のときに気をつけて欲しいこと。 シッターさんがその子と向き合うために、ご家族の声を集めさせてください。

1分で登録、すぐ依頼できます
後からプロフィールはいつでも更新できます。複数のペットも登録OK。
); } // ペット写真用の縦型アップローダー(PhotoUpload の vertical 変形) function PetPhotoUpload({ value, onChange }) { const inputRef = React.useRef(null); const [previewURL, setPreviewURL] = React.useState(null); React.useEffect(() => { if (value instanceof File) { const url = URL.createObjectURL(value); setPreviewURL(url); return () => URL.revokeObjectURL(url); } else { setPreviewURL(null); } }, [value]); const pick = () => inputRef.current?.click(); const onFile = (e) => { const f = e.target.files?.[0]; if (f) onChange(f); e.target.value = ''; }; return (
{previewURL ? ( pet ) : ( 📷 photo )}
); } function OwnerPet({form, updatePet}) { const p = form.pets[0]; return (
STEP 02

ペットの基本情報

あとで何頭でも追加できます。

updatePet(0,{photo:f})}/>
お顔がはっきり見える写真を選んでください
updatePet(0,{name:e.target.value})}/>
{[['dog','犬'],['cat','猫'],['rabbit','うさぎ'],['other','他']].map(([k,n])=>{ const sel = p.species === k; return ( ); })}
updatePet(0,{breed:e.target.value})}/> updatePet(0,{age:+e.target.value})}/>
{[['F','メス'],['M','オス']].map(([k,n])=>{ const sel = p.sex === k; return ( ); })}
updatePet(0,{weight:+e.target.value})}/>
); } function OwnerHealth({form, updatePet, togglePetTrait}) { const p = form.pets[0]; const traits = [ ['friendly','人懐っこい'], ['shy_strangers','人見知り'], ['active','元気いっぱい'], ['calm','おとなしい'], ['barks','よく吠える'], ['food_motivated','食いしん坊'], ['other_pets_ok','他の動物OK'], ['kids_ok','子ども慣れ'], ['anxious_alone','留守番が苦手'], ]; return (
STEP 03

{p.name ? `${p.name}ちゃんのこと、教えてください` : 'ペットのこと、教えてください'}

シッターさんがその子に合わせて、寄り添ってお世話できるように。

性格・特徴(複数選択可)
{traits.map(([k,n])=>{ const sel = p.traits.includes(k); return ( ); })}
updatePet(0,{allergies:e.target.value})}/> updatePet(0,{meds:e.target.value})}/>