// ─── オンラインクリニック 結 医師紹介ページ 共通コンポーネント ─── // 読み込み順: doctors.js → ../lp/shared.jsx → shared.jsx // ../lp/shared.jsx から Icon / OnkriLogo / useReveal / LPStickyCTA を再利用する。 // ヘッダは TOPページ(index.html の Nav)に合わせるため、LPHeader は使わず DoctorNav を使う。 // 各医師ページは するだけ。 const { useEffect: useEffectD } = React; // doctors/ 配下からサイトルート基準のパスを解決する const up = (p) => (p ? '../' + p : p); const DOCTOR_CTA_URL = 'https://quick.yadoc.jp/reception/69798c9253e30355443505'; // 画像が無いときは順に代替画像へ差し替える(index.html の onError と同じ方針) // 文字列でも配列でも渡せる。配列の場合は先頭から順に試す。 const swapToFallback = (fallbacks) => (e) => { const list = Array.isArray(fallbacks) ? fallbacks : [fallbacks]; const step = Number(e.target.dataset.fbStep || 0); if (step >= list.length) return; e.target.dataset.fbStep = String(step + 1); e.target.src = list[step]; }; // ─── 年表(学歴・職歴/受賞歴) ─── const DoctorHistory = ({ rows }) => (
{rows.map((r, i) => (
{r.year}
{r.text}
))}
); // ─── チップ(専門分野・保有資格の1項目) ─── const DoctorTags = ({ items }) => ( ); // ─── 定義リスト(見出し|内容の2列。tags があればチップ、無ければ text) ─── const DoctorDefList = ({ rows }) => (
{rows.map((r, i) => (
{r.label}
{r.tags ? : r.text}
))}
); // ─── 箇条書き(所属学会)。文字列で渡された場合は従来どおり1段落で出す ─── const DoctorList = ({ items, note }) => { if (!Array.isArray(items)) return

{items}

; return (
{note &&

{note}

}
); }; // ─── セクション見出し付きラッパ ─── const DoctorSectionBlock = ({ eyebrow, title, alt, children }) => (
{eyebrow}

{title}

{children}
); // ─── ヘッダ ─── // index.html の Nav(TOPページ)をそのまま移植したもの。項目・段組み・寸法をTOPと揃える。 // 相違点は次の2つだけ。 // ・ページ内アンカー(#merit 等)を ../index.html#merit に、他ページを ../kenpo.html 等に変える // ・下層ページなのでロゴをTOPへのリンクにする(TOPは自分自身なのでリンクなし) // TODO: index.html 側の mainNavItems / subNavItems を変更したら、ここも同じ内容に更新すること。 // TOPの accentColor(TWEAK_DEFAULTS)と同値。ホバー色に使う。 const DOCTOR_ACCENT = '#1a64c8'; // 下段:一般利用者向けのメインナビ(index.html の mainNavItems と同じ並び・同じ項目) const DOCTOR_MAIN_NAV_ITEMS = [ { label: 'メリット', href: '../index.html#merit' }, { label: '予約システム', href: '../index.html#booking' }, { label: '診療メニュー', href: '../index.html#menu' }, { label: '医師紹介', href: '../index.html#doctors' }, { label: '診療時間', href: '../index.html#schedule' }, { label: '流れ', href: '../index.html#flow' }, { label: '費用', href: '../index.html#price' }, { label: '提携医療機関', href: '../index.html#partners' }, { label: 'よくある質問', href: '../index.html#faq' } ]; // 上段:法人・団体向けのサブナビ const DOCTOR_SUB_NAV_ITEMS = [ { label: '健保組合向け', href: '../kenpo.html' }, { label: '企業向け', href: '../corporate.html' } ]; // ../lp/shared.jsx の Icon には menu / x が無いためここで定義する(index.html の Icon と同じパス) const NavGlyph = ({ open, size = 24 }) => ( {open ? : } ); const DoctorNav = () => { const [scrolled, setScrolled] = React.useState(false); const [menuOpen, setMenuOpen] = React.useState(false); useEffectD(() => { const fn = () => setScrolled(window.scrollY > 40); fn(); window.addEventListener('scroll', fn); return () => window.removeEventListener('scroll', fn); }, []); return ( ); }; // ─── フッター ─── // index.html の Footer(TOPページ)をそのまま移植したもの。 // 相違点はリンク先を doctors/ 配下から辿れるパス(../index.html#menu 等)に変えることだけ。 // TODO: index.html 側の Footer を変更したら、ここも同じ内容に更新すること。 // TODO(医師一覧公開時): 「医師紹介」の href を '../doctors/index.html' に変更する。 // 全ページ共通のフッターメニュー。index.html の FOOTER_MENU と同じ内容を doctors/ 配下から辿れるパスで持つ。 const DOCTOR_FOOTER_MENU = [ { title: '診療メニュー', links: [ { label: '高血圧', href: '../lp/高血圧.html' }, { label: '糖尿病', href: '../lp/糖尿病.html' }, { label: '脂質異常症', href: '../lp/脂質異常症.html' }, { label: '花粉症', href: '../lp/花粉症.html' }] }, { title: '医師紹介', links: [ { label: '中神 啓徳', href: 'nakagami.html' }, { label: '田中 裕貴', href: 'tanaka-hiroki.html' }, { label: '田中 真帆', href: 'tanaka-maho.html' }, { label: '宮﨑 祐宗', href: 'miyazaki-masamune.html' }] }, { title: 'ご利用案内', links: [ { label: '費用', href: '../#price' }, { label: '診療時間', href: '../#schedule' }, { label: 'ご利用の流れ', href: '../#flow' }, { label: 'Web予約', href: 'https://quick.yadoc.jp/reception/69798c9253e30355443505', external: true }] }, { title: '法人・健保組合の方', links: [ { label: '健保組合向けご提案', href: '../kenpo.html' }, { label: '企業向けご提案', href: '../corporate.html' }, { label: '健康経営について', href: '/kenko-keiei.html' }] }, { title: 'サポート', links: [ { label: 'よくある質問', href: '../#faq' }, { label: 'お問い合わせ', href: '../contact.html' }, { label: '利用規約', href: '../terms.html' }, { label: 'プライバシーポリシー', href: '../privacy.html' }] } ]; // メニュー1区分。スマホ幅(600px以下)では見出しをタップして開閉するアコーディオン。 // PCでは常に開いた表示(切り替えは doctors.css の @media)。index.html の FooterGroup と同じ作り。 const DoctorFooterGroup = ({ group }) => { const [open, setOpen] = React.useState(false); return (

