Skip to content

Commit

Permalink
add scaffolding for now page
Browse files Browse the repository at this point in the history
  • Loading branch information
igor47 committed Mar 17, 2024
1 parent 8faa3d0 commit 399578f
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 89 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"bootstrap": "^5.3.3",
"clsx": "^2.1.0",
"dayjs": "^1.11.10",
"eslint": "^8.57.0",
"eslint-config-next": "^14.1.3",
Expand Down
23 changes: 23 additions & 0 deletions posts/now-march-2024.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: 'Now: March 2024'
date: 2024-03-17
slug: now-march-2024
description: |
Now page for March 2024
image: /images/rr-jira-pica.png
isNowPage: true
---

I'm finally getting around to making a [now page](https://nownownow.com/about).
I've been meaning to do this for a while, ever since I heard about `now` pages from [Raph Lee](https://www.linkedin.com/in/raphaeltlee/).
Thanks as always, Raph!

### Work ###

I've been spending a lot of time these days working.
In January, I began a contract with [Rock Rabbit](https://rockrabbit.ai) to help them with their infrastructure.
Rock Rabbit (RR)'s mission is to accelerate building electrification.
Buildings are a large portion of overall carbon emissions, up there with transportation and industry.
(I am considering power generation to be


Binary file added public/images/me-sailing.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/rr-jira-pica.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
174 changes: 120 additions & 54 deletions src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,127 @@ import Head from 'next/head'
import Image from 'next/image'
import Link from 'next/link'

import { Linkedin, Github, Headphones, House, ArrowReturnLeft, ChevronBarUp } from 'react-bootstrap-icons'
import { clsx } from 'clsx'
import { Linkedin, Github, Headphones, House, ArrowReturnLeft, ChevronBarUp, CalendarCheck, PersonCircle } from 'react-bootstrap-icons'

import Me from '../../public/images/me.jpg'
import Myhead from '../../public/images/myhead.jpg'
import MeHero from '../../public/images/me-sailing.jpg'
import { useRouter } from 'next/router'

function Socials() {
return (
<div className="d-flex flex-row justify-content-center py-md-2 border-md-bottom">
<a href="https://github.com/igor47" className="my-0 mx-2 link-secondary">
<Github size="20px" title="My Github" />
</a>

<a href="https://www.linkedin.com/in/igor47" className="my-0 mx-2 link-secondary">
<Linkedin size="20px" title="Professional profile" />
</a>

<a href="https://www.last.fm/user/igor47" className="my-0 mx-2 link-secondary">
<Headphones size="20px" title="What I'm Listening To" />
</a>
</div>
)
}

function FaceImg() {
return (
<Image
src={Me}
alt="My Face"
width="134"
height="134"
sizes="(max-width: 576px) 30vw, 20vw"
className="rounded-circle border border-2 border-secondary"
style={{ objectFit: "cover", objectPosition: "left", overflow: "hidden" }}
/>
)
}

function NavLinks() {
const router = useRouter();
const curPath = router.pathname;

const linkClsx = (path: string) => clsx(
"py-1 py-md-2",
{"link-secondary": curPath !== path }, { "link-dark": curPath === path });

return (
<div id="Nav" className="d-flex flex-column ps-2 ps-md-0 py-md-2">
<Link href="/" className={ linkClsx("/") }>
<House size="30" className="my-0 mx-2" />
<span className="align-baseline">Home</span>
</Link>

<Link href="/about" className={ linkClsx("/about") }>
<PersonCircle size="30" className="my-0 mx-2" />
<span className="align-baseline">About</span>
</Link>

<Link href="/now" className={ linkClsx("/now") }>
<CalendarCheck size="30" className="my-0 mx-2" />
<span className="align-baseline">Now</span>
</Link>
</div>
)
}


function Nav() {
return (
<div className="d-flex flex-row flex-md-column">
<div id="Info" className="d-flex flex-column justify-content-center">
<Link href="/" className="link-secondary align-self-center">
<FaceImg />
</Link>

<div className="d-flex flex-column justify-content-center">
<h3 className="mx-auto text-nowrap">
<Link href="/about" className="link-dark">Igor Serebryany</Link>
</h3>
<div className="mx-auto text-secondary d-none d-md-block">Software & Hardware</div>
</div>

<Socials />
</div>

<div className="d-flex align-items-center justify-content-center ps-2 ps-md-0 py-md-2">
<NavLinks />
</div>
</div>
)
}

function Footer() {
return (
<div className="d-flex justify-content-center border-top border-2 py-2 mt-2 border-md-0 py-md-4 mt-md-4 justify-content-md-left ps-md-5">
<Link href="/" className="link-secondary px-3 border-end border-2">
<ArrowReturnLeft size="24" title="Return" />
<House size="24" title="Home" />
</Link>

<a href="#top" className="link-secondary px-3 border-end border-2"
onClick={(e) => {
e.preventDefault();
window.scrollTo({ top: 0, behavior: 'smooth' });
}}
>
<ChevronBarUp size="24" />
</a>

<div className="text-secondary px-3">
Drop me a line! <span className="text-primary">igor47@</span>
</div>
</div>
)

}

export default function Layout({ children }: { children: ReactNode }) {
const heroUrl = (new URL(MeHero.src, "https://igor.moomers.org")).toString();

return (
<>
<Head>
Expand All @@ -22,7 +137,7 @@ export default function Layout({ children }: { children: ReactNode }) {
<meta property="og:type" content="website" key="type" />
<meta property="og:title" content="Igor47 - Home" key="title" />
<meta property="og:description" content="Igor's internet home page and blog" key="description" />
<meta property="og:image" content={`https://igor47.com${Myhead.src}`} key="image" />
<meta property="og:image" content={heroUrl} key="image" />

<script defer data-api="/api/event" data-domain="igor.moomers.org" src="/js/script.js"></script>

Expand All @@ -37,38 +152,7 @@ export default function Layout({ children }: { children: ReactNode }) {
<div className="container-fluid">
<div className="row pt-2">
<div className="col-12 col-md-3">
<div className="d-flex flex-row flex-md-column">
<Link href="/" className="link-secondary align-self-center"><Image
src={Me}
alt="My Face"
width="134"
height="134"
sizes="(max-width: 576px) 30vw, 20vw"
className="rounded-circle border border-2 border-secondary"
style={{ objectFit: "cover", objectPosition: "left", overflow: "hidden" }}
/></Link>

<div className="d-flex flex-column justify-content-center ps-4 ps-md-0 pt-md-4">
<h3 className="mx-auto text-nowrap">
<Link href="/about" className="link-dark">Igor Serebryany</Link>
</h3>
<div className="mx-auto text-secondary">Software & Hardware</div>

<div className="d-flex justify-content-center flex-row pt-2">
<a href="https://github.com/igor47" className="my-0 mx-2 link-secondary">
<Github size="24px" title="My Github" />
</a>

<a href="https://www.linkedin.com/in/igor47" className="my-0 mx-2 link-secondary">
<Linkedin size="24px" title="Professional profile" />
</a>

<a href="https://www.last.fm/user/igor47" className="my-0 mx-2 link-secondary">
<Headphones size="24px" title="What I'm Listening To" />
</a>
</div>
</div>
</div>
<Nav />
</div>

<div
Expand All @@ -80,25 +164,7 @@ export default function Layout({ children }: { children: ReactNode }) {
</div>
</div>

<div className="d-flex justify-content-center border-top border-2 py-2 mt-2 border-md-0 py-md-4 mt-md-4 justify-content-md-left ps-md-5">
<Link href="/" className="link-secondary px-3 border-end border-2">
<ArrowReturnLeft size="24" title="Return" />
<House size="24" title="Home" />
</Link>

<a href="#top" className="link-secondary px-3 border-end border-2"
onClick={(e) => {
e.preventDefault();
window.scrollTo({ top: 0, behavior: 'smooth' });
}}
>
<ChevronBarUp size="24" />
</a>

<div className="text-secondary px-3">
Drop me a line! <span className="text-primary">igor47@</span>
</div>
</div>
<Footer />
</>
)
}
35 changes: 28 additions & 7 deletions src/lib/posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@ import { readdirSync } from 'node:fs';
import { join } from 'node:path';
import matter from 'gray-matter';

import rehypeRaw from 'rehype-raw'
import rehypePrism from '@mapbox/rehype-prism'
import rehypeFormat from 'rehype-format'
import rehypeSlug from 'rehype-slug'
import rehypeStringify from 'rehype-stringify'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {unified} from 'unified'

import { bootstrapize } from './bootstrap'

const POSTS_DIR = join(process.cwd(), 'posts')
type Post = {
export type Post = {
id: string,
fullPath: string,
date: Date,
Expand All @@ -13,9 +24,10 @@ type Post = {
draft: boolean,
description: string | null,
image: string | null,
isNowPage: boolean,
}

function getPosts(postsDir = POSTS_DIR) {
export function getPosts(postsDir = POSTS_DIR) {
// Get file names under /posts
const fileNames = readdirSync(postsDir);
const posts: Array<Post> = []
Expand Down Expand Up @@ -64,16 +76,25 @@ function getPosts(postsDir = POSTS_DIR) {
image: matterResult.data.image || null,
content: matterResult.content,
draft: matterResult.data.draft || false,
isNowPage: !!matterResult.data.isNowPage,
});
}

return posts.sort((a, b) => b.date.valueOf() - a.date.valueOf());
}

export {
getPosts,
}
export async function makePostBody(post: Post) {
return unified()
.use(remarkParse)
.use(remarkRehype, { allowDangerousHtml: true })
// raw html support
.use(rehypeRaw)
// @ts-expect-error -- this has some kind of typing issue
.use(rehypePrism, { ignoreMissing: true })
.use(rehypeFormat)
.use(rehypeSlug)
.use(bootstrapize)
.use(rehypeStringify)
.process(post.content)

export type {
Post,
}
6 changes: 4 additions & 2 deletions src/pages/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ export default function About() {
<Head>
<title>Igor47 - About</title>

<meta property="og:title" content="Igor Serebryany" key="title" />
<meta name="description" content="About Me, Igor Serebryany" key="description" />

<meta property="og:title" content="Igor Serebryany" key="title" />
<meta property="og:url" content="https://igor.moomers.org/about" key="url" />

<meta property="og:type" content="profile" key="type" />
<meta property="og:profile:first_name" content="Igor" />
<meta property="og:profile:last_name" content="Serebryany" />
Expand All @@ -19,7 +21,7 @@ export default function About() {
<div className="row mb-3">
<div className="col-6 col-lg-5 d-flex flex-column justify-content-center">
<img
src="/images/me_hero.jpg"
src="/images/me-sailing.jpg"
alt="Igor Serebryany"
className="rounded"
style={{
Expand Down
21 changes: 18 additions & 3 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default function Home({ posts }: { posts: Array<Post> }) {
return (<>
<Head>
<title>Igor47 - Home</title>
<meta property="og:url" content="https://igor.moomers.org/" key="url" />
</Head>

<main>
Expand Down Expand Up @@ -60,17 +61,31 @@ export default function Home({ posts }: { posts: Array<Post> }) {
}

export async function getStaticProps() {
const posts = getPosts()
let posts = getPosts()

// generate rss feeds
generateFeed(posts)

// treat the latest now page specially
const nows = posts.filter(post => post.isNowPage)
nows.sort((a, b) => a.date.getTime() - b.date.getTime())
const now = nows[0]

// exclude now page
posts = posts.filter(post => post.slug !== now.slug)

// potentially exclude drafts
if (process.env.NODE_ENV !== 'development') {
posts = posts.filter(post => !post.draft)
}

return {
props: {
posts: posts.filter(post => process.env.NODE_ENV === 'development' || !post.draft).map(post => ({
posts: posts.map(post => ({
...post,
date: post.date.toISOString(),
}))
})),
now: now.slug,
}
}
}
Loading

0 comments on commit 399578f

Please sign in to comment.