mirror of
https://github.com/starshardstudio/peafowl.git
synced 2024-11-24 05:54:19 +00:00
Add "all reviews" page
This commit is contained in:
parent
0bbb596c4c
commit
21ff234466
5 changed files with 313 additions and 39 deletions
85
_components/ReviewRow.tsx
Normal file
85
_components/ReviewRow.tsx
Normal file
|
@ -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 (
|
||||||
|
<td key={index} className={`review-rating ${ratingClass}`}>
|
||||||
|
<data value={ratingText}>
|
||||||
|
{ratingText}
|
||||||
|
</data>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "name": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-name`}>
|
||||||
|
<a href={review.url}>
|
||||||
|
<data value={review.name ?? ""}>
|
||||||
|
{review.name}
|
||||||
|
</data>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "namesort": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-namesort`} hidden={true}>
|
||||||
|
<data value={review.name_sort ?? review.name ?? ""}/>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "hascontent": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-hascontent`}>
|
||||||
|
<data value={review.content ? "true" : "false"}>
|
||||||
|
{review.content && <i className={"fa-sharp fa-regular fa-bars-sort"}/>}
|
||||||
|
</data>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "date": {
|
||||||
|
const date = formatDateIso(review.date)
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-date`}>
|
||||||
|
<time dateTime={date ?? ""}>
|
||||||
|
{date}
|
||||||
|
</time>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className={`game ${activeClass} ${ratingClass} ${priorityClass}`}>
|
||||||
|
{columnsElements}
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
92
_components/ReviewTable.tsx
Normal file
92
_components/ReviewTable.tsx
Normal file
|
@ -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 (
|
||||||
|
<col key={index} className={`review-rating`}/>
|
||||||
|
)
|
||||||
|
case "name": return (
|
||||||
|
<col key={index} className={`review-name`}/>
|
||||||
|
)
|
||||||
|
case "hascontent": return (
|
||||||
|
<col key={index} className={`review-hascontent`}/>
|
||||||
|
)
|
||||||
|
case "date": return (
|
||||||
|
<col key={index} className={`review-date`}/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const thElements = columns.map((column, index) => {
|
||||||
|
switch(column) {
|
||||||
|
case "rating": return (
|
||||||
|
<th key={index} scope={"col"} className={`review-rating`}>
|
||||||
|
<abbr title={"The given rating, from 1 to 100."}>
|
||||||
|
<i className={`fa-sharp fa-solid fa-thumbs-up`}/>
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "name": return (
|
||||||
|
<th key={index} scope={"col"} className={`review-name`}>
|
||||||
|
<abbr title={"The title of the reviewed item."}>
|
||||||
|
Title
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "namesort": return (
|
||||||
|
<th key={index} scope={"col"} className={`review-namesort`} hidden={true}>
|
||||||
|
<abbr title={"The title to sort the reviewed item as."}>
|
||||||
|
Sort by
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "hascontent":
|
||||||
|
return (
|
||||||
|
<th key={index} scope={"col"} className={`review-hascontent`}>
|
||||||
|
<abbr title={"Whether the review has textual content, or just metadata."}>
|
||||||
|
<i className={`fa-sharp fa-regular fa-bars-sort`}/>
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "date": return (
|
||||||
|
<th key={index} scope={"col"} className={`review-date`}>
|
||||||
|
<abbr title={"The date of the last update of the review."}>
|
||||||
|
Date
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const trTdElements = reviews.map((review: ReviewData) => (
|
||||||
|
<ReviewRow key={review.url} review={review} columns={columns} priority={priority}/>
|
||||||
|
))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<table id={id}>
|
||||||
|
<colgroup>
|
||||||
|
{colElements}
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{thElements}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{trTdElements}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)
|
||||||
|
}
|
129
_config.ts
129
_config.ts
|
@ -5,10 +5,25 @@ import fileData from "./_plugins/fileData.ts"
|
||||||
import Site from "lume/core/site.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({
|
const site: Site = lume({
|
||||||
prettyUrls: false,
|
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({}))
|
site.use(jsx({}))
|
||||||
|
|
||||||
|
@ -18,17 +33,11 @@ site.data("styles", ["/_static/styles/base.css"])
|
||||||
site.data("lang", "en")
|
site.data("lang", "en")
|
||||||
site.data("date", "Git Created")
|
site.data("date", "Git Created")
|
||||||
|
|
||||||
|
/*===== list of lists =====*/
|
||||||
|
|
||||||
site.data("layout", "index.tsx", "/index.md")
|
site.data("layout", "index.tsx", "/index.md")
|
||||||
site.data("tags", ["index"], "/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({
|
site.use(fileData({
|
||||||
query: "index",
|
query: "index",
|
||||||
urlizer(data) {
|
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({
|
site.use(fileData({
|
||||||
query: "list-games",
|
query: "list-games",
|
||||||
urlizer(_data) {
|
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({
|
site.use(fileData({
|
||||||
query: "game",
|
query: "game",
|
||||||
urlizer(data) {
|
urlizer(data) {
|
||||||
|
@ -80,26 +143,12 @@ site.use(fileData({
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
site.use(feed({
|
/*===== list of anime =====*/
|
||||||
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"
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
|
|
||||||
site.data("url", "/anime/index.html", "/list-anime.md")
|
site.data("url", "/anime/index.html", "/list-anime.md")
|
||||||
site.data("layout", "list-anime.tsx", "/list-anime.md")
|
site.data("layout", "list-anime.tsx", "/list-anime.md")
|
||||||
site.data("tags", ["list", "list-anime"], "/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({
|
site.use(fileData({
|
||||||
query: "list-anime",
|
query: "list-anime",
|
||||||
urlizer(_data) {
|
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({
|
site.use(fileData({
|
||||||
query: "anime",
|
query: "anime",
|
||||||
urlizer(data) {
|
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;
|
|
||||||
|
|
46
_includes/list-all.tsx
Normal file
46
_includes/list-all.tsx
Normal file
|
@ -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 ? (
|
||||||
|
<section id={"list-all-section-intro"}>
|
||||||
|
{data.children}
|
||||||
|
</section>
|
||||||
|
) : null
|
||||||
|
|
||||||
|
const reviews: ReviewData[] = data.search.pages("review")
|
||||||
|
|
||||||
|
const reviews_section = (
|
||||||
|
<section id={"list-all-section-all"}>
|
||||||
|
<h2>
|
||||||
|
Review list
|
||||||
|
<small>
|
||||||
|
<a href={helpers.url("/all/feed.rss")}>
|
||||||
|
<i className={"fa-sharp fa-solid fa-rss"}/> Feed
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
<small>
|
||||||
|
<a href={helpers.url("/all/index.json")}>
|
||||||
|
<i className={"fa-sharp fa-solid fa-brackets-curly"}/> Raw
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
</h2>
|
||||||
|
<div>
|
||||||
|
<ReviewTable id={"list-all-table"} reviews={reviews} priority={"mixed"}/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main id={"list-all-main"}>
|
||||||
|
{intro_section}
|
||||||
|
{reviews_section}
|
||||||
|
<script src={"/_static/scripting/sort.js"}/>
|
||||||
|
<script src={"/_static/scripting/installSortOnLoad.js"}/>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
0
list-all.md
Normal file
0
list-all.md
Normal file
Loading…
Reference in a new issue