diff --git a/package.json b/package.json index 7c7021b..ca744a0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "notes blog", "type": "module", - "version": "4.28.0", + "version": "4.29.0", "repository": { "type": "git", "url": "https://github.com/antoniwan/notes.git" diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 4b3e1b4..de8a48f 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -58,6 +58,9 @@ import pkg from '../../package.json'; 🧠 Writing Insights + 📚 Book Library (for reference) 🏷️ Tag Analytics @@ -84,6 +87,15 @@ import pkg from '../../package.json'; 🌀 BlueSky + + 🧵 + Threads + book.status === 'read').length, + currentlyReadingCount: books.filter((book) => book.status === 'in-progress').length, + toReadCount: books.filter((book) => book.status === 'to-read').length, +}; diff --git a/src/data/navigation.ts b/src/data/navigation.ts index 49b2965..ae218eb 100644 --- a/src/data/navigation.ts +++ b/src/data/navigation.ts @@ -42,6 +42,11 @@ export const mainNavigation: NavigationItem[] = [ label: 'Tag Analytics', icon: '🏷️', }, + { + href: '/library/books', + label: 'Book Library', + icon: '📚', + }, { href: '/api/', label: 'Public API', diff --git a/src/pages/about.astro b/src/pages/about.astro index e9d4c68..5c2f2bd 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -105,6 +105,9 @@ import PageLayout from '../layouts/PageLayout.astro'; rel="noopener noreferrer">BlueSky — my social brain +
  • + 📚 Book library (for reference) — the shelves behind these notes +
  • diff --git a/src/pages/library.astro b/src/pages/library.astro new file mode 100644 index 0000000..05d04cd --- /dev/null +++ b/src/pages/library.astro @@ -0,0 +1,190 @@ +--- +import PageLayout from '../layouts/PageLayout.astro'; +import { books, libraryStats } from '../data/library'; +import type { Book } from '../data/library'; + +const readBooks = books.filter((book) => book.status === 'read'); +const inProgressBooks = books.filter((book) => book.status === 'in-progress'); +const toReadBooks = books.filter((book) => book.status === 'to-read'); + +const shelves = Array.from(new Set(books.map((book) => book.shelf))).sort((a, b) => + a.localeCompare(b), +); + +function groupByShelf(list: Book[]) { + const map = new Map(); + + for (const book of list) { + if (!map.has(book.shelf)) { + map.set(book.shelf, []); + } + map.get(book.shelf)!.push(book); + } + + return Array.from(map.entries()) + .map(([shelf, items]) => ({ + shelf, + books: items.sort((a, b) => a.title.localeCompare(b.title)), + })) + .sort((a, b) => a.shelf.localeCompare(b.shelf)); +} + +const readShelves = groupByShelf(readBooks); +const inProgressShelves = groupByShelf(inProgressBooks); +const toReadShelves = groupByShelf(toReadBooks); +--- + + +

    +

    All books

    + +
    + + + + + +
    + + + + + + + + + + + + { + books.map((book) => ( + + + + + + + )) + } + +
    TitleAuthorShelfStatus
    {book.title}{book.author}{book.shelf} + {book.status === 'read' + ? 'Read' + : book.status === 'in-progress' + ? 'Currently reading' + : 'Reference / not read completely'} +
    +
    + + + + + diff --git a/src/pages/library/books.astro b/src/pages/library/books.astro new file mode 100644 index 0000000..f21d899 --- /dev/null +++ b/src/pages/library/books.astro @@ -0,0 +1,168 @@ +--- +import PageLayout from '../../layouts/PageLayout.astro'; +import { books } from '../../data/library'; + +const shelves = Array.from(new Set(books.map((book) => book.shelf))).sort((a, b) => + a.localeCompare(b), +); +--- + + +
    +

    All books

    +

    + This library exists purely as a reference: books I own, books I've read, and books I dip + into when I need a specific idea. Use the filters to slice by status, shelf, or search by + title and author. +

    + +
    + + + + + +
    + + + + + + + + + + + + { + books.map((book) => ( + + + + + + + )) + } + +
    TitleAuthorShelfStatus
    {book.title}{book.author}{book.shelf} + {book.status === 'read' + ? 'Read' + : book.status === 'in-progress' + ? 'Currently reading' + : 'Reference / not read completely'} +
    +
    +
    + + + +