Files
pat 195baa32cc
deploy / build-and-deploy (push) Canceled after 0s
chore: brand presentation is AiBook.fun
2026-09-02 16:33:08 +00:00

209 lines
7.2 KiB
React

import { useEffect, useMemo } from "react";
import Head from "next/head";
import ReaderNav from "../../components/reader/ReaderNav";
import ReaderCrumbs from "../../components/reader/ReaderCrumbs";
import ReaderFooter from "../../components/reader/ReaderFooter";
import WorkflowBlock from "../../components/reader/WorkflowBlock";
import ChapterOutline from "../../components/reader/ChapterOutline";
import WorkflowRail from "../../components/reader/WorkflowRail";
import ChapterKit from "../../components/reader/ChapterKit";
import useActivation from "../../components/reader/useActivation";
import { CHAPTER, RECIPES, buildOutline } from "../../data/sample-chapter";
const RECIPE_IDS = RECIPES.map((r) => r.id);
const ESSAY_KEYS = ["stakes", "constraints", "practice"];
function Essay({ id, heading, paragraphs }) {
return (
<section className="essay" id={id}>
<h2>{heading}</h2>
{paragraphs.map((p) => (
<p key={p}>{p}</p>
))}
</section>
);
}
export default function RealEstateChapter() {
const { complete, toggle, count, total } = useActivation(RECIPE_IDS);
const [first, second] = RECIPES;
const outline = useMemo(() => buildOutline(CHAPTER, RECIPES), []);
const essayGroup = outline.find((g) => g.label === "Essay");
const workflowGroup = outline.find((g) => g.label === "Workflows");
useEffect(() => {
const hash = window.location.hash;
if (!hash) return;
const el = document.getElementById(hash.slice(1));
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
}, []);
return (
<>
<Head>
<title>{CHAPTER.title} · AiBook.fun reading demo</title>
<meta name="description" content={CHAPTER.promise} />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>
<ReaderNav here="chapter" />
<main>
<article className="chapter-page">
<div className="wrap reader-wide">
<ReaderCrumbs
items={[
{ href: "/read", label: "Library" },
{ label: CHAPTER.vertical, current: true },
]}
/>
</div>
<div className="wrap reader-wide chapter-shell">
<ChapterOutline
groups={outline}
complete={complete}
count={count}
total={total}
/>
<div className="chapter-col">
<span className="spec demo-chip">Reading demo · not the live book</span>
<p className="spec chapter-kicker">
{CHAPTER.vertical} · {CHAPTER.edition} edition
</p>
<h1 className="chapter-title">{CHAPTER.title}</h1>
<p className="chapter-by">{CHAPTER.authors}</p>
<ChapterOutline
variant="mobile"
groups={outline}
complete={complete}
count={count}
total={total}
/>
<p className="chapter-promise">{CHAPTER.promise}</p>
<ChapterKit recipes={RECIPES} />
<section className="chapter-map" aria-label="What's in this chapter">
<h2 className="chapter-map-title">What's in this chapter</h2>
<div className="chapter-map-block">
<p className="spec">Essay</p>
<ul>
{essayGroup.items.map((item) => (
<li key={item.id}>
<a href={`#${item.id}`}>{item.label}</a>
</li>
))}
</ul>
</div>
<div className="chapter-map-block">
<p className="spec">Workflows</p>
<ul>
{workflowGroup.items.map((item) => (
<li key={item.id}>
<a href={`#${item.id}`}>
{item.recipeId} · {item.shortTitle} · {item.time}
{item.tools ? ` · ${item.tools}` : ""}
</a>
</li>
))}
</ul>
</div>
</section>
<div className="skip-row">
<span className="skip-label">Skip to a Try-it</span>
{RECIPES.map((r) => (
<a key={r.id} className="skip-chip" href={`#${r.anchor}`}>
{r.id}
<span className="skip-chip-job">{r.shortTitle}</span>
</a>
))}
</div>
{ESSAY_KEYS.map((key) => (
<Essay
key={key}
id={CHAPTER[key].id}
heading={CHAPTER[key].heading}
paragraphs={CHAPTER[key].paragraphs}
/>
))}
<p className="spec workflow-kicker">
Workflow 1 of {RECIPES.length} in this chapter
</p>
<WorkflowBlock
recipe={first}
index={1}
total={RECIPES.length}
complete={!!complete[first.id]}
onToggleComplete={toggle}
/>
<Essay
id={CHAPTER.between.id}
heading={CHAPTER.between.heading}
paragraphs={CHAPTER.between.paragraphs}
/>
<p className="spec workflow-kicker">
Workflow 2 of {RECIPES.length} in this chapter
</p>
<WorkflowBlock
recipe={second}
index={2}
total={RECIPES.length}
complete={!!complete[second.id]}
onToggleComplete={toggle}
/>
<section className="end-matter" id="further">
<h2>Further workflows in this vertical</h2>
<ul className="further-list">
{CHAPTER.further.map((item) => (
<li key={item.id}>
{item.coming ? (
<>
<span className="recipe-id">
<b>{item.id}</b>
</span>{" "}
{item.title}
</>
) : (
<>
<a href={item.href}>
<span className="recipe-id">
<b>{item.id}</b>
</span>
</a>{" "}
{item.title}
</>
)}
</li>
))}
</ul>
</section>
<section className="end-sources" id="sources">
<h2>Sources</h2>
<ul className="further-list">
{CHAPTER.sources.map((s) => (
<li key={s}>{s}</li>
))}
</ul>
<p className="chapter-updated">Last updated: {CHAPTER.lastUpdated}</p>
</section>
</div>
<WorkflowRail recipes={RECIPES} complete={complete} total={total} />
</div>
</article>
</main>
<ReaderFooter />
</>
);
}