feat: add Journal index page

This commit is contained in:
Stefan Imhoff
2023-06-08 15:17:07 +02:00
parent 251e3c5300
commit 2c8d141002
8 changed files with 149 additions and 25 deletions

View File

@@ -0,0 +1,52 @@
---
import { Picture } from 'astro-imagetools/components';
import type { CollectionEntry } from 'astro:content';
interface Props {
entries: CollectionEntry<'journal'>[];
}
import { pickTwoRandomColors } from '../utils';
import { Link, Subsubheadline } from '../components';
const { entries } = Astro.props;
---
<nav class="col-start-1 col-end-18" aria-label="Journal">
<ul
class="grid auto-rows-[50px] grid-cols-[repeat(auto-fit,_minmax(100px,_1fr))] grid-rows-[50px] gap-[max(25px,_2vw)]"
>
{
entries.map(({ slug, data }) => (
<li class="journal-card image-shadow group">
<Link title={data.title} href={`/${slug}/`} class="block h-full w-full">
<div class="absolute z-10 flex h-full w-full flex-col items-center justify-center p-10 text-center leading-tight text-white">
<Subsubheadline class="!m-0 leading-tight">{data.title}</Subsubheadline>
</div>
{data.cover ? (
<>
{data.cover.endsWith('.svg') ? (
<img src={data.cover} alt={data.title} />
) : (
<Picture
src={data.cover}
alt={data.title}
aspect={0.6}
breakpoints={[300, 512, 768, 1024]}
/>
)}
</>
) : (
<div
class="h-full w-full scale-105 bg-gray-800 blur-sm brightness-[50%] filter transition duration-300 ease-in-out group-hover:brightness-[90%]"
style={`background-image: linear-gradient(to bottom left, ${
pickTwoRandomColors()[0]
} 0%, ${pickTwoRandomColors()[1]} 100%)`}
/>
)}
</Link>
</li>
))
}
</ul>
</nav>

View File

@@ -5,14 +5,19 @@ import { sortByDate } from '../utils';
import GridLayout from '../layouts/GridLayout.astro';
import PageTitle from '../components/PageTitle.astro';
import JournalList from '../components/JournalList.astro';
import { Tag } from '../components';
import { Content as Intro } from '../text/journal/intro.mdx';
import { Link } from '../components';
import { mapping } from '../mdx-components';
const allJournal = await getCollection('journal');
allJournal.sort(sortByDate);
const uniqueTags = [...new Set(allJournal.map((entry) => entry.data.tags).flat())];
uniqueTags.sort((a, b) => a.localeCompare(b));
const title = 'Journal';
const description = '…';
---
@@ -25,18 +30,8 @@ const description = '…';
>
<Intro components={mapping} />
</article>
<nav class="md:col-start-1 md:col-end-16" aria-label="Journal">
<ol>
{
allJournal.map(({ slug, data }) => (
<li>
<Link title={data.title} href={`/${slug}/`}>
{data.title}
</Link>
</li>
))
}
</ol>
</nav>
<aside class="col-start-1 col-end-18 flex flex-wrap gap-y-3">
{uniqueTags.map((tag) => <Tag href={`/tag/${tag}/`}>{tag}</Tag>)}
</aside>
<JournalList entries={allJournal} />
</GridLayout>

View File

@@ -0,0 +1,48 @@
---
import { getCollection } from 'astro:content';
import { sortByDate } from '../../utils';
import GridLayout from '../../layouts/GridLayout.astro';
import PageTitle from '../../components/PageTitle.astro';
import JournalList from '../../components/JournalList.astro';
console.log('test');
export async function getStaticPaths() {
const journalEntries = await getCollection('journal');
journalEntries.sort(sortByDate);
const uniqueTags = [...new Set(journalEntries.map((entry) => entry.data.tags).flat())];
return uniqueTags.map((tag) => {
const filteredEntries = journalEntries.filter((entry) => entry.data.tags.includes(tag));
return {
params: { tag },
props: {
entries: filteredEntries,
},
};
});
}
const { tag } = Astro.params;
const { entries } = Astro.props;
const title = 'Journal';
const description = '…';
---
<GridLayout
title={title}
description={description}
grid="wide"
class="grid"
innerGrid
backLink="/journal/"
>
<PageTitle slot="title">
Tag: {tag}
</PageTitle>
<JournalList entries={entries} />
</GridLayout>

View File

@@ -13,24 +13,17 @@ export const journal = defineCollection({
z.enum([
'book',
'code',
'decentralization',
'design',
'download',
'film',
'health',
'minimalism',
'note-taking',
'personal',
'philosophy',
'poetry',
'politics',
'productivity',
'publication',
'recommendation',
'self-improvement',
'software',
'survival',
'tip',
'typography',
'technology',
'writing',
])
),

View File

@@ -182,4 +182,21 @@
}
}
}
.journal-card {
@apply relative col-span-2 row-span-3 inline-block overflow-hidden rounded-4 border-1 border-black/25 hover:scale-105 dark:border-white/25 md:row-span-5;
& img,
& picture {
@apply !h-full w-full object-cover;
}
& img {
@apply !h-full scale-100 blur-0 brightness-[50%] filter transition duration-300 ease-in-out;
}
&:hover img {
@apply scale-105 blur-sm brightness-[70%];
}
}
}

View File

@@ -1 +1 @@
Writing is a passion for me. Ive written a huge collection of essays about [Ninja&nbsp;&amp;&nbsp;Ninjutsu](https://www.kogakure.de/) that I later converted into a book. The online publishing platform <cite>Medium</cite> selected [one of my essays](/attention/) as a recommendation of the day.
Writing is my passion. I've compiled a large collection of essays on [Ninja & Ninjutsu](https://www.kogakure.de/en/) which I later turned into a book. The online publishing platform <cite>Medium</cite> chose [one of my essays](/attention/) as their recommendation of the day. Additionally, I write [Haiku](/haiku/) poems.

View File

@@ -1,4 +1,5 @@
export * from './date';
export * from './pick-two-random-colors';
export * from './remark-reading-time';
export * from './sort-by-date';
export * from './sort-by-sortkey';

View File

@@ -0,0 +1,18 @@
import colorsJson from '../data/colors-japan.json';
interface Color {
id: string;
name: string;
description: string;
color: string;
}
export const pickTwoRandomColors = (): [string, string] => {
const colors: Color[] = colorsJson;
const randomIndex1 = Math.floor(Math.random() * colors.length);
let randomIndex2 = Math.floor(Math.random() * colors.length);
while (randomIndex2 === randomIndex1) {
randomIndex2 = Math.floor(Math.random() * colors.length);
}
return [colors[randomIndex1].color, colors[randomIndex2].color];
};