180 lines
6.9 KiB
Plaintext
180 lines
6.9 KiB
Plaintext
---
|
|
import MainLayout from "@/layouts/MainLayout.astro"
|
|
import Header from "@/components/Header.astro"
|
|
import NewsList from "@/components/cards/NewsList.astro";
|
|
import { getCollection } from "astro:content";
|
|
import FooterSection from "@/components/section/FooterSection.astro";
|
|
|
|
import { createTranslator, getRouteKeyFromSlug } from '@/i18n';
|
|
const tl = createTranslator(Astro.currentLocale);
|
|
|
|
const { locale, section } = Astro.params;
|
|
const routeKey = getRouteKeyFromSlug(section);
|
|
|
|
const items = await getCollection(routeKey, (post)=>{
|
|
const currentLocale = Astro.currentLocale;
|
|
return post.data.locale == currentLocale
|
|
});
|
|
|
|
const sortedPosts = [...items]
|
|
.sort((a, b) => {
|
|
const dateDiff = new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
|
|
if (dateDiff !== 0) return dateDiff
|
|
return (a.data.order ?? 0) - (b.data.order ?? 0)
|
|
});
|
|
|
|
const allTags = routeKey === "news" ? [...new Set(
|
|
sortedPosts
|
|
.filter(p => p.data.tags && p.data.tags.length > 0)
|
|
.flatMap(p => p.data.tags)
|
|
.filter((tag): tag is string => tag !== undefined)
|
|
)].sort() : [];
|
|
|
|
const allYears = routeKey === "news" ? [...new Set(
|
|
sortedPosts.map(p => new Date(p.data.date).getFullYear())
|
|
)].sort((a, b) => b - a) : [];
|
|
---
|
|
|
|
<MainLayout >
|
|
<div class="top-16 relative mb container mx-auto">
|
|
<Header />
|
|
</div>
|
|
<div class="container mx-auto mt-4">
|
|
<div class="flex flex-col lg:w-1/2 items-center mx-auto py-8">
|
|
<h1 class="text-white text-2xl uppercase font-bold text-center mb-4 font-primary md:mt-20 mt-10">{tl(routeKey + ".title")}</h1>
|
|
<h2 class="text-white text-3xl lg:text-5xl font-bold text-center font-secondary mb-4 md:p-0 px-2">{tl(routeKey + ".text")}</h2>
|
|
</div>
|
|
|
|
|
|
{routeKey === "news" && allTags.length > 0 && (
|
|
<div class="container mx-auto mb-8 px-4 md:px-0">
|
|
<div class="flex flex-nowrap md:flex-wrap gap-2 md:justify-center overflow-x-auto md:overflow-visible pb-2 md:pb-0">
|
|
<button class="filter-btn px-4 py-2 font-primary text-sm cursor-pointer transition-colors whitespace-nowrap" data-tag="all">
|
|
{tl("news.all")}
|
|
</button>
|
|
{allTags.map((tag) => (
|
|
<button class="filter-btn px-4 py-2 font-primary text-sm cursor-pointer transition-colors whitespace-nowrap" data-tag={tag!}>
|
|
{tag}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div class="flex flex-col md:gap-0 gap-2 lg:max-w-4xl mx-auto bg-white p-4 md:p-8">
|
|
{routeKey === "news" && allYears.length > 0 && (
|
|
<div class="container mb-4">
|
|
<div class="flex justify-start md:justify-end">
|
|
<select id="year-filter" class="bg-[#003421] text-[#EBE5D0] px-4 py-2 font-primary text-sm cursor-pointer border-none outline-none">
|
|
<option value="all">{tl("news.allYears")}</option>
|
|
{allYears.map((year) => (
|
|
<option value={year}>{year}</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{
|
|
sortedPosts.map((item) => (
|
|
<div class="news-item" data-tags={routeKey === "news" ? JSON.stringify(item.data.tags || []) : "[]"} data-year={routeKey === "news" ? new Date(item.data.date).getFullYear() : ""}>
|
|
<NewsList data={item} content={{ body: item.body }} routeKey={routeKey} />
|
|
</div>
|
|
))
|
|
}
|
|
</div>
|
|
</div>
|
|
<FooterSection />
|
|
|
|
</MainLayout>
|
|
|
|
<script>
|
|
const activeClasses = "bg-[#003421] text-[#EBE5D0]";
|
|
const inactiveClasses = "bg-[#003421]/20 text-[#EBE5D0] hover:bg-[#003421]/30";
|
|
|
|
let currentTag: string | null = 'all';
|
|
let currentYear: string = 'all';
|
|
|
|
function filterItems() {
|
|
document.querySelectorAll('.news-item').forEach(item => {
|
|
const itemTags = JSON.parse(item.getAttribute('data-tags') || '[]');
|
|
const itemYear = item.getAttribute('data-year');
|
|
|
|
const tagMatch = currentTag === 'all' || currentTag === null || itemTags.includes(currentTag);
|
|
const yearMatch = currentYear === 'all' || itemYear === currentYear;
|
|
|
|
if (tagMatch && yearMatch) {
|
|
(item as HTMLElement).style.display = 'block';
|
|
} else {
|
|
(item as HTMLElement).style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
function activateTag(tag: string | null) {
|
|
currentTag = tag;
|
|
document.querySelectorAll('.filter-btn').forEach(b => {
|
|
if (b.getAttribute('data-tag') === tag) {
|
|
b.classList.remove(...inactiveClasses.split(" "));
|
|
b.classList.add(...activeClasses.split(" "));
|
|
} else {
|
|
b.classList.remove(...activeClasses.split(" "));
|
|
b.classList.add(...inactiveClasses.split(" "));
|
|
}
|
|
});
|
|
filterItems();
|
|
}
|
|
|
|
function updateUrl(tag: string | null) {
|
|
const url = new URL(window.location.href);
|
|
if (tag && tag !== 'all') {
|
|
url.searchParams.set('tag', tag);
|
|
} else {
|
|
url.searchParams.delete('tag');
|
|
}
|
|
window.history.replaceState({}, '', url.toString());
|
|
}
|
|
|
|
function initTags() {
|
|
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
btn.classList.add(...inactiveClasses.split(" "));
|
|
});
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
if (urlParams.has('tag')) {
|
|
urlParams.delete('tag');
|
|
window.history.replaceState({}, '', window.location.pathname + window.location.search);
|
|
}
|
|
|
|
document.querySelector('.filter-btn[data-tag="all"]')?.classList.add(...activeClasses.split(" "));
|
|
document.querySelector('.filter-btn[data-tag="all"]')?.classList.remove(...inactiveClasses.split(" "));
|
|
activateTag('all');
|
|
|
|
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
const tag = btn.getAttribute('data-tag');
|
|
activateTag(tag);
|
|
updateUrl(tag);
|
|
});
|
|
});
|
|
}
|
|
|
|
function initYearFilter() {
|
|
const yearSelect = document.querySelector('#year-filter') as HTMLSelectElement;
|
|
if (yearSelect) {
|
|
yearSelect.addEventListener('change', () => {
|
|
currentYear = yearSelect.value;
|
|
filterItems();
|
|
});
|
|
}
|
|
}
|
|
|
|
document.addEventListener('astro:page-load', () => {
|
|
initTags();
|
|
initYearFilter();
|
|
});
|
|
if (document.readyState === 'complete') {
|
|
initTags();
|
|
initYearFilter();
|
|
}
|
|
</script>
|