{group.links.map((l) => {l.label} )}
); }; const DoctorFooter = () => ( ); // ─── ページ末尾の共通パーツ(出典表記+TOPへ戻る) ─── // 受賞歴がある医師は受賞歴セクションの中に、無い医師は専用セクションの中に置く。 const DoctorPageFoot = ({ doctor: d }) => ( <> {d.source && (

出典: {d.source.label}

)}
オンラインクリニック 結 トップへ戻る
); // ─── 医師詳細ページ本体 ─── const DoctorApp = ({ doctor: d }) => { useReveal(); useEffectD(() => { if (d && d.pageTitle) document.title = d.pageTitle; }, [d]); if (!d) return null; return ( <> {/* ① ファーストビュー:写真+キャッチコピー */}
医師紹介

{(d.catchcopy || []).map((line, i) => {line})}

{d.heroLead &&

{d.heroLead}

}
{d.name}{d.suffix} {d.kana && ({d.kana})}
{d.affiliation &&

{d.affiliation}

}
{d.name}
{/* ② 感情へのアプローチ:患者様へのメッセージ */} {/* 2026-09-11 一旦非表示。doctors.js の showMessage を true にすると戻る。 */} {d.showMessage && d.message && (
MESSAGE

{d.message.title}

{d.message.paragraphs.map((t, i) =>

{t}

)}

{d.affiliation}
{d.name}

)} {/* ③ 専門分野・プロフィール(背景の縞は message→specialty→career… と交互になるよう alt を振る) */} {d.specialty && ( )} {d.licenses && d.licenses.length > 0 && ( )} {/* ⑧ 受賞歴(受賞歴の無い医師は見出しごと省く)+出典・TOPへ戻る。 出典/戻るボタンは受賞歴セクションの末尾に置いていたので、受賞歴が無いときは 同じ見た目の alt セクションを1枚だけ立てて、そこに逃がす(背景の縞も途切れない)。 */} {d.awards && d.awards.length > 0 ? ( ) : (
)} ); }; Object.assign(window, { DoctorApp, DoctorNav, DoctorFooter, DoctorPageFoot, DoctorHistory, DoctorDefList, DoctorTags, DoctorList, DoctorSectionBlock, up });