function getFeaturedImage(item, fallback) { return (item && item._embedded && item._embedded["wp:featuredmedia"] && item._embedded["wp:featuredmedia"][0] && item._embedded["wp:featuredmedia"][0].source_url) || fallback; } function getTermName(item, taxonomy) { const groups = (item && item._embedded && item._embedded["wp:term"]) || []; for (const group of groups) { const t = group.find((t) => t.taxonomy === taxonomy); if (t) return t.name; } return ""; } function stripTags(html) { // タグ除去に加え、WordPressが変換した文字参照(’ など)も元の文字に戻す return (new DOMParser().parseFromString(html || "", "text/html").body.textContent || "").trim(); } function splitTitle(title) { const idx = title.indexOf("、"); if (idx === -1) return [title]; return [title.slice(0, idx + 1), title.slice(idx + 1)]; } const STORY_ITEMS = [ { image: "/wp-content/themes/original/assets/story-photo-highschool.png", category: "高校生 / INTERVIEW", title: ["学校の外で、", "はじめて“企画”をやってみた。"], name: "N.Yさん", }, { image: "/wp-content/themes/original/assets/story-photo-university.png", category: "大学生 / INTERVIEW", title: ["「好き」が、", "最初のきっかけになった。"], name: "N.Yさん", }, { image: "/wp-content/themes/original/assets/story-photo-worker.png", category: "若手社会人 / INTERVIEW", title: ["会社を辞めずに、", "小さく試してみた。"], name: "N.Yさん", }, ]; // Figma上は3種の写真を3回繰り返した仮データ(記事カード|仮原稿)。各写真固有のズーム/トリミング値。 const STORY_CARD_CROPS = [ { h: "127.28%", left: "-8.07%", top: "-0.01%", w: "109.37%" }, { h: "189.09%", left: "-32.51%", top: "-17.27%", w: "162.42%" }, { h: "150%", left: "-21.26%", top: "-8.18%", w: "128.98%" }, ]; // イラスト|ジャンプする人物(ストーリー一覧ヒーローの装飾。Eventセクションと同一アセットを444x469で表示) function HeroJumperIllust({ className }) { const p = "/wp-content/themes/original/assets/event-illust-227-"; return (
); } // 02|ストーリー一覧ヒーロー(Figma 448:580) function StoryHero() { return (
{/* PC: 1440px基準の絶対配置を画面幅に応じて比率を保ったまま縮小・拡大表示する */}

Challenge Stories

長崎で活躍する人たち

{/* SP: シンプルな縦積みレイアウト(装飾イラストは省略) */}

Challenge Stories

長崎で活躍する人たち

); } // 03|インタビュー記事カード一覧(Figma 448:682)。フォールバックは3種のインタビューを3回繰り返した仮データ function InterviewCard({ item, crop, link }) { return (

{item.category}

{item.title.map((line, i) => (

{line}

))}
{item.name && (

{item.name}

)}
); } function InterviewGrid() { const fallbackCards = [0, 1, 2].flatMap(() => STORY_ITEMS.map((item, i) => ({ item, crop: STORY_CARD_CROPS[i], link: STORY_PAGE_URL })) ); const [cards, setCards] = useState(fallbackCards); useEffect(() => { fetch(`${WP_API}/wp/v2/story?_embed&per_page=20&orderby=date&order=desc`) .then((r) => (r.ok ? r.json() : null)) .then((data) => { if (!data || !data.length) return; setCards( data.map((post) => ({ item: { image: getFeaturedImage(post, "/wp-content/themes/original/assets/story-photo-worker.png"), category: `${getTermName(post, "story_category") || "INTERVIEW"} / INTERVIEW`, title: splitTitle(stripTags(post.title.rendered)), name: (post.story_fields && post.story_fields.interviewee_name) || "", }, crop: { h: "127.28%", left: "-8.07%", top: "-0.01%", w: "109.37%" }, link: post.link, })) ); }) .catch(() => {}); }, []); return (
{cards.map((c, idx) => ( ))}
); } function App() { const [mobileOpen, setMobileOpen] = useState(false); return ( <>
setMobileOpen(true)} />