More changes to structure and UI
This commit is contained in:
@@ -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
91
components/lists.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
21
components/quick-links.tsx
Normal file
21
components/quick-links.tsx
Normal 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;
|
||||
34
components/recent-posts.tsx
Normal file
34
components/recent-posts.tsx
Normal 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;
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user