mirror of
https://github.com/starshardstudio/peafowl.git
synced 2024-11-22 04:54:19 +00:00
Create anime pages
This commit is contained in:
parent
ee9e527050
commit
a479d15993
4 changed files with 274 additions and 0 deletions
107
_components/AnimeRow.tsx
Normal file
107
_components/AnimeRow.tsx
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
import {formatDateIso} from "../_utils/date.ts"
|
||||||
|
import {AnimeData, AnimeProgress, animeProgressToClassName, animeProgressToIconDef, animeProgressToTitle} from "../_utils/anime.ts"
|
||||||
|
import {ratingToClassName} from "../_utils/rating.ts"
|
||||||
|
|
||||||
|
|
||||||
|
export type AnimeRowColumnKind = "rating" | "progress" | "name" | "nameoriginal" | "namesort" | "hascontent" | "date"
|
||||||
|
export type AnimeRowColumnPriority = undefined | "rating" | "progress" | "mixed"
|
||||||
|
|
||||||
|
export const animeRowColumnKindDefault: AnimeRowColumnKind[] = ["rating", "name", "namesort", "hascontent", "date", "progress"]
|
||||||
|
|
||||||
|
|
||||||
|
export type AnimeRowProps = {
|
||||||
|
anime: AnimeData,
|
||||||
|
columns?: AnimeRowColumnKind[]
|
||||||
|
priority?: AnimeRowColumnPriority
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function AnimeRow({anime, columns = animeRowColumnKindDefault, priority}: AnimeRowProps) {
|
||||||
|
const activeClass: string = anime.active ? "review-active" : ""
|
||||||
|
const activeClassFa: string = anime.active ? "fa-beat-fade" : ""
|
||||||
|
|
||||||
|
const ratingText: string = anime.rating ? `${anime.rating}` : ""
|
||||||
|
|
||||||
|
const ratingClass: string = ratingToClassName(anime.rating)
|
||||||
|
|
||||||
|
const progressClass: string = animeProgressToClassName(anime.progress)
|
||||||
|
const progressIcon: string = animeProgressToIconDef(anime.progress)
|
||||||
|
const progressTitle: string = animeProgressToTitle(anime.progress)
|
||||||
|
|
||||||
|
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 "progress": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`anime-progress ${progressClass}`}>
|
||||||
|
<data value={anime.progress ?? AnimeProgress.Unset} title={progressTitle}>
|
||||||
|
{progressIcon && <i className={`fa-sharp fa-regular ${progressIcon} ${activeClassFa}`}></i>}
|
||||||
|
</data>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "name": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-name`}>
|
||||||
|
<a href={anime.url}>
|
||||||
|
<data value={anime.name ?? ""}>
|
||||||
|
{anime.name}
|
||||||
|
</data>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "nameoriginal": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-nameoriginal`}>
|
||||||
|
<data value={anime.name_original ?? ""}>
|
||||||
|
{anime.name_original}
|
||||||
|
</data>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "namesort": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-namesort`} hidden={true}>
|
||||||
|
<data value={anime.name ?? ""}/>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "hascontent": {
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-hascontent`}>
|
||||||
|
<data value={anime.content ? "true" : "false"}>
|
||||||
|
{anime.content && <i className={"fa-sharp fa-regular fa-bars-sort"}/>}
|
||||||
|
</data>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case "date": {
|
||||||
|
const date = formatDateIso(anime.date)
|
||||||
|
return (
|
||||||
|
<td key={index} className={`review-date`}>
|
||||||
|
<time dateTime={date ?? ""}>
|
||||||
|
{date}
|
||||||
|
</time>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className={`anime ${activeClass} ${ratingClass} ${progressClass} ${priorityClass}`}>
|
||||||
|
{columnsElements}
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
101
_components/AnimeTable.tsx
Normal file
101
_components/AnimeTable.tsx
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
import {AnimeData} from "../_utils/anime.ts"
|
||||||
|
import {AnimeRow, AnimeRowColumnKind, animeRowColumnKindDefault, AnimeRowColumnPriority} from "./AnimeRow.tsx"
|
||||||
|
|
||||||
|
|
||||||
|
export type AnimeTableProps = {
|
||||||
|
id?: string,
|
||||||
|
anime: AnimeData[],
|
||||||
|
columns?: AnimeRowColumnKind[]
|
||||||
|
priority?: AnimeRowColumnPriority
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function AnimeTable({id, anime, columns = animeRowColumnKindDefault, priority}: AnimeTableProps) {
|
||||||
|
const colElements = columns.map((column, index) => {
|
||||||
|
switch(column) {
|
||||||
|
case "rating": return (
|
||||||
|
<col key={index} className={`review-rating`}/>
|
||||||
|
)
|
||||||
|
case "progress": return (
|
||||||
|
<col key={index} className={`anime-progress`}/>
|
||||||
|
)
|
||||||
|
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 rating of the game, from 1 to 100."}>
|
||||||
|
<i className={`fa-sharp fa-solid fa-thumbs-up`}/>
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "progress": return (
|
||||||
|
<th key={index} scope={"col"} className={`game-progress`}>
|
||||||
|
<abbr title={"The progress that has been made in the game."}>
|
||||||
|
<i className={`fa-sharp fa-solid fa-bars-progress`}/>
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "name": return (
|
||||||
|
<th key={index} scope={"col"} className={`review-name`}>
|
||||||
|
<abbr title={"The title of the game."}>
|
||||||
|
Title
|
||||||
|
</abbr>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
case "namesort": return (
|
||||||
|
<th key={index} scope={"col"} className={`review-namesort`} hidden={true}>
|
||||||
|
<abbr title={"The title to sort the game 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 = anime.map((ani: AnimeData) => (
|
||||||
|
<AnimeRow key={ani.url} anime={ani} columns={columns} priority={priority}/>
|
||||||
|
))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<table id={id}>
|
||||||
|
<colgroup>
|
||||||
|
{colElements}
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{thElements}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{trTdElements}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)
|
||||||
|
}
|
|
@ -17,6 +17,19 @@ export default function(data: AnimeData, helpers: Lume.Helpers) {
|
||||||
|
|
||||||
const dateSeparator = (data.progress || data.hours_played) ? <hr/> : null
|
const dateSeparator = (data.progress || data.hours_played) ? <hr/> : null
|
||||||
|
|
||||||
|
const nameOriginalRow = (
|
||||||
|
<ReviewInfo.MetadataRow
|
||||||
|
className={"anime-nameoriginal"}
|
||||||
|
label={"Original name"}
|
||||||
|
>
|
||||||
|
<data value={data.name_original}>
|
||||||
|
{data.name_original}
|
||||||
|
</data>
|
||||||
|
</ReviewInfo.MetadataRow>
|
||||||
|
)
|
||||||
|
|
||||||
|
const nameSeparator = (data.name_original) ? <hr/> : null
|
||||||
|
|
||||||
const progressRow = data.progress ? (
|
const progressRow = data.progress ? (
|
||||||
<ReviewInfo.MetadataRow
|
<ReviewInfo.MetadataRow
|
||||||
className={`anime-progress ${animeProgressToClassName(data.progress)}`}
|
className={`anime-progress ${animeProgressToClassName(data.progress)}`}
|
||||||
|
|
53
_includes/list-anime.tsx
Normal file
53
_includes/list-anime.tsx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { AnimeTable } from "../_components/AnimeTable.tsx";
|
||||||
|
import { AnimeData } from "../_utils/anime.ts";
|
||||||
|
|
||||||
|
export const layout = "base.tsx";
|
||||||
|
export const url = "/anime.html";
|
||||||
|
|
||||||
|
export default function (data: Lume.Data, helpers: Lume.Helpers) {
|
||||||
|
const introSection = data.content
|
||||||
|
? (
|
||||||
|
<section id={"list-anime-section-intro"}>
|
||||||
|
{data.children}
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const anime: AnimeData[] = data.search.pages("anime");
|
||||||
|
|
||||||
|
const animeSection = (
|
||||||
|
<section id={"list-anime-section-games"}>
|
||||||
|
<h2>
|
||||||
|
Anime list
|
||||||
|
<small>
|
||||||
|
<a href={helpers.url("/anime/feed.rss")}>
|
||||||
|
<i className={"fa-sharp fa-solid fa-rss"} /> Feed
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
<small>
|
||||||
|
<a href={helpers.url("/anime/index.json")}>
|
||||||
|
<i className={"fa-sharp fa-solid fa-brackets-curly"} />
|
||||||
|
{" "}
|
||||||
|
JSON
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
</h2>
|
||||||
|
<div>
|
||||||
|
<AnimeTable
|
||||||
|
id={"list-anime-table"}
|
||||||
|
anime={anime}
|
||||||
|
priority={"mixed"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main id={"list-anime-main"}>
|
||||||
|
{introSection}
|
||||||
|
{animeSection}
|
||||||
|
<script src={"/_static/scripting/sort.js"} />
|
||||||
|
<script src={"/_static/scripting/installSortOnLoad.js"} />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in a new issue