feat: add tina CMS; layouts
This commit is contained in:
parent
09f7530d4a
commit
662a461c3c
33 changed files with 13036 additions and 1243 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -35,4 +35,6 @@ yarn-error.log*
|
|||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
deploy-vars.sh
|
||||
deploy-vars.sh
|
||||
node_modules
|
||||
.env
|
10
content/books/Sex--Punishment.md
Normal file
10
content/books/Sex--Punishment.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: Sex & Punishment
|
||||
author: Eric Berkowitz
|
||||
stars: 3
|
||||
readDate: 2024-05-31T23:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/79ffd129-2325-45d0-826d-c6969a09e239'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/lqtuj9d7fdj1qw1lei01yby42h9z'
|
||||
tags: 'non-fiction, history'
|
||||
---
|
||||
|
10
content/books/a-night-to-remember.md
Normal file
10
content/books/a-night-to-remember.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
tags: 'non-fiction, classics, history'
|
||||
title: A Night To Remember
|
||||
author: Walter Lord
|
||||
stars: 3.5
|
||||
readDate: 2024-06-30T23:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/5192ee9e-ffb2-4c72-a7c3-8051d950d66f'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/pdwshwni6jyc7ivp55j6tsxzngfl'
|
||||
---
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
---
|
||||
title: Alice's Adventures in Wonderland
|
||||
title: Alice's Adventures in Wonderland
|
||||
author: Lewis Carroll
|
||||
stars: 3
|
||||
readDate: 2024
|
||||
url: https://app.thestorygraph.com/books/83b0e44a-06fe-4042-9d2d-e4f41244fb9c
|
||||
thumbnailUrl: https://cdn.thestorygraph.com/l83t3e6wh6tq7dqxbvrba34ee2nb
|
||||
tags: fiction, classics, fantasy
|
||||
---
|
||||
readDate: 2023-04-30T23:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/83b0e44a-06fe-4042-9d2d-e4f41244fb9c'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/l83t3e6wh6tq7dqxbvrba34ee2nb'
|
||||
tags: 'fiction, classics, fantasy'
|
||||
---
|
||||
|
||||
|
|
10
content/books/animal-farm.md
Normal file
10
content/books/animal-farm.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: Animal Farm
|
||||
author: George Orwell
|
||||
stars: 4
|
||||
readDate: 2023-01-01T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/f4b706d9-4ed9-4b15-85e0-2493581de818'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/jztibk5xvnynw7mh7hfw0orhbzuh'
|
||||
tags: 'fiction, classics, dystopian'
|
||||
---
|
||||
|
|
@ -2,8 +2,9 @@
|
|||
title: Cities That Shaped The Ancient World
|
||||
author: John Julius Norwich
|
||||
stars: 3.5
|
||||
readDate: 2024
|
||||
url: https://app.thestorygraph.com/books/20bc1ff4-56bb-4e88-a403-bc150d45f9d2
|
||||
thumbnailUrl: https://cdn.thestorygraph.com/i8znw2yrd6p4m76dx6rvyuyd48h2
|
||||
tags: non-fiction, history
|
||||
readDate: 2023-02-01T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/20bc1ff4-56bb-4e88-a403-bc150d45f9d2'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/i8znw2yrd6p4m76dx6rvyuyd48h2'
|
||||
tags: 'non-fiction, history'
|
||||
---
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
---
|
||||
title: "The Song of Achilles"
|
||||
title: The Song of Achilles
|
||||
author: Madline Miller
|
||||
stars: 2.5
|
||||
readDate: 2025/03/22
|
||||
url: https://app.thestorygraph.com/books/9202845d-26cd-4a85-b15f-408116117028
|
||||
thumbnailUrl: https://cdn.thestorygraph.com/m8cw3kb3qx4h2jl8kg0u4m3txhie
|
||||
tags: fiction, fantasy, romance
|
||||
readDate: 2025-03-22T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/9202845d-26cd-4a85-b15f-408116117028'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/m8cw3kb3qx4h2jl8kg0u4m3txhie'
|
||||
tags: 'fiction, fantasy, romance'
|
||||
---
|
||||
|
||||
This one really tailed off half-way through. I found the characters very one-dimensional (Patrcolus pines after Achilles, Achilles has muscles and can swing a sword fast), but the story took me at least up until the half-way mark. Weirdly I wasn't interested too much when the actual Iliad story line started to get going - maybe because I've heard it a million times before - and their essentially non-existent romance (more accurately an inch-deep obsession, I'd argue) didn't exactly inspire me to carry on reading.
|
||||
|
|
10
content/books/starmaker.md
Normal file
10
content/books/starmaker.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: Star Maker
|
||||
author: Olaf Stapledon
|
||||
stars: 4.5
|
||||
readDate: 2023-03-01T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/c1d60727-8e24-4a1f-9f0e-974d68a934d2'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/bln6q5k1v7ealnwss4msv0jixlhk'
|
||||
tags: 'fiction, classics, science fiction'
|
||||
---
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
---
|
||||
title: "Stasiland: Stories from Behind the Berlin Wall"
|
||||
title: 'Stasiland: Stories from Behind the Berlin Wall'
|
||||
author: Anna Funder
|
||||
stars: 4
|
||||
readDate: 2025/03/22
|
||||
url: https://app.thestorygraph.com/books/9202845d-26cd-4a85-b15f-408116117028
|
||||
thumbnailUrl: https://cdn.thestorygraph.com/gphzjvwbhr8d5agrieobx0yy2xhb
|
||||
tags: non-fiction, history, politics
|
||||
readDate: 2023-02-01T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/9202845d-26cd-4a85-b15f-408116117028'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/gphzjvwbhr8d5agrieobx0yy2xhb'
|
||||
tags: 'non-fiction, history, politics'
|
||||
---
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
title: Stray Reflections
|
||||
author: Muhammad Iqbal
|
||||
stars: 5
|
||||
readDate: 2025/03/22
|
||||
url:
|
||||
thumbnailUrl:
|
||||
tags: non-fiction, politics, philosophy
|
||||
readDate: 2023-03-01T00:00:00.000Z
|
||||
url: null
|
||||
thumbnailUrl: null
|
||||
tags: 'non-fiction, politics, philosophy'
|
||||
---
|
||||
|
||||
|
|
10
content/books/the-marmalade-diaries.md
Normal file
10
content/books/the-marmalade-diaries.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: The Marmalade Diaries
|
||||
author: Ben Aitken
|
||||
stars: 4.5
|
||||
readDate: 2023-01-01T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/406fe719-07de-44ba-b4e7-86714f638cf9'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/ou589mae0cxxup4cqq1mlnqdaj62'
|
||||
tags: non-fiction
|
||||
---
|
||||
|
10
content/books/the-midnight-library.md
Normal file
10
content/books/the-midnight-library.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: The Midnight Library
|
||||
author: Matt Haig
|
||||
stars: 4
|
||||
readDate: 2024-06-30T23:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/d9c7ed04-6148-4e01-a118-d96cba16f507'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/b9g1h8bhrqz7qs2fagzhsixbp6xy'
|
||||
tags: 'fiction, literary, science fiction'
|
||||
---
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
---
|
||||
title: To Be Taught, If Fortunate
|
||||
title: 'To Be Taught, If Fortunate'
|
||||
author: Becky Chambers
|
||||
stars: 4.5
|
||||
readDate: 2025/03/22
|
||||
url: https://app.thestorygraph.com/books/fca2631f-b3e2-4b9d-a2fd-4c1ec5e4d3f7
|
||||
thumbnailUrl: https://cdn.thestorygraph.com/8ep9zjc581zefkzfyhtizqjnz8u5
|
||||
tags: fiction, science fiction
|
||||
readDate: 2025-03-22T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/fca2631f-b3e2-4b9d-a2fd-4c1ec5e4d3f7'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/8ep9zjc581zefkzfyhtizqjnz8u5'
|
||||
tags: 'fiction, science fiction'
|
||||
---
|
||||
Really enjoyed this! It was reflective yet lighthearted. I also love this specific flavour of sci-fi, where vastly different species of aliens and worlds are thought up and articulated beautifully by the author.
|
||||
|
||||
Really enjoyed this! It was reflective yet lighthearted. I also love this specific flavour of sci-fi, where vastly different species of aliens and worlds are thought up and articulated beautifully by the author.
|
||||
|
|
11
content/books/when-the-moon-hits-your-eye.md
Normal file
11
content/books/when-the-moon-hits-your-eye.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
title: When the Moon Hits Your Eye
|
||||
author: John Scalzi
|
||||
stars: 2.5
|
||||
readDate: 2025-03-26T00:00:00.000Z
|
||||
url: 'https://app.thestorygraph.com/books/4f3c3b02-3d2b-4765-93ac-4656133bbec5'
|
||||
thumbnailUrl: 'https://cdn.thestorygraph.com/718cb49yqfu02zekeq22yl8lgm8v'
|
||||
tags: 'fiction, science fiction'
|
||||
---
|
||||
|
||||
Some interesting chapters in here exploring how governments and various public/private institutions could deal with the moon randomly turning to choose, but a lot of fluff in between them. Can't really recommend, unless you want to skip to the good bits like I did.
|
|
@ -2,7 +2,9 @@
|
|||
title: Attitudes to reading, and how mine have changed
|
||||
pubdate: 2025-03-18T00:00:00.000Z
|
||||
desc: I was discussing reading habits with my good friend Beth, specifically around reading multiple books at once vs. reading a single book at a time...
|
||||
tags: reading, books
|
||||
tags:
|
||||
- reading
|
||||
- books
|
||||
---
|
||||
I was discussing reading habits with my good friend Beth, specifically around reading multiple books at once vs. reading a single book at a time (we're both very members of the former group), and it got me thinking as to why there seems to me to be this split in reading habits, and where it might come from.
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
title: Migrating from GitHub to Forgejo
|
||||
pubdate: 2025-03-16T00:00:00.000Z
|
||||
desc: I recently moved all of my reposfrom GitHub to a self-hosted Forgejo instance running on my own servers.
|
||||
tags: tech, hosting
|
||||
tags:
|
||||
- tech
|
||||
- hosting
|
||||
---
|
||||
|
||||
I recently moved all of my repos (public and private) from GitHub to a self-hosted [Forgejo](https://forgejo.org/) instance running on my own servers.
|
||||
|
|
|
@ -3,7 +3,10 @@ title: Performance considerations when writing a TCP game server in dotnet
|
|||
pubdate: 2025-02-23T21:12:37.864Z
|
||||
moddate: 2025-03-21T21:12:47.864Z
|
||||
desc: While writing a TCP game server in dotnet for a hobby project, I learned a few ways to improve the efficiency and scalability of the server while running into some performance issues. Here's what I learned!
|
||||
tags: tech, programming, dotnet
|
||||
tags:
|
||||
- tech
|
||||
- programming
|
||||
- dotnet
|
||||
---
|
||||
|
||||
While writing a TCP game server in dotnet for a hobby project (check it out [here](https://github.com/AaronJY/GServer)), I learned a few ways to improve the efficiency and scalability of the server while running into some performance issues.
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
title: "Quickwrite: A reflection on Wintering by Katherine May"
|
||||
pubdate: 2025-03-09T00:00:00.000Z
|
||||
desc: "Katherine May draws a unique parallel in her book ‘Wintering’ between the coming of and living through the winter months, and those liminal times in your life – when a gap opens up underfoot and swallows us whole...."
|
||||
tags: books, reading
|
||||
tags:
|
||||
- books
|
||||
- reading
|
||||
---
|
||||
|
||||
Katherine May draws a unique parallel in her book ‘Wintering’ between the coming of and living through the winter months, and those liminal times in your life – when a gap opens up underfoot and swallows us whole. It’s never clear when such a gap appears to steal us away, and how long exactly we’ll spend in the liminality we fall into, and most of us claw at the walls in an attempt to scale up and out, back into the warm light of day – how things used to be. Katherine’s book is an account of how she learned to see it more as a wave to ride than a locked room to break free from. Her ultimate message is an argument to reframe it, or to see it for what it really is; not as a bleak, timeless realm devoid of hope and light, but of a necessary state we all find ourselves in at various points in our lives, and that this realm offers its own medicines for those who care to look. These seasonal and spiritual changes Katherine refers to as ‘Wintering’ – aptly a verb to articulate its ephemeral nature – serve much in the same way a good night’s sleep does: while a deep and peaceful sleep purges metabolic waste and toxins from our brains, a wintering can offer a more spiritual cleanse; a hibernation after a hot and unrelenting summer; a mirror held up in front to break our blind and frenzied sprint towards a goal we’ve long forgotten; a beloved teacher from our school days with a soft voice, reassuring smile and placations to calm our nerves.
|
|
@ -2,7 +2,9 @@
|
|||
title: Deploying aaronjy.me on a Google Storage bucket
|
||||
pubdate: 2024-05-01T00:00:00.000Z
|
||||
desc: "Google Cloud Storage is an effective solution for hosting static sites, offering a simple and scalable way to manage web assets. A manual deployment strategy involves four key steps: backing up existing files to a backup bucket, removing sensitive files for security, uploading the latest site files from the build directory, and invalidating Google’s global cache to ensure users access updated content."
|
||||
tags: tech, hosting
|
||||
tags:
|
||||
- tech
|
||||
- hosting
|
||||
---
|
||||
Google actually has [documentation](https://cloud.google.com/storage/docs/hosting-static-website) on how to deploy a static site to a storage bucket, but I wanted to talk about how I handle deployments, as Google doesn't covert that!
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
title: Supporting content file structure changes on a static site
|
||||
pubdate: 2024-03-18T16:47:32.150Z
|
||||
desc: Static site generators (SSGs) convert complex site sources into HTML, CSS, and JS, allowing flexible hosting options. While they offer benefits like speed and low costs, updating content can be challenging for non-technical users. A solution involves assigning unique identifiers to articles and creating a URL mapping file to simplify restructuring and managing content links.
|
||||
tags: tech
|
||||
tags:
|
||||
- tech
|
||||
---
|
||||
Static site generators (SSGs) are great. They take your complex site source and distil it down to the web's native language: HTML, CSS and JS. You can host your files anywhere: in cloud-native storage buckets; on low-cost CPanel hosting; on global CDNs; your old Lenovo ThinkPad in your cupboard running an Apache server that hasn't been patched since 2008; the list goes on. Wanna go further and throw away your CMS? Cool, you can use markdown files and a text editor as your CMS.
|
||||
|
13833
package-lock.json
generated
13833
package-lock.json
generated
File diff suppressed because it is too large
Load diff
13
package.json
13
package.json
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"name": "www-aaronjy-2024",
|
||||
"version": "1.6.3.0",
|
||||
"name": "www-aaronjy-me",
|
||||
"version": "1.7.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"dev": "TINA_PUBLIC_IS_LOCAL=true tinacms dev -c \"next dev\"",
|
||||
"build": "next build",
|
||||
"postbuild": "next-sitemap --config next-sitemap.config.cjs",
|
||||
"start": "next start",
|
||||
|
@ -17,13 +17,13 @@
|
|||
"dependencies": {
|
||||
"@highlightjs/cdn-assets": "^11.11.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"feather-icons": "^4.29.2",
|
||||
"highlight.js": "^11.11.0",
|
||||
"next": "^14.2.6",
|
||||
"next-seo": "^6.5.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"react-dom": "^18",
|
||||
"tinacms": "^2.7.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/preset-env": "^7.25.4",
|
||||
|
@ -32,6 +32,7 @@
|
|||
"@commitlint/config-conventional": "^19.1.0",
|
||||
"@testing-library/jest-dom": "^6.4.2",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@tinacms/cli": "^1.9.3",
|
||||
"@types/jest": "^29.5.12",
|
||||
"babel-jest": "^29.7.0",
|
||||
"eslint": "^9.9.0",
|
||||
|
|
2
public/admin/.gitignore
vendored
Normal file
2
public/admin/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
index.html
|
||||
assets/
|
34
src/components/Book/Book.jsx
Normal file
34
src/components/Book/Book.jsx
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { formatDate } from '@/lib/helpers'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
|
||||
function Book({ attributes, html }) {
|
||||
return (
|
||||
<>
|
||||
<h1>{attributes.title}<br /><small>by {attributes.author}</small></h1>
|
||||
<article>
|
||||
<NextSeo
|
||||
title={attributes.title} description={attributes.desc} openGraph={
|
||||
{
|
||||
title: attributes.title,
|
||||
description: attributes.desc,
|
||||
type: 'article',
|
||||
article: {
|
||||
publishedTime: attributes.pubdate ?? null
|
||||
}
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div>
|
||||
<Link href='./'>Back...</Link>
|
||||
{attributes.pubdate && <p>{formatDate(attributes.pubdate)}</p>}
|
||||
<div data-test='content' dangerouslySetInnerHTML={{ __html: html || "<p>(no review)</p>" }} />
|
||||
</div>
|
||||
</article>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default Book
|
|
@ -1,16 +1,14 @@
|
|||
import Image from 'next/image'
|
||||
|
||||
import style from './BookListItem.module.css'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function BookListItem ({ href, title, author, stars, readDate, url, thumbnailUrl, tags, review }) {
|
||||
export default function BookListItem({ href, title, author, stars, readDate, url, thumbnailUrl, tags, review }) {
|
||||
return (
|
||||
<div className={style.item}>
|
||||
<div className={style['image-container']}>
|
||||
<Link href={href}>
|
||||
<Image src={thumbnailUrl ?? '/img/book-placeholder.jpg'} alt={`Book cover for ${title}`} width={300} height={464} />
|
||||
</Link>
|
||||
</div>
|
||||
<Link href={href}>
|
||||
<div className={style['thumb']} style={{
|
||||
backgroundImage: `url(${thumbnailUrl ?? '/img/book-placeholder.jpg'})`
|
||||
}}></div>
|
||||
</Link>
|
||||
<div>
|
||||
<h2 className={style.heading}>
|
||||
<Link href={href}>{title}</Link>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.heading {
|
||||
|
@ -16,3 +15,12 @@
|
|||
/* font-weight: bold; */
|
||||
}
|
||||
|
||||
|
||||
.thumb {
|
||||
width: auto;
|
||||
height: 200px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 6px;
|
||||
}
|
|
@ -56,9 +56,7 @@ export function getStaticEntries (contentPath) {
|
|||
const directoryItems = fs.readdirSync(contentPath, { withFileTypes: true })
|
||||
return directoryItems.map((dirent) =>
|
||||
getMarkdownEntry(`${dirent.path}/${dirent.name}`)
|
||||
).sort((a, b) =>
|
||||
new Date(b.attributes.pubdate).getTime() - new Date(a.attributes.pubdate).getTime()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function getContentTags (contentPath) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import DefaultLayout from '@/layouts/DefaultLayout/DefaultLayout'
|
||||
import { getStaticEntryPaths, getStaticEntryProps } from '@/lib/content'
|
||||
import Article from '@/components/Article/Article'
|
||||
import Book from '@/components/Book/Book'
|
||||
|
||||
export const getStaticPaths = () => getStaticEntryPaths('./content/books')
|
||||
export const getStaticProps = (ctx) => getStaticEntryProps('./content/books', ctx)
|
||||
|
@ -9,7 +9,7 @@ export const getStaticProps = (ctx) => getStaticEntryProps('./content/books', ct
|
|||
export default function LibrarySingle ({ attributes, html }) {
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<Article attributes={attributes} html={html} />
|
||||
<Book attributes={attributes} html={html} />
|
||||
</DefaultLayout>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,22 +6,22 @@ import { NextSeo } from 'next-seo'
|
|||
|
||||
export const Title = 'Library'
|
||||
|
||||
export const getStaticProps = () => ({
|
||||
props: {
|
||||
bookEntries: getStaticEntries('./content/books')
|
||||
export const getStaticProps = () => {
|
||||
const bookEntries = getStaticEntries('./content/books')
|
||||
.sort((a, b) => {
|
||||
return b.attributes.readDate - a.attributes.readDate
|
||||
});
|
||||
|
||||
return {
|
||||
props: {
|
||||
// Silliness to make sure dates don't get passed to the
|
||||
// page function below as [object Object]
|
||||
bookEntries: JSON.parse(JSON.stringify(bookEntries))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const SORT_TITLE = 'title'
|
||||
const SORT_RATING = 'rating'
|
||||
|
||||
export default function Library ({ bookEntries }) {
|
||||
// const tags = getTags(bookEntries)
|
||||
|
||||
// const [sorter, setSorter] = useState(SORT_TITLE)
|
||||
|
||||
// console.log(bookEntries)
|
||||
}
|
||||
|
||||
export default function Library({ bookEntries }) {
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<NextSeo
|
||||
|
@ -36,37 +36,12 @@ export default function Library ({ bookEntries }) {
|
|||
<h1>{Title}</h1>
|
||||
|
||||
<section>
|
||||
<div className='form-group'>
|
||||
<label htmlFor='sortBy'>Sort by: </label>
|
||||
<select id='sortBy' name='sort-by'>
|
||||
<option value={SORT_TITLE}>Title (A-Z)</option>
|
||||
<option value={SORT_RATING}>Rating (5-0)</option>
|
||||
{/* <optgroup label="Genre">
|
||||
{Object.keys(tags).sort().map(tag => (
|
||||
<option>{tag}</option>
|
||||
))}
|
||||
</optgroup> */}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<Grid columns={4}>
|
||||
{bookEntries.map((entry, i) => (
|
||||
<Grid columns={5}>
|
||||
{bookEntries.map((entry, _) => (
|
||||
<BookListItem key={entry.attributes.title} {...entry.attributes} href={`/library/${entry.slug}`} />
|
||||
))}
|
||||
</Grid>
|
||||
</section>
|
||||
</DefaultLayout>
|
||||
)
|
||||
}
|
||||
|
||||
// function getTags (bookEntries) {
|
||||
// const tags = {}
|
||||
// for (const entry of bookEntries) {
|
||||
// const entryTags = entry.attributes.tags.split(', ')
|
||||
// for (const entryTag of entryTags) {
|
||||
// tags[entryTag] = tags[entryTag] ? tags[entryTag] + 1 : 1
|
||||
// }
|
||||
// }
|
||||
|
||||
// return tags
|
||||
// }
|
||||
}
|
|
@ -7,6 +7,9 @@ import StaticContentList from '@/components/StaticContentList/StaticContentList'
|
|||
export const getStaticProps = () => ({
|
||||
props: {
|
||||
postEntries: getStaticEntries('./content/writing')
|
||||
.sort((a, b) =>
|
||||
new Date(b.attributes.pubdate).getTime() - new Date(a.attributes.pubdate).getTime()
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
1
tina/.gitignore
vendored
Normal file
1
tina/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
__generated__
|
136
tina/config.js
Normal file
136
tina/config.js
Normal file
|
@ -0,0 +1,136 @@
|
|||
import { defineConfig } from "tinacms";
|
||||
|
||||
// Your hosting provider likely exposes this as an environment variable
|
||||
const branch =
|
||||
process.env.GITHUB_BRANCH ||
|
||||
process.env.VERCEL_GIT_COMMIT_REF ||
|
||||
process.env.HEAD ||
|
||||
"main";
|
||||
|
||||
export default defineConfig({
|
||||
branch,
|
||||
|
||||
// Get this from tina.io
|
||||
clientId: process.env.NEXT_PUBLIC_TINA_CLIENT_ID,
|
||||
// Get this from tina.io
|
||||
token: process.env.TINA_TOKEN,
|
||||
|
||||
build: {
|
||||
outputFolder: "admin",
|
||||
publicFolder: "public",
|
||||
},
|
||||
media: {
|
||||
tina: {
|
||||
mediaRoot: "",
|
||||
publicFolder: "public",
|
||||
},
|
||||
},
|
||||
// See docs on content modeling for more info on how to setup new content models: https://tina.io/docs/schema/
|
||||
schema: {
|
||||
collections: [
|
||||
{
|
||||
name: "books",
|
||||
label: "Library",
|
||||
path: 'content/books',
|
||||
match: {
|
||||
include: "*"
|
||||
},
|
||||
format: "md",
|
||||
fields: [
|
||||
{
|
||||
type: "string",
|
||||
name: "title",
|
||||
label: "Title",
|
||||
isTitle: true,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: "author",
|
||||
label: "Author",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
name: "stars",
|
||||
label: "Stars",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: 'datetime',
|
||||
name: "readDate",
|
||||
label: "Read date",
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: "url",
|
||||
label: "URL",
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: "thumbnailUrl",
|
||||
label: "Thumbnail URL",
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: "tags",
|
||||
label: "Tags",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
type: "rich-text",
|
||||
name: "body",
|
||||
label: "Body",
|
||||
isBody: true,
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "writing",
|
||||
label: "Writing",
|
||||
path: "content/writing",
|
||||
match: {
|
||||
include: "*"
|
||||
},
|
||||
format: "md",
|
||||
fields: [
|
||||
{
|
||||
type: "string",
|
||||
name: "title",
|
||||
label: "Title",
|
||||
isTitle: true,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: "datetime",
|
||||
name: "pubdate",
|
||||
label: "Publish Date",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
ui: {
|
||||
component: "textarea"
|
||||
},
|
||||
name: "desc",
|
||||
label: "Description",
|
||||
},
|
||||
{
|
||||
type: "string",
|
||||
name: "tags",
|
||||
label: "Tags",
|
||||
list: true
|
||||
},
|
||||
{
|
||||
type: "rich-text",
|
||||
name: "body",
|
||||
label: "Body",
|
||||
isBody: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
1
tina/tina-lock.json
Normal file
1
tina/tina-lock.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue