// ─── オンラインクリニック 結 医師紹介ページ 共通コンポーネント ───
// 読み込み順: 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 }) => (
{items.map((t, i) => - {t}
)}
);
// ─── 定義リスト(見出し|内容の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 (
{items.map((t, i) => - {t}
)}
{note &&
{note}
}
);
};
// ─── セクション見出し付きラッパ ───
const DoctorSectionBlock = ({ eyebrow, title, alt, 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 }) => (
);
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 (
);
};
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}
}
{/* ② 感情へのアプローチ:患者様へのメッセージ */}
{/* 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 });