// Matching Search — filter sidebar + sitter cards grid + detail drawer // Interactive: filters update result count, clicking a card opens detail. // 全シッター統一料金(ds.js の PALPET_PRICING に集約) — 個別の rate は持たない const SITTERS = [ {id:1, name:'みかこ', age:29, area:'港区南青山', stations:['表参道','外苑前','青山一丁目'], dist:1.2, pets:['dog','cat','rabbit'], rating:4.98, reviews:312, exp:6, cert:true, verified:true, photo:'peach', tags:['散歩','投薬','シニア'], avail:'土曜 10:00〜', headline:'その子のペースに合わせて、まいにちを大切に。'}, {id:2, name:'たくみ', age:34, area:'世田谷区池尻', stations:['池尻大橋','三軒茶屋','渋谷'], dist:3.8, pets:['dog'], rating:4.96, reviews:188, exp:8, cert:true, verified:true, photo:'warm', tags:['大型犬OK','長距離散歩'], avail:'平日のみ', headline:'体力勝負も任せてください。'}, {id:3, name:'ゆり', age:41, area:'渋谷区代々木', stations:['代々木','参宮橋','明治神宮前','原宿'], dist:2.4, pets:['cat','rabbit'], rating:4.94, reviews:456, exp:12, cert:true, verified:true, photo:'sage', tags:['猫専門','投薬','長期'], avail:'毎日', headline:'臆病な子こそ、得意です。'}, {id:4, name:'けんと', age:27, area:'中野区東中野', stations:['東中野','中野','落合'], dist:5.1, pets:['dog','cat'], rating:4.92, reviews:201, exp:3, cert:false, verified:true, photo:'cream', tags:['深夜OK','緊急対応'], avail:'24時間対応', headline:'夜勤明けの飼い主さんへ。'}, {id:5, name:'あゆみ', age:33, area:'品川区五反田', stations:['五反田','大崎','目黒'], dist:4.0, pets:['dog','cat'], rating:4.89, reviews:142, exp:5, cert:true, verified:true, photo:'warm', tags:['ブラッシング','遊び好き'], avail:'週末メイン', headline:'たっぷり遊んで、ぐっすり眠れるように。'}, {id:6, name:'なお', age:38, area:'目黒区中目黒', stations:['中目黒','代官山','恵比寿','祐天寺'], dist:2.9, pets:['dog','rabbit'], rating:4.97, reviews:289, exp:10, cert:true, verified:true, photo:'peach', tags:['うさぎ専門','看護師経験'], avail:'平日午前', headline:'看護師経験を活かしたケア。'}, ]; // 統一料金は ds.js > window.PALPET_PRICING で管理 const PRICING = (typeof window !== 'undefined' && window.PALPET_PRICING) || { plans:{} }; // 「基本ペットシッタープラン」の最小料金(30分)を訴求用に取得 const STANDARD_TIERS = PRICING.plans?.standard?.tiers || []; const STANDARD_MIN = STANDARD_TIERS[0]?.price || 3800; const STANDARD_60 = STANDARD_TIERS.find(t => t.minutes === 60)?.price || 5300; const NEARBY_STATIONS = ['表参道','外苑前','青山一丁目','広尾','六本木','乃木坂','恵比寿','渋谷','原宿','麻布十番']; function SearchPage({ initialMode = 'list' }) { const [mode, setMode] = React.useState(initialMode); // 'list' | 'detail' const [selected, setSelected] = React.useState(SITTERS[0]); const [filters, setFilters] = React.useState({ pets:['dog'], radius: 5, minExp: 0, minRating: 4.5, services:['visit'], certOnly:false, stations: [], }); const filtered = SITTERS.filter(s => filters.pets.some(p => s.pets.includes(p)) && s.rating >= filters.minRating && s.exp >= filters.minExp && s.dist <= filters.radius && (!filters.certOnly || s.cert) && (filters.stations.length === 0 || filters.stations.some(st => (s.stations||[]).includes(st))) ); const set = (k,v) => setFilters(f=>({...f,[k]:v})); const toggle = (k,v) => setFilters(f=>({...f, [k]: f[k].includes(v) ? f[k].filter(x=>x!==v) : [...f[k],v]})); return (
{/* Header */}
palpet
S
{/* Filter sidebar */} {/* Results column */}
🏛️
19年のペットケア実績を持つソプラ銀座が運営。厳しい審査・面接を経た有資格者のみが在籍するため、 料金は全シッター統一です(1時間 ¥{STANDARD_60.toLocaleString()}〜・税込)。

