// MyBookings — 飼い主のマイページ。予約履歴・再予約・初回カウンセリング・レビュー投稿を集約 const MY_BOOKINGS = [ { id:'B-3842', status:'completed', sitter:'みかこ', sitterId:1, sitterPhoto:'peach', date:'2026-05-12(日)', time:'14:00–16:00', service:'訪問ケア', pet:'ココ(柴犬・3歳)', total: 12900, reviewed:true, rating:5, }, { id:'B-3744', status:'completed', sitter:'みかこ', sitterId:1, sitterPhoto:'peach', date:'2026-04-28(日)', time:'10:00–12:00', service:'訪問ケア・散歩', pet:'ココ(柴犬・3歳)', total: 12900, reviewed:false, rating:null, }, { id:'B-3611', status:'completed', sitter:'たくみ', sitterId:2, sitterPhoto:'warm', date:'2026-04-06(日)', time:'09:00–13:00', service:'訪問ケア・散歩', pet:'ココ(柴犬・3歳)', total: 21600, reviewed:true, rating:5, }, { id:'B-3520', status:'completed', sitter:'ゆり', sitterId:3, sitterPhoto:'sage', date:'2026-03-24(日)', time:'13:00–15:00', service:'訪問ケア', pet:'ココ(柴犬・3歳)', total: 13800, reviewed:true, rating:4, }, ]; const UPCOMING = [ { id:'B-3911', status:'upcoming', sitter:'みかこ', sitterId:1, sitterPhoto:'peach', date:'2026-05-24(土)', time:'10:00–13:00', service:'訪問ケア・散歩', pet:'ココ(柴犬・3歳)', total: 16100, paymentStatus:'paid', // pre-paid }, ]; function MyBookings({ initialTab = 'overview' }) { const [tab, setTab] = React.useState(initialTab); // overview | history | counseling | reviews const [reviewing, setReviewing] = React.useState(null); // booking to review return (
{/* Header */}
palpet
S
{/* Sub-nav tabs */}
{[ ['overview','ホーム'], ['history','予約履歴'], ['counseling','初回カウンセリング'], ['reviews','レビュー'], ].map(([k,n])=>( ))}
{tab === 'overview' && } {tab === 'history' && } {tab === 'counseling' && } {tab === 'reviews' && }
{reviewing && setReviewing(null)}/>}
); } // ---------- ホーム ---------- function OverviewTab({ onTab, onReview }) { const next = UPCOMING[0]; const unreviewed = MY_BOOKINGS.filter(b => !b.reviewed); return (
{/* 次の予定 */} 予約を編集 : null}/> {next ? (
{next.date} ・ {next.time}
{next.sitter}さんが {next.pet} のお世話
{next.service}
事前精算済
) : (
予約はありません。シッターを探してみましょう。
)} {/* 未投稿のレビュー */} {unreviewed.length > 0 && ( onTab('reviews')}>すべて見る}/>
{unreviewed.slice(0,2).map(b=>( onReview(b)}/> ))}
)} {/* リピート予約 */} onTab('history')}>履歴を見る}/>
以前と同じシッター・同じ条件で、ワンクリックで予約できます。
{MY_BOOKINGS.slice(0,2).map(b => )}
{/* 初回カウンセリング */}
初回カウンセリング
30分・無料。ペットの性格や暮らしについてヒアリングし、相性のいいシッターをご提案します。
{/* サマリー */}
); } // ---------- 予約履歴 ---------- function HistoryTab({ onReview }) { const [filter, setFilter] = React.useState('all'); // all | upcoming | completed | unreviewed const all = [...UPCOMING.map(b=>({...b,status:'upcoming'})), ...MY_BOOKINGS]; const items = all.filter(b => { if (filter === 'all') return true; if (filter === 'upcoming') return b.status === 'upcoming'; if (filter === 'completed') return b.status === 'completed'; if (filter === 'unreviewed') return b.status === 'completed' && !b.reviewed; return true; }); return (

予約履歴

{items.length}件の予約
{[['all','すべて'],['upcoming','予定'],['completed','完了'],['unreviewed','未レビュー']].map(([k,n])=>( ))}
{items.map(b => ( ))}
); } function BookingRow({ booking, onReview }) { const b = booking; const isUpcoming = b.status === 'upcoming'; return (
{isUpcoming?'予定':'完了'} {b.id} {b.date}・{b.time}
{b.sitter}さん ・ {b.service}
{b.pet} ・ 合計 ¥{b.total.toLocaleString()}(事前精算済)
{b.status === 'completed' && b.reviewed && (
あなたのレビュー:{b.rating}.0
)}
{isUpcoming ? ( <> ) : ( <> {!b.reviewed && ( )} )}
); } // ---------- 初回カウンセリング ---------- function CounselingTab() { const slots = [ ['5/22 (木)','10:00','available'], ['5/22 (木)','14:00','available'], ['5/22 (木)','19:00','full'], ['5/23 (金)','11:00','available'], ['5/23 (金)','15:00','available'], ['5/23 (金)','20:00','available'], ['5/24 (土)','10:00','full'], ['5/24 (土)','13:00','available'], ['5/24 (土)','16:00','available'], ]; const [pick, setPick] = React.useState('5/23 (金) 15:00'); return (
初めての方限定 ・ 30分 ・ 無料

まずはお話を聞かせてください

専属のコンシェルジュが、ペットの性格や暮らし方を伺ったうえで、相性の良いシッターをご提案します。 ビデオ通話または電話、どちらでもOKです。

{slots.map(([d,t,st],i)=>{ const key = `${d} ${t}`; const sel = pick === key; const full = st === 'full'; return ( ); })}
{['ビデオ通話','電話'].map((n,i)=>( ))}