mirror of
https://github.com/starshardstudio/peafowl.git
synced 2024-11-27 23:44: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";
|
||||
|
||||
|
||||
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;
|
||||
|
|
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