Add programming-resources; swi->generic Nintendo;

Remove custom html from markdown, clean-up UI (again)

Signed-off-by: Paul W. <lambdapaul@protonmail.com>
This commit is contained in:
2024-02-13 18:01:07 -05:00
parent dc86590e6a
commit e3c70632e2
28 changed files with 392 additions and 304 deletions

13
components/container.tsx Normal file
View File

@@ -0,0 +1,13 @@
export type ChildrenType = JSX.Element | Array<ChildrenType>;
function Container(props: { children?: ChildrenType, ignore?: boolean }) {
if (props.ignore)
return <>{props.children}</>;
return (
<div className='container'>
{props.children}
</div>
);
}
export default Container;

View File

@@ -1,25 +1,18 @@
import Title from './title';
type ChildrenType = JSX.Element | Array<ChildrenType>;
import Container, { ChildrenType } from './container';
type LayoutProps = {
children?: ChildrenType,
removeContainer?: boolean,
};
function Container(props: {children?: ChildrenType, ignore?: boolean}) {
if (props.ignore)
return <>{props.children}</>;
return <div className='container'>
{props.children}
</div>;
}
function Layout(props : LayoutProps) {
function Layout(props: LayoutProps) {
return (
<>
<Title />
<Container ignore={props.removeContainer}>{props.children}</Container>
<Container ignore={props.removeContainer}>
{props.children}
</Container>
</>
);
}

View File

@@ -1,103 +0,0 @@
import style from '../styles/lists.module.css';
import React, { ReactElement } from 'react';
export interface listItem {
[x: string]: any;
children?: listItem[] | string[];
url?: string;
type?: string;
title: string;
description?: string;
};
export function toListItem(record: Record<string, any>): listItem | null {
if (!record.title)
return null;
let children: listItem[] | string[] = [];
if (Array.isArray(record.children) && record.children.length) {
let lchildren: listItem[] = [];
let schildren: string[] = [];
for (const child of record.children) {
if (typeof child === 'string') {
schildren.push(child);
continue;
}
const lChild = toListItem(child);
if (lChild)
lchildren.push(lChild);
}
if (!lchildren.length) {
children = schildren;
}
else {
children = [...lchildren, ...schildren.map((s: string): listItem => {
return { title: s };
})];
}
}
return Object.assign(record, {
title: record.title,
url: record.url,
children: children.length ? children : undefined,
type: record.type?.length ? record.type : undefined,
description: record.description,
});
}
export function mapChild(
obj: listItem | string,
level: number,
typeMap? : Record<string, (o: listItem) => JSX.Element>
) {
if (typeof obj === 'string') {
if (obj === '')
return <></>
return <span className={style.listItem}>{obj}</span>
}
if (obj.title === '')
return <></>
const desc = obj.description
? <span className={style.listItemDesc}>{obj.description}</span>
: <></>;
if (obj.url)
return (
<>
<span className={style.listItem}><a href={obj.url}>{obj.title}</a></span>
{desc}
</>);
if (!obj.children) {
let cb;
if (obj.type && typeMap) {
cb = typeMap[obj.type]
}
return cb
? cb(obj)
: (<><span className={style.listItem}>{obj.title}</span>{desc}</>);
}
let title: ReactElement;
if (level >= 0 && level <= 4)
title = React.createElement(`h${level + 2}`, {}, obj.title);
else
title = React.createElement('strong', {}, obj.title);
return (
<section className={level < 4 && `block ${style.block}` || ''}>
{title}
{obj.description ? <p className={style.desc}>{obj.description}</p> : <></>}
<div>
{obj.children.map(l => mapChild(l, level + 1, typeMap))}
</div>
</section>
);
}

View File

@@ -4,12 +4,17 @@ import Pages from '../public/external.json';
function QuickLinks() {
return (
<div className='block'>
<div className='h2'>Quick Links</div>
<h2>Quick Links</h2>
{
Object.entries(Pages).map(([title, link], i) => {
const extern = link.match(/^http/) && `blue extern` || '';
return (
<Link key={i} href={link} className={`${extern} link button`}>{title}</Link>
<Link
key={i}
href={link}
className={`${extern} link button`}>
{title}
</Link>
);
})
}

View File

@@ -2,22 +2,29 @@ import Link from "next/link";
import NotesInfo from '../public/notes.json';
function RecentNotes() {
const notes = Object.entries(NotesInfo);
const notes = Object.entries(NotesInfo).reverse();
return (
<div className='block'>
<div className='h2'>Recent Notes</div>
{notes?.slice(0, 10)
.map(([slug, note]: any) => {
return <Link key={slug} href={`/notes/${slug}`} className={`button link`}>{note.title}</Link>
<ul className='block'>
<h2>Recent Notes</h2>
{notes?.slice(0, 5)
.map(([slug, note]: any, i: number) => {
return (
<li
key={i}
>
<Link
href={`/notes/${slug}`}>
{note.title}
</Link>
</li>
);
})
}
{
notes.length > 10 &&
<div>
<Link href='/notes' className='h5'>More...</Link>
</div>
notes.length > 5 &&
<Link href='/notes'>More...</Link>
}
</div>
</ul>
);
}

View File

@@ -1,34 +1,46 @@
import Link from "next/link";
import date from "../lib/date";
import { toRelativeDate } from "../lib/date";
import style from '../styles/recent-posts.module.css';
import PostsInfo from '../public/posts.json';
function PostBlock({ slug, otime, title }: { slug: string, otime: string, title: string }) {
return (
<div className={style.block}>
<span className={style.postDate}>
{toRelativeDate(new Date(otime))}
</span>
<div className={style.postTitle}>
<Link href={`/posts/${slug}`}>
{title}
</Link>
</div>
</div>
);
}
function RecentPosts() {
const posts = Object.entries(PostsInfo);
const posts = Object.entries(PostsInfo).reverse();
if (!posts.length)
return <></>;
return (
<div className='block'>
<div className='h2'>Recent Posts</div>
<h2>Recent Posts</h2>
<div className={style.container}>
{posts?.slice(0, 10)
.map(([slug, post]: any) => {
return <div className={style.block} key={post.slug}>
<span className={style.postDate}>
{date.toRelativeDate(new Date(post.otime))}
</span>
<div className={style.postTitle}>
<Link href={`/posts/${slug}`}>
{post.title}
</Link>
</div>
</div>
.map(([slug, post]: any, i: number) => {
return (
<PostBlock
key={i}
slug={slug}
title={post.title}
otime={post.otime} />
);
})}
</div>
{
posts.length > 10 &&
<div className={style.more}>
<Link href='/posts' className='h5'>More...</Link>
<Link href='/posts' >More...</Link>
</div>
}
</div>

View File

@@ -17,7 +17,7 @@ function createPathElements(ancestors: Array<{ name: string, path: string }>) {
</>
);
});
};
}
function Title() {
@@ -31,10 +31,12 @@ function Title() {
const subPaths = pagePath.split('/');
for (const p of subPaths.slice(1, subPaths.length)) {
splitPath.push({ name: currRoot[p].title, path: p });
if (currRoot === undefined
|| currRoot[p] === undefined
|| currRoot[p].subpages !== undefined)
currRoot = currRoot[p].subpages!;
|| currRoot[p].subpages === undefined)
break;
currRoot = currRoot[p].subpages!;
}
if (splitPath !== undefined && splitPath.length > 0)
title = splitPath.pop()!.name;
@@ -53,9 +55,11 @@ function Title() {
</h1>
</div>
<div className={`${style.nav} h1`}>
{title
? <><Link href='/'>PaulW.XYZ</Link> / {pathElements}{title}</>
: <>PaulW.XYZ /</>}
{
title
? <><Link href='/'>PaulW.XYZ</Link> / {pathElements}{title}</>
: <>PaulW.XYZ /</>
}
</div>
</>
);