Improve song lists
This commit is contained in:
parent
8cddb5706e
commit
e089245be2
|
@ -29,10 +29,13 @@ export const collections = {
|
||||||
songs: defineCollection({
|
songs: defineCollection({
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
|
composer: z.string().optional(),
|
||||||
|
lyrics: z.string().optional(),
|
||||||
album: z.record(
|
album: z.record(
|
||||||
z.string(),
|
z.string(),
|
||||||
z.object({
|
z.object({
|
||||||
track: z.number()
|
track: z.number(),
|
||||||
|
vocal: z.array(z.string()).optional()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
---
|
---
|
||||||
title: Black Eyes
|
title: Black Eyes
|
||||||
|
composer: Kirin (EastNewSound)
|
||||||
|
lyrics: Mei Ayakura
|
||||||
album:
|
album:
|
||||||
ARCD0051:
|
ARCD0051:
|
||||||
track: 7
|
track: 7
|
||||||
|
vocal:
|
||||||
|
- Mei Ayakura
|
||||||
---
|
---
|
||||||
|
|
||||||
{% lyrics %}
|
{% lyrics %}
|
||||||
|
|
9
src/data/circles.json
Normal file
9
src/data/circles.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"Alstroemeria Records": {
|
||||||
|
"albums": {
|
||||||
|
"ARCD0051": {
|
||||||
|
"title": "Engaged Dancehall"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import Lyrics from "../../layouts/Lyrics.astro";
|
import Base from "../../layouts/Base.astro";
|
||||||
import { getCollection } from "astro:content";
|
import Header from '../../components/headers/Base.astro';
|
||||||
|
import { CollectionEntry, getCollection } from "astro:content";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return (await getCollection('songs'))
|
return (await getCollection('songs'))
|
||||||
|
@ -9,10 +10,20 @@ export async function getStaticPaths() {
|
||||||
.flat()
|
.flat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
song: CollectionEntry<'songs'>;
|
||||||
|
}
|
||||||
|
|
||||||
const { song } = Astro.props;
|
const { song } = Astro.props;
|
||||||
const { Content } = await song.render();
|
const { Content } = await song.render();
|
||||||
---
|
---
|
||||||
|
|
||||||
<Lyrics frontmatter={song.data}>
|
<Base>
|
||||||
|
<main class="l-songs-song">
|
||||||
|
<article class="l-songs-song__page">
|
||||||
|
<Header title={song.data.title} />
|
||||||
<Content />
|
<Content />
|
||||||
</Lyrics>
|
</article>
|
||||||
|
</main>
|
||||||
|
</Base>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
import List from "../../layouts/List.astro";
|
import Base from "../../layouts/Base.astro";
|
||||||
import { getCollection } from 'astro:content';
|
import Header from '../../components/headers/Base.astro';
|
||||||
import { getAllCats } from "../../utils/songs";
|
import { CollectionEntry, getCollection } from 'astro:content';
|
||||||
|
import { ALBUMS, getAllCats } from "../../utils/songs";
|
||||||
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
|
@ -13,12 +14,33 @@ export async function getStaticPaths() {
|
||||||
props: {
|
props: {
|
||||||
songs: songs
|
songs: songs
|
||||||
.filter(entry => cat in entry.data.album)
|
.filter(entry => cat in entry.data.album)
|
||||||
.map(song => ({ title: song.data.title, slug: `/songs/${cat}/${song.slug}/` })) }
|
.map(song => ({ frontmatter: song.data, slug: `/songs/${cat}/${song.slug}/` }))
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
songs: Array<{
|
||||||
|
frontmatter: CollectionEntry<'songs'>['data'],
|
||||||
|
slug: string,
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
const { cat } = Astro.params;
|
const { cat } = Astro.params;
|
||||||
const { songs } = Astro.props;
|
const { songs } = Astro.props;
|
||||||
|
const album = ALBUMS[cat!];
|
||||||
---
|
---
|
||||||
|
|
||||||
<List title={cat!} pages={songs} />
|
<Base>
|
||||||
|
<main class="l-songs-cat">
|
||||||
|
<article class="l-songs-cat__article">
|
||||||
|
<Header title={`${cat} - ${album.title}`} />
|
||||||
|
<div class="l-songs-cat__list">
|
||||||
|
{songs.map(song => [
|
||||||
|
<span>{song.frontmatter.album[cat!].track}</span>
|
||||||
|
<a href={song.slug}>{song.frontmatter.title}</a>
|
||||||
|
])}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</Base>
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
---
|
---
|
||||||
import List from "../../layouts/List.astro";
|
import List from "../../layouts/List.astro";
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
import { getAllCats } from "../../utils/songs";
|
import { ALBUMS, getAllCats } from "../../utils/songs";
|
||||||
|
|
||||||
|
|
||||||
const pages = [...getAllCats(await getCollection('songs'))]
|
const pages = [...getAllCats(await getCollection('songs'))]
|
||||||
.sort((a, b) => a < b ? 1 : -1)
|
.sort((a, b) => a < b ? 1 : -1)
|
||||||
.map(catalog => ({ title: catalog, slug: `/songs/${catalog}/` }));
|
.map(catalog => ({
|
||||||
|
title: `${catalog} - ${ALBUMS[catalog].title}`,
|
||||||
|
slug: `/songs/${catalog}/`
|
||||||
|
}));
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<List title="Songs" pages={pages} />
|
<List title="Albums" pages={pages} />
|
||||||
|
|
12
src/schema.d.ts
vendored
Normal file
12
src/schema.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/** @file src/data/circles.json */
|
||||||
|
interface CirclesSchema {
|
||||||
|
/** Circle name */
|
||||||
|
[key: string]: {
|
||||||
|
albums: {
|
||||||
|
/** Catalog number */
|
||||||
|
[key: string]: {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
.l-lyrics {
|
|
||||||
display: flex;
|
|
||||||
padding: 2em 0;
|
|
||||||
|
|
||||||
&__page {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
23
src/styles/layouts/_songs.scss
Normal file
23
src/styles/layouts/_songs.scss
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
.l-songs-cat {
|
||||||
|
padding: 1.5em;
|
||||||
|
|
||||||
|
&__article {
|
||||||
|
max-width: 40em;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 3em 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.l-songs-song {
|
||||||
|
padding: 1.5em;
|
||||||
|
|
||||||
|
&__page {
|
||||||
|
max-width: 40em;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,4 +32,4 @@
|
||||||
@use 'layouts/home';
|
@use 'layouts/home';
|
||||||
@use 'layouts/pages';
|
@use 'layouts/pages';
|
||||||
@use 'layouts/article';
|
@use 'layouts/article';
|
||||||
@use 'layouts/lyrics';
|
@use 'layouts/songs';
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
|
import circles from "../data/circles.json";
|
||||||
import type { CollectionEntry } from "astro:content";
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
|
|
||||||
type Song = CollectionEntry<'songs'>;
|
type Song = CollectionEntry<'songs'>;
|
||||||
|
|
||||||
|
interface Metadata {
|
||||||
|
[key: string]: {
|
||||||
|
circle: string,
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getAllCats(songs: Song[]): Set<string> {
|
export function getAllCats(songs: Song[]): Set<string> {
|
||||||
return songs.reduce(
|
return songs.reduce(
|
||||||
|
@ -13,3 +21,20 @@ export function getAllCats(songs: Song[]): Set<string> {
|
||||||
new Set<string>()
|
new Set<string>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createMetadata(circles: CirclesSchema): Metadata {
|
||||||
|
const metadata: Metadata = {};
|
||||||
|
|
||||||
|
for (const circle of Object.keys(circles)) {
|
||||||
|
const data = circles[circle];
|
||||||
|
for (const cat of Object.keys(data.albums))
|
||||||
|
metadata[cat] = {
|
||||||
|
circle,
|
||||||
|
title: data.albums[cat].title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const ALBUMS: Metadata = createMetadata(circles);
|
Loading…
Reference in a new issue