turbopack and app router; very annoying to work with!

This commit is contained in:
2025-05-31 22:06:24 -04:00
parent 43229c4c47
commit 1cca454a75
35 changed files with 125 additions and 310 deletions

View File

@@ -0,0 +1,9 @@
export default function Container(props: { children?: React.ReactNode, ignore?: boolean }) {
if (props.ignore)
return <>{props.children}</>;
return (
<div className='container'>
{props.children}
</div>
);
}

View File

@@ -0,0 +1,24 @@
import Link from 'next/link';
import Pages from '../../../public/external.json';
function QuickLinks() {
return (
<div className='block'>
{
Object.entries(Pages).map(([title, link]) => {
const extern = link.match(/^http/) && `blue extern` || '';
return (
<Link
key={link}
href={link}
className={`${extern} link button`}>
{title}
</Link>
);
})
}
</div>
);
}
export default QuickLinks;

View File

@@ -0,0 +1,40 @@
import Link from "next/link";
import NotesInfo from '../../../public/notes.json';
function RecentNotes() {
const notes = Object.entries(NotesInfo)
.map(([slug, note]) => {
return {
slug,
title: note.title,
mtime: new Date(note.mtime)
}
})
.sort(
(a, b) => {
return b.mtime.getTime() - a.mtime.getTime();
}
);
return (
<div className='block'>
<h2>Recent Notes</h2>
<ul>
{notes?.slice(0, 5)
.map(({slug, title, mtime}) => {
return (
<li key={slug} >
<Link href={`/notes/${slug}`}>{title}</Link>
</li>
);
})
}
{
notes.length > 5 &&
<Link href='/notes'>More...</Link>
}
</ul>
</div>
);
}
export default RecentNotes;

View File

@@ -0,0 +1,52 @@
.container {
border-bottom-left-radius: 0.5rem;
border-bottom: 1px dashed var(--main-border-color);
border-left: 1px dashed var(--main-border-color);
padding-top: 1.25rem;
margin-left: 0.5rem;
}
.block {
margin: 0;
position: relative;
display: flex;
align-items: center;
}
.block+.block {
border-top: 1px dashed var(--main-border-color);
}
.block:first-of-type {
border-top-right-radius: 0.5rem;
}
.block:nth-of-type(2n) {
background-color: var(--table-even-color);
}
.block:nth-of-type(2n+1) {
background-color: var(--table-odd-color);
}
.postTitle {
flex: 1 1 60%;
padding: .25rem 0.75rem;
}
.postDate {
flex: 1 1;
display: inline-block;
text-align: right;
font-style: italic;
font-size: 1rem;
padding: .25rem 0.50rem;
}
.more {
text-align: right;
}
.more a {
text-decoration: none;
}

View File

@@ -0,0 +1,50 @@
import Link from "next/link";
import { toRelativeDate } from "../lib/date";
import style from './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).reverse();
if (!posts.length)
return <></>;
return (
<div className='block'>
<h2>Recent Posts</h2>
<div className={style.container}>
{posts?.slice(0, 10)
.map(([slug, post]: any, i: number) => {
return (
<PostBlock
key={slug}
slug={slug}
title={post.title}
otime={post.otime} />
);
})}
</div>
{
posts.length > 10 &&
<div className={style.more}>
<Link href='/posts' >More...</Link>
</div>
}
</div>
);
}
export default RecentPosts;

View File

@@ -0,0 +1,30 @@
.container {
text-align: center;
margin: auto;
background-color: var(--main-background-color);
}
.container .title {
border-bottom: 1px solid #FFFFFF;
max-width: 95%;
margin: auto;
}
.nav {
padding: 0.25rem 0.75rem;
font-size: 1.25rem;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
position: fixed;
bottom: 0;
z-index: 1000;
margin: 0;
height: 2.5rem;
max-height: 2.5rem;
min-height: 2.5rem;
min-width: 100%;
width: 100%;
background: linear-gradient(to bottom right, #1a3a15, #09351b) no-repeat center center fixed;
overflow-y: hidden;
overflow-x: auto;
white-space: nowrap;
}

View File

@@ -0,0 +1,68 @@
'use client'
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Fragment } from 'react';
import style from './title.module.css';
import SiteMap from '../../../public/sitemap.json';
import { Sites } from '../lib/site';
function createPathElements(ancestors: Array<{ name: string, path: string }>) {
let currentPath = '';
return ancestors.map((ancestor, id) => {
currentPath += `/${ancestor.path}`
return (
<Fragment key={currentPath} >
<Link href={currentPath}>{ancestor.name}</Link>
<> / </>
</Fragment>
);
});
}
export default function Title() {
const pagePath = usePathname();
const splitPath: Array<{ name: string, path: string }> = [];
// TODO(Paul): clean this up
let currRoot: Sites = SiteMap.pages;
let title: string | null = null;
if (pagePath && pagePath !== '/') {
const subPaths = pagePath.split('?')[0].split('#')[0].split('/');
for (const p of subPaths.slice(1, subPaths.length)) {
if (!p || !currRoot[p])
continue;
splitPath.push({ name: currRoot[p].title, path: p });
if (currRoot === undefined
|| currRoot[p] === undefined
|| currRoot[p].pages === undefined)
break;
currRoot = currRoot[p].pages!;
}
if (splitPath !== undefined && splitPath.length > 0)
title = splitPath.pop()!.name;
}
const pathElements = splitPath && createPathElements(splitPath) || <></>;
return (
<>
{/* <head>
<title>{title && `${title} | PaulW.XYZ` || 'PaulW.XYZ'}</title>
</head> */}
<div className={style.container}>
<h1 className={style.title}>
{title || 'PaulW.XYZ'}
</h1>
</div>
<div className={`${style.nav} h1`}>
{
title
? <><Link href='/'>PaulW.XYZ</Link> / {pathElements}{title}</>
: <>PaulW.XYZ /</>
}
</div>
</>
);
}