_includes/resources/tutorial/TutorialStepLayout.11ty.tsx (108 lines of code) (raw):
import { LayoutContext, LayoutProps } from "../../../src/models";
import { TutorialStep, TutorialStepFrontmatter } from "./TutorialStepModels";
import VideoPlayer from "../../video/VideoPlayer.11ty";
import { Tutorial } from "./TutorialModels";
import { BottomNav } from "./TopBottomNav.11ty";
import { BaseLayout } from "../../layouts/BaseLayout.11ty";
import ArticleTitleSubtitle from "../common/ArticleTitleSubtitle.11ty";
import ArticleAuthor from "../common/ArticleAuthor.11ty";
import ArticleTopics from "../common/ArticleTopics.11ty";
import { Fragment } from "jsx-async-runtime/jsx-dev-runtime";
import EditArticle from "../common/EditArticle.11ty";
export type TutorialStepLayoutData = LayoutProps & TutorialStepFrontmatter;
export function TutorialStepLayout(
this: LayoutContext,
data: TutorialStepLayoutData,
): JSX.Element {
const { collections, content, page } = data;
const tutorialStep = collections.resourceMap.get(page.url) as TutorialStep;
const parent = tutorialStep.parentTutorial as Tutorial;
const references = tutorialStep.references;
// video
const video = tutorialStep.video && (
<VideoPlayer source={tutorialStep.video} />
);
// Sidebars
let sidebarSteps: JSX.Element;
if (parent) {
// Sometimes a tutorialstep might be "in-progress" and not
// yet linked into the tutorial
sidebarSteps = parent.tutorialSteps && (
<div class="column is-3 is-full-touch">
<aside class="menu">
<p class="menu-label">Tutorial</p>
<ul class="menu-list">
{parent.tutorialSteps.map((step) => (
<li>
<a
class={step == tutorialStep ? "is-active" : ""}
href={step.url}
>
{step.title}
</a>
</li>
))}
</ul>
</aside>
</div>
);
}
// Main content
const videoBottom = tutorialStep.videoBottom;
const main = (
<Fragment>
<ArticleTitleSubtitle
title={tutorialStep.title}
subtitle={tutorialStep.subtitle}
/>
<ArticleAuthor
author={references!.author}
displayDate={tutorialStep.displayDate}
/>
<EditArticle path={page.inputPath} />
<ArticleTopics topics={references!.topics} />
{video && !videoBottom && <div class="mb-4">{video}</div>}
{content ? <div>{content}</div> : null}
{video && videoBottom && <div class="mb-4">{video}</div>}
</Fragment>
);
// Breadcrumbs
let breadcrumbs: JSX.Element;
if (parent) {
breadcrumbs = (
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>
<a href={parent.url}>{parent.title}</a>
</li>
<li class="is-active">
<a href={tutorialStep.url}>{tutorialStep.title}</a>
</li>
</ul>
</nav>
);
}
// Bottom nav
let bottomNav: JSX.Element;
if (parent) {
bottomNav = (
<BottomNav parent={parent} currentStep={tutorialStep}></BottomNav>
);
}
return (
<BaseLayout subtitle={tutorialStep.subtitle} {...data}>
<div class="section">
<div class="container">
<div class="columns is-multiline">
{sidebarSteps}
<div class="column is-9">
{breadcrumbs}
<main class="content">
{main}
<hr />
{bottomNav}
</main>
</div>
</div>
</div>
</div>
</BaseLayout>
);
}
export const render = TutorialStepLayout;