diff options
Diffstat (limited to 'services/blog/nuldoc-src/pages')
| -rw-r--r-- | services/blog/nuldoc-src/pages/AboutPage.tsx | 110 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/AtomPage.tsx | 26 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/HomePage.tsx | 53 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/NotFoundPage.tsx | 27 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/PostListPage.tsx | 54 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/PostPage.tsx | 66 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/SlideListPage.tsx | 42 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/SlidePage.tsx | 72 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/TagListPage.tsx | 57 | ||||
| -rw-r--r-- | services/blog/nuldoc-src/pages/TagPage.tsx | 43 |
10 files changed, 550 insertions, 0 deletions
diff --git a/services/blog/nuldoc-src/pages/AboutPage.tsx b/services/blog/nuldoc-src/pages/AboutPage.tsx new file mode 100644 index 00000000..3d6583a4 --- /dev/null +++ b/services/blog/nuldoc-src/pages/AboutPage.tsx @@ -0,0 +1,110 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import StaticScript from "../components/StaticScript.tsx"; +import { Config } from "../config.ts"; +import { dateToString } from "../revision.ts"; +import { getPostPublishedDate } from "../generators/post.ts"; +import { SlidePage } from "../generators/slide.ts"; + +export default function AboutPage( + slides: SlidePage[], + config: Config, +) { + return ( + <PageLayout + metaCopyrightYear={config.blog.siteCopyrightYear} + metaDescription="このサイトの著者について" + metaTitle={`About|${config.blog.siteName}`} + config={config} + > + <body className="single"> + <GlobalHeader config={config} /> + <main className="main"> + <article className="post-single"> + <header className="post-header"> + <h1 className="post-title">nsfisis</h1> + <div className="my-icon"> + <div id="myIcon"> + <img src="/favicon.svg" /> + </div> + <StaticScript + fileName="/my-icon.js" + defer="true" + config={config} + /> + </div> + </header> + <div className="post-content"> + <section> + <h2>読み方</h2> + <p> + 読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。 + </p> + </section> + <section> + <h2>アカウント</h2> + <ul> + <li> + <a + href="https://twitter.com/nsfisis" + target="_blank" + rel="noreferrer" + > + Twitter (現 𝕏): @nsfisis + </a> + </li> + <li> + <a + href="https://github.com/nsfisis" + target="_blank" + rel="noreferrer" + > + GitHub: @nsfisis + </a> + </li> + </ul> + </section> + <section> + <h2>仕事</h2> + <ul> + <li> + {"2021-01~現在: "} + <a + href="https://www.dgcircus.com/" + target="_blank" + rel="noreferrer" + > + デジタルサーカス株式会社 + </a> + </li> + </ul> + </section> + <section> + <h2>登壇</h2> + <ul> + {Array.from(slides).sort((a, b) => { + const ta = dateToString(getPostPublishedDate(a)); + const tb = dateToString(getPostPublishedDate(b)); + if (ta > tb) return -1; + if (ta < tb) return 1; + return 0; + }).map((slide) => ( + <li> + <a href={slide.href}> + {`${ + dateToString(getPostPublishedDate(slide)) + }: ${slide.event} (${slide.talkType})`} + </a> + </li> + ))} + </ul> + </section> + </div> + </article> + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/AtomPage.tsx b/services/blog/nuldoc-src/pages/AtomPage.tsx new file mode 100644 index 00000000..21c3bfaf --- /dev/null +++ b/services/blog/nuldoc-src/pages/AtomPage.tsx @@ -0,0 +1,26 @@ +import { Feed } from "../generators/atom.ts"; + +export default function AtomPage({ feed }: { feed: Feed }) { + return ( + <feed xmlns="http://www.w3.org/2005/Atom"> + <id>{feed.id}</id> + <title>{feed.title}</title> + <link rel="alternate" href={feed.linkToAlternate} /> + <link rel="self" href={feed.linkToSelf} /> + <author> + <name>{feed.author}</name> + </author> + <updated>{feed.updated}</updated> + {feed.entries.map((entry) => ( + <entry> + <id>{entry.id}</id> + <link rel="alternate" href={entry.linkToAlternate} /> + <title>{entry.title}</title> + <summary>{entry.summary}</summary> + <published>{entry.published}</published> + <updated>{entry.updated}</updated> + </entry> + ))} + </feed> + ); +} diff --git a/services/blog/nuldoc-src/pages/HomePage.tsx b/services/blog/nuldoc-src/pages/HomePage.tsx new file mode 100644 index 00000000..8850d039 --- /dev/null +++ b/services/blog/nuldoc-src/pages/HomePage.tsx @@ -0,0 +1,53 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config } from "../config.ts"; + +export default function HomePage(config: Config) { + return ( + <PageLayout + metaCopyrightYear={config.blog.siteCopyrightYear} + metaDescription="nsfisis のブログサイト" + metaTitle={config.blog.siteName} + metaAtomFeedHref={`https://${config.blog.fqdn}/atom.xml`} + config={config} + > + <body className="single"> + <GlobalHeader config={config} /> + <main className="main"> + <article className="post-single"> + <article className="post-entry"> + <a href="/about/"> + <header className="entry-header"> + <h2>About</h2> + </header> + </a> + </article> + <article className="post-entry"> + <a href="/posts/"> + <header className="entry-header"> + <h2>Posts</h2> + </header> + </a> + </article> + <article className="post-entry"> + <a href="/slides/"> + <header className="entry-header"> + <h2>Slides</h2> + </header> + </a> + </article> + <article className="post-entry"> + <a href="/tags/"> + <header className="entry-header"> + <h2>Tags</h2> + </header> + </a> + </article> + </article> + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/NotFoundPage.tsx b/services/blog/nuldoc-src/pages/NotFoundPage.tsx new file mode 100644 index 00000000..9631fef2 --- /dev/null +++ b/services/blog/nuldoc-src/pages/NotFoundPage.tsx @@ -0,0 +1,27 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config } from "../config.ts"; + +export default function NotFoundPage( + config: Config, +) { + return ( + <PageLayout + metaCopyrightYear={config.blog.siteCopyrightYear} + metaDescription="リクエストされたページが見つかりません" + metaTitle={`Page Not Found|${config.blog.siteName}`} + config={config} + > + <body className="single"> + <GlobalHeader config={config} /> + <main className="main"> + <article> + <div className="not-found">404</div> + </article> + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/PostListPage.tsx b/services/blog/nuldoc-src/pages/PostListPage.tsx new file mode 100644 index 00000000..054955e6 --- /dev/null +++ b/services/blog/nuldoc-src/pages/PostListPage.tsx @@ -0,0 +1,54 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import Pagination from "../components/Pagination.tsx"; +import PostPageEntry from "../components/PostPageEntry.tsx"; +import { Config } from "../config.ts"; +import { PostPage } from "../generators/post.ts"; + +export default function PostListPage( + posts: PostPage[], + config: Config, + currentPage: number, + totalPages: number, +) { + const pageTitle = "投稿一覧"; + + const pageInfoSuffix = ` (${currentPage}ページ目)`; + const metaTitle = `${pageTitle}${pageInfoSuffix}|${config.blog.siteName}`; + const metaDescription = `投稿した記事の一覧${pageInfoSuffix}`; + + return ( + <PageLayout + metaCopyrightYear={config.blog.siteCopyrightYear} + metaDescription={metaDescription} + metaTitle={metaTitle} + metaAtomFeedHref={`https://${config.blog.fqdn}/posts/atom.xml`} + config={config} + > + <body className="list"> + <GlobalHeader config={config} /> + <main className="main"> + <header className="page-header"> + <h1>{pageTitle}{pageInfoSuffix}</h1> + </header> + + <Pagination + currentPage={currentPage} + totalPages={totalPages} + basePath="/posts/" + /> + + {posts.map((post) => <PostPageEntry post={post} key={post.uuid} />)} + + <Pagination + currentPage={currentPage} + totalPages={totalPages} + basePath="/posts/" + /> + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/PostPage.tsx b/services/blog/nuldoc-src/pages/PostPage.tsx new file mode 100644 index 00000000..97a24048 --- /dev/null +++ b/services/blog/nuldoc-src/pages/PostPage.tsx @@ -0,0 +1,66 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config, getTagLabel } from "../config.ts"; +import { Element } from "../dom.ts"; +import { Document } from "../djot/document.ts"; +import { dateToString } from "../revision.ts"; +import { getPostPublishedDate } from "../generators/post.ts"; + +export default function PostPage( + doc: Document, + config: Config, +) { + return ( + <PageLayout + metaCopyrightYear={getPostPublishedDate(doc).year} + metaDescription={doc.description} + metaKeywords={doc.tags.map((slug) => getTagLabel(config, slug))} + metaTitle={`${doc.title}|${config.blog.siteName}`} + requiresSyntaxHighlight + config={config} + > + <body className="single"> + <GlobalHeader config={config} /> + <main className="main"> + <article className="post-single"> + <header className="post-header"> + <h1 className="post-title">{doc.title}</h1> + {doc.tags.length !== 0 && ( + <ul className="post-tags"> + {doc.tags.map((slug) => ( + <li className="tag"> + <a href={`/tags/${slug}/`}>{getTagLabel(config, slug)}</a> + </li> + ))} + </ul> + )} + </header> + <div className="post-content"> + <section id="changelog"> + <h2> + <a href="#changelog">更新履歴</a> + </h2> + <ol> + {doc.revisions.map((rev) => ( + <li className="revision"> + <time datetime={dateToString(rev.date)}> + {dateToString(rev.date)} + </time> + {`: ${rev.remark}`} + </li> + ))} + </ol> + </section> + { + // TODO: refactor + (doc.root.children[0] as Element).children + } + </div> + </article> + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/SlideListPage.tsx b/services/blog/nuldoc-src/pages/SlideListPage.tsx new file mode 100644 index 00000000..3d87d492 --- /dev/null +++ b/services/blog/nuldoc-src/pages/SlideListPage.tsx @@ -0,0 +1,42 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import SlidePageEntry from "../components/SlidePageEntry.tsx"; +import { Config } from "../config.ts"; +import { dateToString } from "../revision.ts"; +import { getPostPublishedDate } from "../generators/post.ts"; +import { SlidePage } from "../generators/slide.ts"; + +export default function SlideListPage( + slides: SlidePage[], + config: Config, +) { + const pageTitle = "スライド一覧"; + + return ( + <PageLayout + metaCopyrightYear={config.blog.siteCopyrightYear} + metaDescription="登壇したイベントで使用したスライドの一覧" + metaTitle={`${pageTitle}|${config.blog.siteName}`} + metaAtomFeedHref={`https://${config.blog.fqdn}/slides/atom.xml`} + config={config} + > + <body className="list"> + <GlobalHeader config={config} /> + <main className="main"> + <header className="page-header"> + <h1>{pageTitle}</h1> + </header> + {Array.from(slides).sort((a, b) => { + const ta = dateToString(getPostPublishedDate(a)); + const tb = dateToString(getPostPublishedDate(b)); + if (ta > tb) return -1; + if (ta < tb) return 1; + return 0; + }).map((slide) => <SlidePageEntry slide={slide} key={slide.uuid} />)} + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/SlidePage.tsx b/services/blog/nuldoc-src/pages/SlidePage.tsx new file mode 100644 index 00000000..fc11072d --- /dev/null +++ b/services/blog/nuldoc-src/pages/SlidePage.tsx @@ -0,0 +1,72 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import StaticScript from "../components/StaticScript.tsx"; +import { Config, getTagLabel } from "../config.ts"; +import { dateToString } from "../revision.ts"; +import { Slide } from "../slide/slide.ts"; +import { getPostPublishedDate } from "../generators/post.ts"; + +export default function SlidePage( + slide: Slide, + config: Config, +) { + return ( + <PageLayout + metaCopyrightYear={getPostPublishedDate(slide).year} + metaDescription={slide.title} + metaKeywords={slide.tags.map((slug) => getTagLabel(config, slug))} + metaTitle={`${slide.event} (${slide.talkType})|${config.blog.siteName}`} + requiresSyntaxHighlight + config={config} + > + <body className="single"> + <GlobalHeader config={config} /> + <main className="main"> + <article className="post-single"> + <header className="post-header"> + <h1 className="post-title">{slide.title}</h1> + {slide.tags.length !== 0 && ( + <ul className="post-tags"> + {slide.tags.map((slug) => ( + <li className="tag"> + <a href={`/tags/${slug}/`}>{getTagLabel(config, slug)}</a> + </li> + ))} + </ul> + )} + </header> + <div className="post-content"> + <section id="changelog"> + <h2> + <a href="#changelog">更新履歴</a> + </h2> + <ol> + {slide.revisions.map((rev) => ( + <li className="revision"> + <time datetime={dateToString(rev.date)}> + {dateToString(rev.date)} + </time> + {`: ${rev.remark}`} + </li> + ))} + </ol> + </section> + <canvas id="slide" data-slide-link={slide.slideLink} /> + <div> + <button id="prev" type="button">Prev</button> + <button id="next" type="button">Next</button> + </div> + <StaticScript + fileName="/slide.js" + type="module" + config={config} + /> + </div> + </article> + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/TagListPage.tsx b/services/blog/nuldoc-src/pages/TagListPage.tsx new file mode 100644 index 00000000..cdb83ea5 --- /dev/null +++ b/services/blog/nuldoc-src/pages/TagListPage.tsx @@ -0,0 +1,57 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config } from "../config.ts"; +import { TagPage } from "../generators/tag.ts"; + +export default function TagListPage( + tags: TagPage[], + config: Config, +) { + const pageTitle = "タグ一覧"; + + return ( + <PageLayout + metaCopyrightYear={config.blog.siteCopyrightYear} + metaDescription="タグの一覧" + metaTitle={`${pageTitle}|${config.blog.siteName}`} + config={config} + > + <body className="list"> + <GlobalHeader config={config} /> + <main className="main"> + <header className="page-header"> + <h1>{pageTitle}</h1> + </header> + {Array.from(tags).sort((a, b) => { + const ta = a.tagSlug; + const tb = b.tagSlug; + if (ta < tb) return -1; + if (ta > tb) return 1; + return 0; + }).map((tag) => ( + <article className="post-entry"> + <a href={tag.href}> + <header className="entry-header"> + <h2>{tag.tagLabel}</h2> + </header> + <footer className="entry-footer"> + {(() => { + const posts = tag.numOfPosts === 0 + ? "" + : `${tag.numOfPosts}件の記事`; + const slides = tag.numOfSlides === 0 + ? "" + : `${tag.numOfSlides}件のスライド`; + return `${posts}${posts && slides ? "、" : ""}${slides}`; + })()} + </footer> + </a> + </article> + ))} + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} diff --git a/services/blog/nuldoc-src/pages/TagPage.tsx b/services/blog/nuldoc-src/pages/TagPage.tsx new file mode 100644 index 00000000..02c484af --- /dev/null +++ b/services/blog/nuldoc-src/pages/TagPage.tsx @@ -0,0 +1,43 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import PostPageEntry from "../components/PostPageEntry.tsx"; +import SlidePageEntry from "../components/SlidePageEntry.tsx"; +import { Config, getTagLabel } from "../config.ts"; +import { getPostPublishedDate } from "../generators/post.ts"; +import { TaggedPage } from "../generators/tagged_page.ts"; + +export default function TagPage( + tagSlug: string, + pages: TaggedPage[], + config: Config, +) { + const tagLabel = getTagLabel(config, tagSlug); + const pageTitle = `タグ「${tagLabel}」一覧`; + + return ( + <PageLayout + metaCopyrightYear={getPostPublishedDate(pages[pages.length - 1]).year} + metaDescription={`タグ「${tagLabel}」のついた記事またはスライドの一覧`} + metaKeywords={[tagLabel]} + metaTitle={`${pageTitle}|${config.blog.siteName}`} + metaAtomFeedHref={`https://${config.blog.fqdn}/tags/${tagSlug}/atom.xml`} + config={config} + > + <body className="list"> + <GlobalHeader config={config} /> + <main className="main"> + <header className="page-header"> + <h1>{pageTitle}</h1> + </header> + {pages.map((page) => + "event" in page + ? <SlidePageEntry slide={page} key={page.uuid} /> + : <PostPageEntry post={page} key={page.uuid} /> + )} + </main> + <GlobalFooter config={config} /> + </body> + </PageLayout> + ); +} |