港区周辺のシッター

{filtered.length}名のシッターが対応可能 ・ 5/24(土)以降
並び替え
{filtered.map(s => ( {setSelected(s); setMode('detail');}}/> ))} {filtered.length===0 && (
条件にあうシッターが見つかりませんでした。
条件をゆるめてみてください。
)}
{/* Detail drawer */} {mode === 'detail' && ( )}
); } const iconBtn = { width:38,height:38,borderRadius:12,border:'none',background:'transparent', cursor:'pointer',display:'grid',placeItems:'center',color:'#5d4d3a', }; const chip = (sel) => ({ padding:'8px 14px',borderRadius:999,fontFamily:'inherit',fontSize:13,cursor:'pointer', border:'1.5px solid '+(sel?'var(--c-primary)':'rgba(0,0,0,.08)'), background: sel?'var(--c-primary-soft)':'#fff', color: sel?'var(--c-primary-deep)':'#3c2f1e', fontWeight: sel?700:500, }); function FilterGroup({label, children}) { return (
{label}
{children}
); } function SearchBar() { return (
港区南青山 · 柴犬・3歳 · 5/24(土)10:00〜
); } const photoTones = { peach:['#F8CFB8','#EBA689'], warm:['#F4DBA8','#E8B97A'], sage:['#CBE0CC','#9CC2A4'], cream:['#F5E7CC','#E0CFA8'] }; // photoBG は「シッターID」または「トーン名」を受け取る // - 数値ID(1〜6)→ Unsplashのシッター写真を返す // - 文字列 'peach'/'warm'/'sage'/'cream' → 斜線パターンを返す(後方互換) const photoBG = (idOrTone) => { if (typeof idOrTone === 'number' && typeof window !== 'undefined' && window.PALPET_PHOTOS?.sitters?.[idOrTone]) { return `url("${window.PALPET_PHOTOS.sitters[idOrTone]}") center/cover no-repeat`; } const t = photoTones[idOrTone] ? idOrTone : 'warm'; return `repeating-linear-gradient(135deg, ${photoTones[t][0]} 0 12px, ${photoTones[t][1]} 12px 24px)`; }; const petLabelMap = {dog:'犬',cat:'猫',rabbit:'うさぎ',bird:'鳥',reptile:'爬虫類'}; function SitterCard({sitter, active, compact, onClick}) { const s = sitter; return (
{s.name}{s.age}歳
{s.verified && ✓ 本人確認} {s.cert && 資格あり}
{s.area}・{s.dist}km 経験 {s.exp}年
{s.stations && s.stations.length > 0 && (
{s.stations.slice(0,4).map((st,i)=>( {st} ))}
)}
{s.headline}
{!compact && (
{s.tags.map((t,i)=>( {t} ))}
)}
{s.rating} ({s.reviews}) {s.avail}
全国共通料金 このシッターに依頼
); } const Badge = ({children, tone}) => ( {children} ); function SitterDetail({sitter, onClose}) { const s = sitter; return (
シッター詳細

{s.name}{s.age}歳

{s.area} ・ {s.dist}km {s.avail}
全シッター統一料金
¥{STANDARD_60.toLocaleString()}/1時間〜
料金表を見る
{s.verified && ✓ 本人確認} {s.cert && 資格保有} 保険適用 {s.exp}年の経験 ソプラ銀座 認定

はじめまして

{s.headline}
ペットケアアドバイザー2級を保有しています。実家で犬・猫・うさぎを飼っていた経験があり、 どの子のお世話も大切にお引き受けします。

対応できるペット

{s.pets.map(p=>(
{p==='dog'&&}{p==='cat'&&}{p==='rabbit'&&} {petLabelMap[p]}
))}

得意なお世話

{s.tags.map((t,i)=>( {t} ))}

レビュー

{[ ['出張中、毎日の写真と動画が届いてホッとしました。','ゆうこさん','5/12'], ['シニアの猫の投薬もばっちり。安心してまかせられます。','けんすけさん','4/28'], ].map(([q,n,d],i)=>(
5.0 · {n}
{d}
{q}
))}
); } const H3 = ({children}) =>

{children}

; const Stat = ({n,l,hint}) => (
{n}
{l}
); window.SearchPage = SearchPage; window.photoBG = photoBG; window.photoTones = photoTones; window.SitterBadge = Badge; window.SITTERS = SITTERS;