Improve styles for song page
This commit is contained in:
parent
9c55241e21
commit
15d32a6dab
71
src/components/markdown/Song.astro
Normal file
71
src/components/markdown/Song.astro
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
metadata: {
|
||||||
|
cover: string;
|
||||||
|
title: string;
|
||||||
|
cat: string;
|
||||||
|
track: number;
|
||||||
|
circle: string;
|
||||||
|
composer?: string;
|
||||||
|
lyrics?: string;
|
||||||
|
vocal?: string[];
|
||||||
|
other: Array<{
|
||||||
|
cat: string;
|
||||||
|
}>;
|
||||||
|
origin?: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { metadata } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<section class="c-song">
|
||||||
|
<a href={metadata.cover}><img src={metadata.cover} /></a>
|
||||||
|
<div class="c-song__title">
|
||||||
|
<h2 class="c-song__heading">{metadata.title}</h2>
|
||||||
|
<span class="c-song__cat">{metadata.cat}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="c-song__table">
|
||||||
|
<tr>
|
||||||
|
<td>Track</td>
|
||||||
|
<td>{metadata.track}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Circle</td>
|
||||||
|
<td>{metadata.circle}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Composer</td>
|
||||||
|
<td>{metadata.composer}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Lyrics</td>
|
||||||
|
<td>{metadata.lyrics}</td>
|
||||||
|
</tr>
|
||||||
|
{!!metadata.vocal?.length &&
|
||||||
|
<tr>
|
||||||
|
<td>Vocal</td>
|
||||||
|
<td>
|
||||||
|
<ul>{metadata.vocal.map(vocalist => <li>{vocalist}</li>)}</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
{!!metadata.origin?.length &&
|
||||||
|
<tr>
|
||||||
|
<td>Origin</td>
|
||||||
|
<td>
|
||||||
|
<ul>{metadata.origin.map(title => <li>{title}</li>)}</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
{!!metadata.other?.length &&
|
||||||
|
<tr>
|
||||||
|
<td>Other versions</td>
|
||||||
|
<td>
|
||||||
|
<ul>{metadata.other.map(version => <li>{version.cat}</li>)}</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</table>
|
||||||
|
</section>
|
|
@ -31,6 +31,7 @@ export const collections = {
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
composer: z.string().optional(),
|
composer: z.string().optional(),
|
||||||
lyrics: z.string().optional(),
|
lyrics: z.string().optional(),
|
||||||
|
origin: z.array(z.string()).optional(),
|
||||||
album: z.record(
|
album: z.record(
|
||||||
z.string(),
|
z.string(),
|
||||||
z.object({
|
z.object({
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
title: Black Eyes
|
title: Black Eyes
|
||||||
composer: Kirin (EastNewSound)
|
composer: Kirin (EastNewSound)
|
||||||
lyrics: Mei Ayakura
|
lyrics: Mei Ayakura
|
||||||
|
origin:
|
||||||
|
- 天狗が見ている 〜 Black Eyes
|
||||||
album:
|
album:
|
||||||
ARCD0051:
|
ARCD0051:
|
||||||
track: 7
|
track: 7
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
"Alstroemeria Records": {
|
"Alstroemeria Records": {
|
||||||
"albums": {
|
"albums": {
|
||||||
"ARCD0051": {
|
"ARCD0051": {
|
||||||
"title": "Engaged Dancehall"
|
"title": "Engaged Dancehall",
|
||||||
|
"cover": "/static/albums/ARCD0051.jpg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
import Base from "../../layouts/Base.astro";
|
import Base from "../../layouts/Base.astro";
|
||||||
|
import Song from "../../components/markdown/Song.astro";
|
||||||
import { CollectionEntry, getCollection } from "astro:content";
|
import { CollectionEntry, getCollection } from "astro:content";
|
||||||
import { ALBUMS } from "../../utils/songs";
|
import { ALBUMS } from "../../utils/songs";
|
||||||
|
|
||||||
|
@ -19,52 +20,31 @@ interface Props {
|
||||||
const { cat, song } = Astro.props;
|
const { cat, song } = Astro.props;
|
||||||
const { Content } = await song.render();
|
const { Content } = await song.render();
|
||||||
|
|
||||||
const metadata = {
|
|
||||||
...song.data,
|
|
||||||
...song.data.album[cat],
|
|
||||||
...ALBUMS[cat],
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Other versions of this song */
|
/** Other versions of this song */
|
||||||
const other = Object.keys(song.data.album)
|
const other = Object.keys(song.data.album)
|
||||||
.filter(other => other != cat)
|
.filter(other => other != cat)
|
||||||
.map(cat => ({ cat, title: ALBUMS[cat].title }));
|
.map(cat => ({ cat, title: ALBUMS[cat].title }));
|
||||||
|
|
||||||
|
const metadata = {
|
||||||
|
...song.data,
|
||||||
|
...song.data.album[cat],
|
||||||
|
...ALBUMS[cat],
|
||||||
|
cat,
|
||||||
|
other
|
||||||
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<Base>
|
<Base>
|
||||||
<main class="l-songs-song">
|
<main class="l-song">
|
||||||
<article class="l-songs-song__page">
|
<article class="l-song__page">
|
||||||
<header class="p-header">
|
<header class="p-header">
|
||||||
<h1 class="p-header__heading">{song.data.title}</h1>
|
<h1 class="p-header__heading">{song.data.title}</h1>
|
||||||
</header>
|
</header>
|
||||||
<Content />
|
<Content />
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<aside class="l-songs-song__meta">
|
<aside class="l-song__aside">
|
||||||
<section class="p-song-meta">
|
<Song metadata={metadata} />
|
||||||
<div>{metadata.circle}</div>
|
|
||||||
<div>{metadata.title}</div>
|
|
||||||
<div>{cat}</div>
|
|
||||||
<div>Track {metadata.track}</div>
|
|
||||||
<div>Composer: {metadata.composer}</div>
|
|
||||||
<div>Lyrics: {metadata.lyrics}</div>
|
|
||||||
{metadata.vocal && (
|
|
||||||
<div>
|
|
||||||
Vocal:
|
|
||||||
<ul>
|
|
||||||
{metadata.vocal.map(vocalist => <li>{vocalist}</li>)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!!other.length && (
|
|
||||||
<div>
|
|
||||||
Other versions:
|
|
||||||
<ul>
|
|
||||||
{other.map(version => <li>{version.cat}</li>)}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
</aside>
|
</aside>
|
||||||
</main>
|
</main>
|
||||||
</Base>
|
</Base>
|
||||||
|
|
1
src/schema.d.ts
vendored
1
src/schema.d.ts
vendored
|
@ -6,6 +6,7 @@ interface CirclesSchema {
|
||||||
/** Catalog number */
|
/** Catalog number */
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
title: string;
|
title: string;
|
||||||
|
cover: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-song-meta {
|
|
||||||
padding: 0.5em;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 0.5em;
|
|
||||||
box-shadow: var(--shadow-l);
|
|
||||||
}
|
|
43
src/styles/components/_song.scss
Normal file
43
src/styles/components/_song.scss
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
.c-song {
|
||||||
|
max-width: 20em;
|
||||||
|
margin-inline: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
box-shadow: var(--shadow-l);
|
||||||
|
|
||||||
|
&__heading {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3em;
|
||||||
|
margin: 0.3em 0 0 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cat {
|
||||||
|
color: gray;
|
||||||
|
font-size: 0.8em;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '(';
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
content: ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__table {
|
||||||
|
td:not(:last-child) {
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,14 +13,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.l-songs-song {
|
.l-song {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
display: grid;
|
|
||||||
column-gap: 1em;
|
|
||||||
grid-template-columns: 1fr 16em;
|
|
||||||
|
|
||||||
&__page {
|
&__page {
|
||||||
max-width: 40em;
|
max-width: 40em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 50em) {
|
||||||
|
display: grid;
|
||||||
|
column-gap: 1em;
|
||||||
|
grid-template-columns: 1fr 20em;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
@use 'components/search';
|
@use 'components/search';
|
||||||
@use 'components/tab';
|
@use 'components/tab';
|
||||||
@use 'components/lyrics';
|
@use 'components/lyrics';
|
||||||
|
@use 'components/song';
|
||||||
|
|
||||||
// Partials
|
// Partials
|
||||||
@use 'partials/nav';
|
@use 'partials/nav';
|
||||||
|
|
|
@ -6,8 +6,12 @@ type Song = CollectionEntry<'songs'>;
|
||||||
|
|
||||||
interface Metadata {
|
interface Metadata {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
|
/** Circle name */
|
||||||
circle: string,
|
circle: string,
|
||||||
title: string
|
/** Album title */
|
||||||
|
title: string,
|
||||||
|
/** Path to album cover image */
|
||||||
|
cover: string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,10 +32,7 @@ function createMetadata(circles: CirclesSchema): Metadata {
|
||||||
for (const circle of Object.keys(circles)) {
|
for (const circle of Object.keys(circles)) {
|
||||||
const data = circles[circle];
|
const data = circles[circle];
|
||||||
for (const cat of Object.keys(data.albums))
|
for (const cat of Object.keys(data.albums))
|
||||||
metadata[cat] = {
|
metadata[cat] = { circle, ...data.albums[cat] }
|
||||||
circle,
|
|
||||||
title: data.albums[cat].title,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue