102 lines
3.1 KiB
Plaintext
102 lines
3.1 KiB
Plaintext
---
|
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
|
import ArticleTile from '../../components/ArticleTile.astro';
|
|
import { getCollection } from 'astro:content';
|
|
import { useTranslations } from '../../i18n/ui';
|
|
|
|
const lang = 'cs';
|
|
const t = useTranslations(lang);
|
|
|
|
const posts = (await getCollection('blog', ({ data }) => !data.draft))
|
|
.filter(p => p.id.startsWith('cs/'))
|
|
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
|
|
|
const allTags = [...new Set(posts.flatMap(p => p.data.tags))].sort();
|
|
---
|
|
|
|
<BaseLayout title="Vladimír Duša" description="Osobní web Vladimíra Duši" lang={lang} alternateUrl="/en/">
|
|
{posts.length === 0 ? (
|
|
<div class="px-8 py-16 text-gray-400 text-sm">{t('empty.articles')}</div>
|
|
) : (
|
|
<div class="px-8 pb-12">
|
|
{allTags.length > 0 && (
|
|
<div class="tag-filter" id="tag-filter">
|
|
<button class="tag-filter-btn active" data-tag="all">{t('filter.all')}</button>
|
|
{allTags.map((tag) => (
|
|
<>
|
|
<span class="tag-filter-sep">·</span>
|
|
<button class="tag-filter-btn" data-tag={tag}>{tag}</button>
|
|
</>
|
|
))}
|
|
</div>
|
|
)}
|
|
<div class="article-grid">
|
|
{posts.map((post, i) => {
|
|
const baseSlug = post.id.replace(/^cs\//, '').replace(/\.md$/, '');
|
|
return (
|
|
<ArticleTile
|
|
title={post.data.title}
|
|
href={`/cs/clanky/${baseSlug}`}
|
|
image={post.data.image}
|
|
description={post.data.description}
|
|
tags={post.data.tags}
|
|
class={i % 6 === 0 ? 'tile-featured-left' : i % 6 === 5 ? 'tile-featured-right' : 'tile-regular'}
|
|
eager={i < 3}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</BaseLayout>
|
|
|
|
<script>
|
|
const buttons = document.querySelectorAll<HTMLButtonElement>('.tag-filter-btn');
|
|
const tiles = document.querySelectorAll<HTMLAnchorElement>('.article-tile');
|
|
|
|
function applyFilter(tag: string) {
|
|
buttons.forEach(btn => btn.classList.toggle('active', btn.dataset.tag === tag));
|
|
|
|
tiles.forEach(tile => {
|
|
const tileTags = (tile.dataset.tags ?? '').split(',').filter(Boolean);
|
|
const matches = tag === 'all' || tileTags.includes(tag);
|
|
tile.classList.toggle('is-filtered', !matches);
|
|
});
|
|
|
|
const url = new URL(window.location.href);
|
|
if (tag === 'all') url.searchParams.delete('tag');
|
|
else url.searchParams.set('tag', tag);
|
|
history.replaceState(null, '', url.toString());
|
|
}
|
|
|
|
const initialTag = new URLSearchParams(window.location.search).get('tag') ?? 'all';
|
|
applyFilter(initialTag);
|
|
|
|
buttons.forEach(btn => {
|
|
btn.addEventListener('click', () => applyFilter(btn.dataset.tag ?? 'all'));
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.article-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
grid-auto-rows: 260px;
|
|
gap: 10px;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.article-grid {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-auto-rows: 200px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.article-grid {
|
|
grid-template-columns: 1fr;
|
|
grid-auto-rows: 220px;
|
|
}
|
|
}
|
|
</style>
|