More changes to structure and UI

This commit is contained in:
2022-04-27 21:55:18 -04:00
parent 3d4b1b4f54
commit 9d761d0d3d
22 changed files with 257 additions and 218 deletions

View File

@@ -1,22 +1,24 @@
import FuzzyBar from './fuzzy-bar';
import Meta from './meta';
import Title from './title';
// import FuzzyBar from './fuzzy-bar';
type layoutProps = {
type ChildrenType = JSX.Element | Array<ChildrenType>;
type LayoutProps = {
name: string,
title?: string,
children?: JSX.Element | JSX.Element[],
ancestors?: Array<{ name: string, path: string }>
children?: ChildrenType,
};
function Layout(props: layoutProps) {
function Layout({ name, title, children, ancestors }: LayoutProps) {
return (
<>
<Meta name={props.name} ancestors={props.ancestors} />
<Title title={props.title} name={props.name} ancestors={props.ancestors} />
<FuzzyBar />
<Meta name={name} ancestors={ancestors} />
<Title title={title} name={name} ancestors={ancestors} />
{/* <FuzzyBar /> */}
<div className='container'>
{props.children}
{children}
</div>
</>
);

91
components/lists.tsx Normal file
View File

@@ -0,0 +1,91 @@
import style from '../styles/lists.module.css';
import React, { ReactElement } from 'react';
interface listItem {
children?: listItem[] | string[];
url?: 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 {
title: record.title,
url: record.url,
children: children.length ? children : undefined,
description: record.description,
};
}
export function mapChild(obj: listItem | string, level: number) {
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)
return (
<>
<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))}
</div>
</section>
);
}

View File

@@ -1,16 +1,17 @@
import Head from 'next/head';
export default function Meta(props: { name: string, ancestors?: Array<{ name: string, path: string }> }) {
function Meta({name, ancestors}
: {name: string, ancestors?: Array<{ name: string, path: string }> }) {
const path = () => {
if (!props.ancestors)
return props.name;
if (!ancestors)
return name;
let path = '';
props.ancestors.map((obj) => {
ancestors.map((obj) => {
path = `${path}${obj.name} /`;
});
return `${path} ${props.name}`;
return `${path} ${name}`;
};
return (
@@ -18,4 +19,6 @@ export default function Meta(props: { name: string, ancestors?: Array<{ name: st
<title>PaulW.XYZ / {path()}</title>
</Head>
);
}
}
export default Meta;

View File

@@ -0,0 +1,21 @@
import Link from 'next/link';
import Pages from '../public/pages.json';
import style from '../styles/quick-links.module.css'
function QuickLinks() {
return (<>
<div className='h2'>Quick Links</div>
{
Pages.map((obj, i) => {
const extern = obj.link.match(/^http/) && `blue ${style.blueButton}` || '';
return (
<Link key={i} href={obj.link}>
<a className={`${extern} ${style.button} button`}>{obj.title}</a>
</Link>
);
})
}
</>);
}
export default QuickLinks;

View File

@@ -0,0 +1,34 @@
import Link from "next/link";
import date from "../util/date";
import { PostMeta } from "../util/slug";
import style from '../styles/recent-posts.module.css';
function RecentPosts({ postsMeta }: { postsMeta: PostMeta[] }) {
return (<>
<div className='h2'>Recent Posts</div>
<div className={style.container}>
{postsMeta?.slice(0, 10)
.map((post: any) => {
return <div className={style.block} key={post.slug}>
<Link href={`/posts/${post.slug}`}>
<a className={`${style.postTitle} h5`}>{post.title}</a>
</Link>
<span className={style.postDate}>
{date.prettyPrint(new Date(post.created_at))}
</span>
</div>
})}
</div>
{
postsMeta.length > 10 &&
<div className={style.more}>
<Link href='/posts'>
<a className='h5'>More...</a>
</Link>
</div>
}
</>
);
}
export default RecentPosts;

View File

@@ -7,42 +7,33 @@ type propsObj = {
ancestors?: Array<{ name: string, path: string }>
};
function Title(props: propsObj) {
const path = () => {
if (!props.ancestors)
return (<></>);
let currentPath = '';
return (<>
{
props.ancestors.map(ancestor => {
currentPath += `/${ancestor.path}`
return (
<>
<Link href={currentPath} key=''>
<a>{ancestor.name}</a>
</Link>
<> / </>
</>
);
})
}
</>
function createPathElements(ancestors: Array<{ name: string, path: string }>) {
let currentPath = '';
return ancestors.map((ancestor) => {
currentPath += `/${ancestor.path}`
return (
<>
<Link href={currentPath}>
<a>{ancestor.name}</a>
</Link>
<> / </>
</>
);
};
});
};
function Title({ name, title, ancestors }: propsObj) {
const pathElements = ancestors && createPathElements(ancestors) || <></>;
return (
<>
<h1 className={style.container}>
{props.title || props.name}
{title || name}
</h1>
<div className={style.nav + ' h1'}>
{
props.name === ''
? <>PaulW.XYZ / {props.name}</>
: <><Link href='/'><a>PaulW.XYZ</a></Link> / {path()}{props.name}</>
}
<div className={`${style.nav} h1`}>
{name
? <><Link href='/'><a>PaulW.XYZ</a></Link> / {pathElements}{name}</>
: <>PaulW.XYZ /</>}
</div>
</>
);