11import { GetStaticProps } from "next" ;
22import Image from "next/image" ;
33import { useState } from "react" ;
4- import z from "zod" ;
54
6- import { library } from "@/cms/content/library.json" ;
5+ import { Book } from "@/cms/models/Book" ;
6+ import { getBookRepository } from "@/cms/repositories" ;
77import { Heading } from "@/components/Heading" ;
88import { Link } from "@/components/Link" ;
99import { Text } from "@/components/Text" ;
1010import { Application } from "@/layouts/Application" ;
1111
12- const BookSchema = z . object ( {
13- title : z . string ( ) ,
14- author : z . string ( ) ,
15- readAt : z . iso . date ( ) ,
16- category : z . union ( [
17- z . literal ( "foundational" ) ,
18- z . literal ( "craft" ) ,
19- z . literal ( "mental-models" ) ,
20- z . literal ( "worldview" ) ,
21- z . literal ( "exploration" ) ,
22- ] ) ,
23- image : z . string ( ) ,
24- status : z . union ( [ z . literal ( "read" ) ] ) ,
25- language : z . union ( [ z . literal ( "en" ) , z . literal ( "es" ) ] ) ,
26- } ) ;
27-
28- type Book = z . infer < typeof BookSchema > ;
29-
3012type LibraryPageProps = {
3113 library : Record < Book [ "category" ] , Book [ ] > ;
3214} ;
3315
34- const toBook = ( data : unknown ) : Book => {
35- return BookSchema . parse ( data ) ;
36- } ;
37-
3816export function LibrarySection ( props : Readonly < React . PropsWithChildren > ) {
3917 return < div className = "LibrarySection" > { props . children } </ div > ;
4018}
@@ -50,6 +28,13 @@ export function LibrarySectionDescription(props: Readonly<React.PropsWithChildre
5028export function LibrarySectionBooks ( props : Readonly < { books : Book [ ] } > ) {
5129 const [ now ] = useState ( ( ) => Date . now ( ) ) ;
5230
31+ const yearsAgo = ( date : Date ) => {
32+ return new Intl . RelativeTimeFormat ( "en" , { numeric : "auto" } ) . format (
33+ - Math . floor ( ( now - date . getTime ( ) ) / ( 1000 * 60 * 60 * 24 * 30 * 12 ) ) ,
34+ "year" ,
35+ ) ;
36+ } ;
37+
5338 return (
5439 < ul className = "LibrarySection__Books" >
5540 { props . books . map ( ( book ) => {
@@ -71,14 +56,7 @@ export function LibrarySectionBooks(props: Readonly<{ books: Book[] }>) {
7156 < dd className = "LibrarySection__Book__Author" > { book . author } </ dd >
7257
7358 < dt className = "sr-only" > Read At</ dt >
74- < dd className = "LibrarySection__Book__Date" >
75- { /* Displays relative time - e.g, 1 year ago */ }
76- last read{ " " }
77- { new Intl . RelativeTimeFormat ( "en" , { numeric : "auto" } ) . format (
78- - Math . floor ( ( now - new Date ( book . readAt ) . getTime ( ) ) / ( 1000 * 60 * 60 * 24 * 30 * 12 ) ) ,
79- "year" ,
80- ) }
81- </ dd >
59+ < dd className = "LibrarySection__Book__Date" > last read { yearsAgo ( new Date ( book . readAt ) ) } </ dd >
8260 </ dl >
8361 </ li >
8462 ) ;
@@ -167,7 +145,7 @@ export default function LibraryPage(props: Readonly<LibraryPageProps>) {
167145}
168146
169147export const getStaticProps : GetStaticProps < LibraryPageProps > = async ( ) => {
170- const books = library . map ( toBook ) ;
148+ const books = getBookRepository ( ) . all ( ) ;
171149
172150 return {
173151 props : {
0 commit comments