diff --git a/.gitignore b/.gitignore index b61c209..4cfe6a4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules/ dist/ .next/ .DS_Store - +public/posts.json \ No newline at end of file diff --git a/next.config.js b/next.config.js index 253e491..ca95034 100755 --- a/next.config.js +++ b/next.config.js @@ -6,11 +6,23 @@ module.exports = { webpack: (config, options) => { config.experiments = { asset: true }; + const { cachePostLinkData } = require('./util/post-cache'); + + config.plugins.push( + { + apply: (compiler) => { + compiler.hooks.initialize.tap('cachePostLinkDataInit', _ => { + cachePostLinkData(); + }); + } + } + ) + config.module.rules.push( { test: /\.ya?ml$/, use: 'js-yaml-loader', - + }, { test: /\.svg$/, diff --git a/pages/_app.tsx b/pages/_app.tsx index 85a3eb0..8122073 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -3,5 +3,5 @@ import 'normalize.css'; import '../styles/global.css'; export default function MyApp({ Component, pageProps }: AppProps) { - return + return } \ No newline at end of file diff --git a/pages/about.tsx b/pages/about.tsx index 3267276..5fbcf16 100644 --- a/pages/about.tsx +++ b/pages/about.tsx @@ -17,7 +17,7 @@ function AboutPage() { Got any questions, concerns, or issues? Feel free to contact me via my email: lambdapaul [at] pm [dot] me.
- {ReadmeMd.replace(/#{1,5} /g, (s: string) => {return `#${s}`})} + {ReadmeMd.replace(/#{1,5} /g, (s: string) => { return `#${s}` })}
) diff --git a/pages/index.tsx b/pages/index.tsx index 81475ec..fe2cc37 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -2,46 +2,44 @@ import Link from 'next/link'; import React from 'react'; import Layout from '../components/layout'; import Pages from '../public/pages.json'; -import cachePostLinkData from '../util/post-cache'; +import Posts from '../public/posts.json'; +import style from '../styles/home.module.css'; +import prettyDatePrint from '../util/pretty-date'; - -function HomePage({posts}: any) { - Pages.sort((x, y) => { return ('' + x.title).localeCompare(y.title) }); +function HomePage({ posts }: any) { + Pages.sort((x, y) => { return (x.title).localeCompare(y.title) }); return (
Welcome!
{ Pages.map(obj => { - return
+ return - {obj.title}{obj.link.match('^http*')? ' ↗' : ''} + {obj.title} -
+ }) }
-
Posts
-
- {posts?.map((post: any) => { - return
- [{ (new Date(post.last_updated)).toLocaleString()}] - {post.title} - -
+ + + {Posts?.map((post: any) => { + return + + + + })} - +
Posts Posted
+ + {post.title} + + {prettyDatePrint(new Date(post.created_at))}
) } -export async function getStaticProps() { - // make this webpack plugin - return { - props: {posts: cachePostLinkData()} - }; -} - export default HomePage; \ No newline at end of file diff --git a/pages/playlists.tsx b/pages/playlists.tsx index ae58cc2..81f16ab 100644 --- a/pages/playlists.tsx +++ b/pages/playlists.tsx @@ -12,7 +12,7 @@ function toListItem(record: Record): listItem | null { if (!record.title) return null; - let children: listItem[]= []; + let children: listItem[] = []; if (record.children) for (const child of record.children) { const lChild = toListItem(child); @@ -23,7 +23,7 @@ function toListItem(record: Record): listItem | null { return { title: record.title, url: record.url, - children: children.length? children : undefined, + children: children.length ? children : undefined, }; } @@ -38,7 +38,7 @@ function mapChild(obj: listItem, level: number) { let title: ReactElement; if (level >= 0 && level <= 3) - title = React.createElement(`h${level+3}`, {}, obj.title); + title = React.createElement(`h${level + 3}`, {}, obj.title); else title = React.createElement('strong', {}, obj.title); diff --git a/pages/posts/[page].tsx b/pages/posts/[page].tsx index 888e8db..19d3208 100644 --- a/pages/posts/[page].tsx +++ b/pages/posts/[page].tsx @@ -3,34 +3,36 @@ import { useRouter } from 'next/router'; import { getAllPosts, getPost } from '../../util/slug'; import ReactMarkdown from 'react-markdown'; import Image from 'next/image'; +import style from '../../styles/post.module.css'; -function Post({post} : any) { // eh +function Post({ post }: any) { // eh const router = useRouter(); - return ( - -
-
- {post.cover ? {`${post.title} : ''} - -
- {post.content} -
+ return (<> + +
+
+
+ {post.content} +
+
+
+ ); } -export async function getStaticProps({params}: any) { +export async function getStaticProps({ params }: any) { const post = getPost(params.page); return { - props: {post} + props: { post } }; } export async function getStaticPaths() { const posts = getAllPosts(); return { - paths: posts.map(post => { + paths: posts.map((post: any) => { return { params: { page: post.slug diff --git a/pages/posts/index.tsx b/pages/posts/index.tsx index 0508324..d6fe8b2 100644 --- a/pages/posts/index.tsx +++ b/pages/posts/index.tsx @@ -1,31 +1,30 @@ import Link from 'next/link'; import React from 'react'; import Layout from '../../components/layout'; -import Pages from '../../public/pages.json'; -import cachePostLinkData from '../../util/post-cache'; - +import Posts from '../../public/posts.json'; +import prettyDatePrint from '../../util/pretty-date'; function HomePage({posts}: any) { - Pages.sort((x, y) => { return ('' + x.title).localeCompare(y.title) }); + Posts.sort((x, y) => { return x.title.localeCompare(y.title) }); + // todo: create a table-like interface return ( - {posts.map((post: any) => { + <> +
+ Post Name Created on Last Updated +
+ {Posts.map((post: any) => { return
{post.title} -
[{ (new Date(post.last_updated)).toLocaleString()}]
+ {prettyDatePrint(new Date(post.created_at))} + {post.last_updated ? {prettyDatePrint(new Date(post.last_updated))} : ''}
})} +
) } -export async function getStaticProps() { - - return { - props: {posts: cachePostLinkData()} - }; -} - export default HomePage; \ No newline at end of file diff --git a/pages/recommended.tsx b/pages/recommended.tsx index c602460..ac35e62 100644 --- a/pages/recommended.tsx +++ b/pages/recommended.tsx @@ -1,6 +1,6 @@ import Layout from '../components/layout'; import rec from '../public/recommended.yaml'; -import {toListItem, mapChild} from '../util/resrec'; +import { toListItem, mapChild } from '../util/resrec'; function Recommended() { return ( diff --git a/pages/resources.tsx b/pages/resources.tsx index 3b46a4f..e880019 100644 --- a/pages/resources.tsx +++ b/pages/resources.tsx @@ -1,6 +1,6 @@ import Layout from '../components/layout'; import res from '../public/resources.yaml'; -import {toListItem, mapChild} from '../util/resrec'; +import { toListItem, mapChild } from '../util/resrec'; function Resources() { return ( diff --git a/public/posts.json b/public/posts.json deleted file mode 100644 index 238787d..0000000 --- a/public/posts.json +++ /dev/null @@ -1 +0,0 @@ -[{"title":"Thoughts on Baba Is You","slug":"thoughts-on-baba-is-you","last_updated":"2021-10-30T00:43:00.000Z"}] \ No newline at end of file diff --git a/styles/fuzzy.module.css b/styles/fuzzy.module.css index c24045b..fe6f177 100644 --- a/styles/fuzzy.module.css +++ b/styles/fuzzy.module.css @@ -11,6 +11,8 @@ .search { display: block; width: 100%; + max-width: 1018px; + margin: 0 auto; font-size: 2rem; background: linear-gradient(to bottom right, #406b39, #225546) no-repeat center center fixed; box-shadow: inset 0 4px 8px 0 rgba(0, 0, 0, 0.2); @@ -26,8 +28,9 @@ } .results { + max-width: 1018px; padding: 1rem; - margin: 2rem; + margin: 2rem auto; } .hyperlink { diff --git a/styles/global.css b/styles/global.css index 2cf2ed3..9c5d535 100644 --- a/styles/global.css +++ b/styles/global.css @@ -140,11 +140,6 @@ section { margin: 0.5rem; } -img { - border: 1px solid #FFFFFF; - border-radius: 1rem; -} - .lambda-logo { width: 256px; height: 256px; diff --git a/styles/home.module.css b/styles/home.module.css new file mode 100644 index 0000000..a561ac9 --- /dev/null +++ b/styles/home.module.css @@ -0,0 +1,22 @@ +.button { + padding: 0.2rem 1rem; + margin: 0.3rem 0.3rem; + background:#1a3a15; + color: rgba(255, 255, 255); + display: inline-block; + text-decoration: none; + transition: 100ms ease-in-out all; + border: 1px solid #ffffff; + border-radius: 0.5rem; +} + +.button:hover { + text-decoration: none; + background:#099945; +} + +.button:active { + text-decoration: none; + box-shadow: none; + transform: translate(1px, 1px); +} \ No newline at end of file diff --git a/styles/post.module.css b/styles/post.module.css new file mode 100644 index 0000000..1babb7f --- /dev/null +++ b/styles/post.module.css @@ -0,0 +1,16 @@ +.imageBlock { + position: absolute; + right: 0; + left: 0; + background-size: cover; + min-height: 100%; + background-attachment: fixed; +} + +.block { + background-color: rgba(13, 17, 23, 0.9); +} + +.spacer { + height: 5rem; +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 7d8da63..1362332 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,6 @@ "jsx": "preserve", "importHelpers": true }, - "include": ["next-env.d.ts", "shims.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "util/post-cache.js", "util/slug.js"], "exclude": ["node_modules"] } diff --git a/util/post-cache.d.ts b/util/post-cache.d.ts new file mode 100644 index 0000000..fb86317 --- /dev/null +++ b/util/post-cache.d.ts @@ -0,0 +1 @@ +export default function cachePostLinkData(): any; \ No newline at end of file diff --git a/util/post-cache.js b/util/post-cache.js new file mode 100644 index 0000000..87c102c --- /dev/null +++ b/util/post-cache.js @@ -0,0 +1,16 @@ +const fs = require('fs'); +const { getAllPosts } = require('./slug'); +const { join } = require('path'); + +const publicDir = join(process.cwd(), 'public'); + +module.exports = { + cachePostLinkData: () => { + const posts = getAllPosts(['title', 'slug', 'created_at', 'last_updated']); + fs.writeFile(`${publicDir}/posts.json`, JSON.stringify(posts), (e) => { + if (e) + console.error(e); + }); + return posts; + } +} \ No newline at end of file diff --git a/util/post-cache.ts b/util/post-cache.ts deleted file mode 100644 index dd5399b..0000000 --- a/util/post-cache.ts +++ /dev/null @@ -1,14 +0,0 @@ -import fs from 'fs'; -import { getAllPosts } from './slug'; -import { join } from 'path'; - -const publicDir = join(process.cwd(), 'public'); - -export default function cachePostLinkData() { - const posts = getAllPosts(['title', 'slug', 'last_updated']); - fs.writeFile(`${publicDir}/posts.json`, JSON.stringify(posts), (e) => { - if (e) - console.error(e); - }); - return posts; -} \ No newline at end of file diff --git a/util/pretty-date.ts b/util/pretty-date.ts new file mode 100644 index 0000000..9c34fc8 --- /dev/null +++ b/util/pretty-date.ts @@ -0,0 +1,50 @@ +const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' +]; + +const suffixes = ['','st','nd','rd','th']; + +export default function prettyDatePrint(date: Date) { + const now = new Date(); + const diff = now.getTime() - date.getTime(); + + let tdiff = Math.floor(diff/1000); + + if (tdiff < 60) { + return `${tdiff} seconds ago`; + } + + tdiff = Math.floor(tdiff/60); + if (tdiff < 60) { + return `${tdiff} minute${tdiff === 1? '' : 's'} ago`; + } + + tdiff = Math.floor(tdiff/60); + if (tdiff < 24) { + return `${tdiff} hour${tdiff === 1? '' : 's'} ago`; + } + if (tdiff < 48) { + return `Yesterday`; + } + + const year = date.getFullYear(); + const month = months[date.getMonth()]; + const day = date.getDate(); + let sfx; + if (day >= 1 && day <= 3) + sfx = suffixes[day]; + else + sfx = suffixes[4]; + return `${day}${sfx} ${month} ${year}`; +} \ No newline at end of file diff --git a/util/resrec.tsx b/util/resrec.tsx index 7e66832..7535cfa 100644 --- a/util/resrec.tsx +++ b/util/resrec.tsx @@ -31,16 +31,16 @@ export function toListItem(record: Record): listItem | null { children = schildren; } else { - children = [...lchildren, ... schildren.map((s: string): listItem => { + children = [...lchildren, ...schildren.map((s: string): listItem => { return { title: s }; - }) ]; + })]; } } return { title: record.title, url: record.url, - children: children.length? children : undefined, + children: children.length ? children : undefined, description: record.description, }; } diff --git a/util/slug.d.ts b/util/slug.d.ts new file mode 100644 index 0000000..4d89cb7 --- /dev/null +++ b/util/slug.d.ts @@ -0,0 +1,4 @@ +interface Post { slug?: string, rawslug?: string, content?: string, title?: string }; + +export function getAllPosts(filter: Array = []): Post[]; +export function getPost(rawslug: string, filter: Array = []): Post; \ No newline at end of file diff --git a/util/slug.ts b/util/slug.js similarity index 66% rename from util/slug.ts rename to util/slug.js index 6785aa6..d57401a 100644 --- a/util/slug.ts +++ b/util/slug.js @@ -1,10 +1,10 @@ -import fs from 'fs' -import matter from 'gray-matter'; -import { join } from 'path'; +const fs = require('fs'); +const matter = require('gray-matter'); +const { join } = require('path'); const postsDirectory = join(process.cwd(), 'posts'); -export function getPost(rawslug: string, filter: Array = []) { +function getPost(rawslug, filter = []) { const slug = rawslug.replace(/\.md$/, ''); const path = join(postsDirectory, `${slug}.md`); const file = fs.readFileSync(path, 'utf-8'); @@ -16,7 +16,7 @@ export function getPost(rawslug: string, filter: Array = []) { if (filter.length === 0) return { ...data, content, slug, rawslug }; - let post: { slug?: string, rawslug?: string, content?: string, title?: string } | any = {}; + let post = {}; for (const [_, entry] of filter.entries()) { if (entry === 'slug') post[entry] = slug; @@ -27,8 +27,6 @@ export function getPost(rawslug: string, filter: Array = []) { if (entry === 'content') post[entry] = content; - - if (typeof data[entry] !== 'undefined') { post[entry] = data[entry] } @@ -36,12 +34,14 @@ export function getPost(rawslug: string, filter: Array = []) { return post; } -export function getAllPosts(filter: Array = []) { +function getAllPosts(filter = []) { const files = fs.readdirSync(postsDirectory); return files - .filter(c => !c.match(/^\./)) - .map(file => { - return getPost(file, filter) - }); -} \ No newline at end of file + .filter(c => !c.match(/^\./)) + .map(file => { + return getPost(file, filter) + }); +} + +module.exports = { getAllPosts, getPost }; \ No newline at end of file