mirror of
https://github.com/kogakure/website-astro-stefanimhoff.de.git
synced 2026-02-03 20:15:27 +00:00
feat: add Tag pages and tags to journal pages
This commit is contained in:
@@ -2,20 +2,43 @@ import cx from 'classnames';
|
||||
|
||||
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||
|
||||
import { Link } from '.';
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
active?: boolean;
|
||||
children: ComponentChild;
|
||||
class?: string;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
export const Tag: FunctionalComponent<Props> = ({ class: className, children, ...props }) => {
|
||||
export const Tag: FunctionalComponent<Props> = ({
|
||||
active,
|
||||
class: className,
|
||||
children,
|
||||
href,
|
||||
...props
|
||||
}) => {
|
||||
const classes = cx(
|
||||
'inline-flex items-center justify-center rounded-25 border-2 border-shibui-350 bg-shibui-200 px-3 py-1 text-1 leading-none text-black mie-1 dark:border-shibui-750 dark:bg-shibui-950 dark:text-white',
|
||||
'capitalize border-3 relative inline-flex items-center justify-center rounded-25 border-2 border-shibui-350 bg-shibui-200 px-3 py-1 text-1 font-normal leading-none text-black mie-1 pbs-3 dark:border-shibui-750 dark:bg-shibui-950 dark:text-white min-w-[50px]',
|
||||
{
|
||||
'!bg-shibui-500 !text-white hover:!bg-shibui-700 dark:!border-shibui-500 dark:!bg-shibui-700 hover:dark:!bg-shibui-400':
|
||||
href,
|
||||
'active [&.active]:!border-black/25 !text-white [&.active]:!bg-accent': active,
|
||||
},
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{href ? (
|
||||
<Link href={href} class={classes} {...props}>
|
||||
{children}
|
||||
</Link>
|
||||
) : (
|
||||
<span class={classes} {...props}>
|
||||
{children}
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import GridLayout from '../layouts/GridLayout.astro';
|
||||
import PageTitle from '../components/PageTitle.astro';
|
||||
import Pagination from '../components/Pagination.astro';
|
||||
import Picture from '../components/Picture.astro';
|
||||
import { Banner, ListItem, OrderedList, TextLink } from '../components';
|
||||
import { Banner, ListItem, OrderedList, Tag, TextLink } from '../components';
|
||||
|
||||
import { mapping } from '../mdx-components';
|
||||
|
||||
@@ -52,14 +52,13 @@ const description = '…';
|
||||
<PageTitle slot="title" class="!text-6">
|
||||
{entry.data.title}
|
||||
</PageTitle>
|
||||
|
||||
{
|
||||
entry.data.cover && (
|
||||
<Picture
|
||||
alt={entry.data.title}
|
||||
aspect={1.6}
|
||||
breakpoints={[300, 500, 700, 1000, 1300, 1500, 1800, 2000]}
|
||||
class="col-span-full h-auto !mbe-0 xl:col-start-1 xl:col-end-14 3xl:col-end-13 [&_img]:!w-full [&_img]:!max-w-none [&_picture]:!w-full [&_picture]:!max-w-none"
|
||||
class="col-span-full aspect-video h-auto !mbe-0 xl:col-start-1 xl:col-end-14 3xl:col-end-13 [&_img]:!w-full [&_img]:!max-w-none [&_picture]:!w-full [&_picture]:!max-w-none"
|
||||
format={['webp', 'avif']}
|
||||
src={entry.data.cover}
|
||||
/>
|
||||
@@ -79,11 +78,14 @@ const description = '…';
|
||||
<div class="leading-tight">
|
||||
<time datetime={dateToISO(entry.data.date)}>{dateToFormat(entry.data.date)}</time>
|
||||
</div>
|
||||
<div class="leading-none">
|
||||
<div class="leading-none mbe-6">
|
||||
{wordCount(entry.body)}
|
||||
<span class="italic">words</span> • {minutesRead}
|
||||
<span class="italic">read</span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-y-3">
|
||||
{entry.data.tags.map((t) => <Tag href={`/tag/${t}/`}>{t}</Tag>)}
|
||||
</div>
|
||||
</aside>
|
||||
<div
|
||||
class="journal-post col-start-2 col-end-18 md:col-start-5 md:col-end-15 xl:col-start-6 xl:col-end-14 3xl:col-start-7 3xl:col-end-13"
|
||||
|
||||
32
src/pages/tag.astro
Normal file
32
src/pages/tag.astro
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
import { sortByDate } from '../utils';
|
||||
|
||||
import GridLayout from '../layouts/GridLayout.astro';
|
||||
import PageTitle from '../components/PageTitle.astro';
|
||||
import { Tag } from '../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 = 'Tags';
|
||||
const description = '…';
|
||||
---
|
||||
|
||||
<GridLayout
|
||||
backLink="/journal/"
|
||||
class="grid"
|
||||
description={description}
|
||||
grid="wide"
|
||||
innerGrid
|
||||
title={title}
|
||||
>
|
||||
<PageTitle grid="wide" innerGrid>Tags</PageTitle>
|
||||
<aside class="col-start-1 col-end-18 flex flex-wrap gap-y-3">
|
||||
{uniqueTags.map((t) => <Tag href={`/tag/${t}/`}>{t}</Tag>)}
|
||||
</aside>
|
||||
</GridLayout>
|
||||
@@ -6,14 +6,20 @@ 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';
|
||||
|
||||
console.log('test');
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
interface Props {
|
||||
entries: CollectionEntry<'journal'>[];
|
||||
uniqueTags: string[];
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const journalEntries = await getCollection('journal');
|
||||
journalEntries.sort(sortByDate);
|
||||
|
||||
const uniqueTags = [...new Set(journalEntries.map((entry) => entry.data.tags).flat())];
|
||||
uniqueTags.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
return uniqueTags.map((tag) => {
|
||||
const filteredEntries = journalEntries.filter((entry) => entry.data.tags.includes(tag));
|
||||
@@ -21,13 +27,14 @@ export async function getStaticPaths() {
|
||||
params: { tag },
|
||||
props: {
|
||||
entries: filteredEntries,
|
||||
uniqueTags: uniqueTags,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { tag } = Astro.params;
|
||||
const { entries } = Astro.props;
|
||||
const { entries, uniqueTags } = Astro.props;
|
||||
|
||||
const title = 'Journal';
|
||||
const description = '…';
|
||||
@@ -41,8 +48,17 @@ const description = '…';
|
||||
innerGrid
|
||||
backLink="/journal/"
|
||||
>
|
||||
<PageTitle slot="title">
|
||||
Tag: {tag}
|
||||
<PageTitle slot="title" class="capitalize">
|
||||
{tag}
|
||||
</PageTitle>
|
||||
<aside class="col-start-1 col-end-18 flex flex-wrap gap-y-3">
|
||||
{
|
||||
uniqueTags.map((uTag) => (
|
||||
<Tag active={uTag === tag} href={`/tag/${uTag}/`}>
|
||||
{uTag}
|
||||
</Tag>
|
||||
))
|
||||
}
|
||||
</aside>
|
||||
<JournalList entries={entries} />
|
||||
</GridLayout>
|
||||
Reference in New Issue
Block a user