From 21ff234466939b828a9639f93295fcc37341ee7e Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 21 Nov 2024 05:28:20 +0100 Subject: [PATCH] Add "all reviews" page --- _components/ReviewRow.tsx | 85 ++++++++++++++++++++++++ _components/ReviewTable.tsx | 92 +++++++++++++++++++++++++ _config.ts | 129 +++++++++++++++++++++++++----------- _includes/list-all.tsx | 46 +++++++++++++ list-all.md | 0 5 files changed, 313 insertions(+), 39 deletions(-) create mode 100644 _components/ReviewRow.tsx create mode 100644 _components/ReviewTable.tsx create mode 100644 _includes/list-all.tsx create mode 100644 list-all.md diff --git a/_components/ReviewRow.tsx b/_components/ReviewRow.tsx new file mode 100644 index 0000000..0f24868 --- /dev/null +++ b/_components/ReviewRow.tsx @@ -0,0 +1,85 @@ +import {formatDateIso} from "../_utils/date.ts" +import {ratingToClassName} from "../_utils/rating.ts" +import { ReviewData } from "../_utils/review.ts"; + + +export type ReviewRowColumnKind = "rating" | "name" | "namesort" | "hascontent" | "date" +export type ReviewRowColumnPriority = undefined | "rating" | "progress" | "mixed" + +export const reviewRowColumnKindDefault: ReviewRowColumnKind[] = ["rating", "name", "namesort", "hascontent", "date"] + + +export type ReviewRowProps = { + review: ReviewData, + columns?: ReviewRowColumnKind[] + priority?: ReviewRowColumnPriority +} + + +export function ReviewRow({review, columns = reviewRowColumnKindDefault, priority}: ReviewRowProps) { + const activeClass: string = review.active ? "review-active" : "" + const activeClassFa: string = review.active ? "fa-beat-fade" : "" + + const ratingText: string = review.rating ? `${review.rating}` : "" + + const ratingClass: string = ratingToClassName(review.rating) + + const priorityClass: string = priority ? `priority-${priority}` : "" + + const columnsElements = columns.map((kind, index) => { + switch(kind) { + case "rating": { + return ( + + + {ratingText} + + + ) + } + case "name": { + return ( + + + + {review.name} + + + + ) + } + case "namesort": { + return ( + + + + ) + } + case "hascontent": { + return ( + + + {review.content && } + + + ) + } + case "date": { + const date = formatDateIso(review.date) + return ( + + + + ) + } + } + }) + + return ( + + {columnsElements} + + ) +} \ No newline at end of file diff --git a/_components/ReviewTable.tsx b/_components/ReviewTable.tsx new file mode 100644 index 0000000..f97fcd9 --- /dev/null +++ b/_components/ReviewTable.tsx @@ -0,0 +1,92 @@ +import {GameData} from "../_utils/game.ts" +import {ReviewData} from "../_utils/review.ts"; +import { ReviewRow, ReviewRowColumnKind, reviewRowColumnKindDefault, ReviewRowColumnPriority } from "./ReviewRow.tsx"; + + +export type ReviewTableProps = { + id?: string, + reviews: ReviewData[], + columns?: ReviewRowColumnKind[] + priority?: ReviewRowColumnPriority +} + + +export function ReviewTable({id, reviews, columns = reviewRowColumnKindDefault, priority}: ReviewTableProps) { + const colElements = columns.map((column, index) => { + switch(column) { + case "rating": return ( + + ) + case "name": return ( + + ) + case "hascontent": return ( + + ) + case "date": return ( + + ) + } + }) + + const thElements = columns.map((column, index) => { + switch(column) { + case "rating": return ( + + + + + + ) + case "name": return ( + + + Title + + + ) + case "namesort": return ( + + + Sort by + + + ) + case "hascontent": + return ( + + + + + + ) + case "date": return ( + + + Date + + + ) + } + }) + + const trTdElements = reviews.map((review: ReviewData) => ( + + )) + + return ( + + + {colElements} + + + + {thElements} + + + + {trTdElements} + +
+ ) +} \ No newline at end of file diff --git a/_config.ts b/_config.ts index 4137673..99d9e2d 100644 --- a/_config.ts +++ b/_config.ts @@ -5,10 +5,25 @@ import fileData from "./_plugins/fileData.ts" import Site from "lume/core/site.ts"; +let location: URL | undefined = undefined +try { + location = new URL("") // TODO: Enter the base URL of your website here, or links won't work! +} +catch (e) { + if(e instanceof TypeError) { + // pass safely + } + else { + throw e + } +} + + const site: Site = lume({ prettyUrls: false, - location: new URL(""), // TODO: Enter the base URL of your website here, or links won't work! + location, }) +export default site site.use(jsx({})) @@ -18,17 +33,11 @@ site.data("styles", ["/_static/styles/base.css"]) site.data("lang", "en") site.data("date", "Git Created") +/*===== list of lists =====*/ + site.data("layout", "index.tsx", "/index.md") site.data("tags", ["index"], "/index.md") - -site.data("url", "/games/index.html", "/list-games.md") -site.data("layout", "list-games.tsx", "/list-games.md") -site.data("tags", ["list", "list-games"], "/list-games.md") - -site.data("layout", "game.tsx", "/games") -site.data("tags", ["review", "game"], "/games") - site.use(fileData({ query: "index", urlizer(data) { @@ -43,6 +52,43 @@ site.use(fileData({ } })) +/*===== list of all reviews =====*/ + +site.data("url", "/all/index.html", "/list-all.md") +site.data("layout", "list-all.tsx", "/list-all.md") +site.data("tags", ["list", "list-all"], "/list-all.md") + +site.use(fileData({ + query: "list-all", + urlizer(_data) { + return "/all/index.json" + }, + contentizer(data) { + return JSON.stringify({ + content: data.content, + items: site.search.pages("review").map((data) => data.url.replace(".html", ".json")) + }) + } +})) + +site.use(feed({ + output: ["/all/feed.rss", "/all/feed.json"], + query: "review", + limit: 10, + info: { + title: "Reviews", // TODO: Change this to your site's videogame section's name! + }, + items: { + title: "=name" + } +})) + +/*===== list of games =====*/ + +site.data("url", "/games/index.html", "/list-games.md") +site.data("layout", "list-games.tsx", "/list-games.md") +site.data("tags", ["list", "list-games"], "/list-games.md") + site.use(fileData({ query: "list-games", urlizer(_data) { @@ -56,6 +102,23 @@ site.use(fileData({ } })) +site.use(feed({ + output: ["/games/feed.rss", "/games/feed.json"], + query: "game", + limit: 10, + info: { + title: "Videogames", // TODO: Change this to your site's videogame section's name! + }, + items: { + title: "=name" + } +})) + +/*===== game =====*/ + +site.data("layout", "game.tsx", "/games") +site.data("tags", ["review", "game"], "/games") + site.use(fileData({ query: "game", urlizer(data) { @@ -80,26 +143,12 @@ site.use(fileData({ } })) -site.use(feed({ - output: ["/games/feed.rss", "/games/feed.json"], - query: "game", - limit: 10, - info: { - title: "Videogames", // TODO: Change this to your site's videogame section's name! - }, - items: { - title: "=name" - } -})) - +/*===== list of anime =====*/ site.data("url", "/anime/index.html", "/list-anime.md") site.data("layout", "list-anime.tsx", "/list-anime.md") site.data("tags", ["list", "list-anime"], "/list-anime.md") -site.data("layout", "anime.tsx", "/anime") -site.data("tags", ["review", "anime"], "/anime") - site.use(fileData({ query: "list-anime", urlizer(_data) { @@ -113,6 +162,23 @@ site.use(fileData({ } })) +site.use(feed({ + output: ["/anime/feed.rss", "/anime/feed.json"], + query: "anime", + limit: 10, + info: { + title: "Anime", // TODO: Change this to your site's anime section's name! + }, + items: { + title: "=name" + } +})) + +/*===== anime =====*/ + +site.data("layout", "anime.tsx", "/anime") +site.data("tags", ["review", "anime"], "/anime") + site.use(fileData({ query: "anime", urlizer(data) { @@ -134,18 +200,3 @@ site.use(fileData({ }) } })) - -site.use(feed({ - output: ["/anime/feed.rss", "/anime/feed.json"], - query: "anime", - limit: 10, - info: { - title: "Anime", // TODO: Change this to your site's anime section's name! - }, - items: { - title: "=name" - } -})) - - -export default site; diff --git a/_includes/list-all.tsx b/_includes/list-all.tsx new file mode 100644 index 0000000..9a37cf5 --- /dev/null +++ b/_includes/list-all.tsx @@ -0,0 +1,46 @@ +import { ReviewTable } from "../_components/ReviewTable.tsx"; +import { ReviewData } from "../_utils/review.ts"; + + +export const layout = "base.tsx" +export const url = "/all.html" + +export default function(data: Lume.Data, helpers: Lume.Helpers) { + const intro_section = data.content ? ( +
+ {data.children} +
+ ) : null + + const reviews: ReviewData[] = data.search.pages("review") + + const reviews_section = ( +
+

+ Review list + + + Feed + + + + + Raw + + +

+
+ +
+
+ ) + + return ( +
+ {intro_section} + {reviews_section} +