feat: Add event collection and event page structure
All checks were successful
SteamWarCI Build successful

- Introduced a new events collection in config.ts with schema validation.
- Created a new event markdown file for the WarGear event.
- Updated German translations to include new event-related strings.
- Modified PageLayout to support a wide layout option.
- Enhanced announcements page to improve tag filtering and post rendering.
- Implemented dynamic event pages with detailed event information and fight plans.
- Added an index page for events to list all upcoming events.
This commit is contained in:
2025-11-10 12:37:32 +01:00
parent 446e4bb839
commit c3bb62f3fb
26 changed files with 2135 additions and 300 deletions

View File

@@ -1,43 +1,48 @@
---
import {getCollection} from "astro:content";
import { getCollection } from "astro:content";
import PageLayout from "../../layouts/PageLayout.astro";
import {astroI18n, createGetStaticPaths, t} from "astro-i18n";
import { astroI18n, createGetStaticPaths, t } from "astro-i18n";
import PostComponent from "../../components/PostComponent.astro";
import dayjs from "dayjs";
import TagComponent from "../../components/TagComponent.astro";
import SWPaginator from "@components/styled/SWPaginator.svelte";
export const getStaticPaths = createGetStaticPaths(async (props) => {
const posts = await getCollection("announcements", entry => entry.id.split("/")[0] === astroI18n.locale);
const posts = await getCollection("announcements", (entry) => entry.id.split("/")[0] === astroI18n.locale);
const germanPosts = await getCollection("announcements", entry => entry.id.split("/")[0] === astroI18n.fallbackLocale);
const germanPosts = await getCollection("announcements", (entry) => entry.id.split("/")[0] === astroI18n.fallbackLocale);
germanPosts.forEach(value => {
if (posts.find(post => post.data.key === value.data.key)) {
germanPosts.forEach((value) => {
if (posts.find((post) => post.data.key === value.data.key)) {
return;
} else {
posts.push(value);
}
});
return props.paginate(posts.sort((a, b) => dayjs(b.data.created).unix() - dayjs(a.data.created).unix()), {
pageSize: 5,
});
return props.paginate(
posts.sort((a, b) => dayjs(b.data.created).unix() - dayjs(a.data.created).unix()),
{
pageSize: 5,
}
);
});
async function getTags() {
const posts = await getCollection("announcements");
const tags = new Map<string, number>();
posts.forEach(post => {
post.data.tags.forEach(tag => {
if (tags.has(tag)) {
tags.set(tag, tags.get(tag) + 1);
posts.forEach((post) => {
post.data.tags.forEach((tag) => {
if (tags.has(tag.toLowerCase())) {
tags.set(tag.toLowerCase(), tags.get(tag) + 1);
} else {
tags.set(tag, 1);
tags.set(tag.toLowerCase(), 1);
}
});
});
return Array.from(tags).sort((a, b) => b[1] - a[1]).map(value => value[0]);
return Array.from(tags)
.sort((a, b) => b[1] - a[1])
.map((value) => value[0]);
}
const { page } = Astro.props;
@@ -46,15 +51,15 @@ const tags = await getTags();
<PageLayout title={t("blog.title")}>
<div class="py-2">
{tags.map(tag => (
<TagComponent tag={tag} transition:name={`${tag}-tag-filter`} />
))}
{tags.map((tag) => <TagComponent tag={tag} transition:name={`${tag}-tag-filter`} />)}
</div>
{page.data.map((post) => (
<div>
<PostComponent post={post}/>
</div>
))}
{
page.data.map((post) => (
<div>
<PostComponent post={post} />
</div>
))
}
<SWPaginator
maxPage={page.lastPage}
page={page.currentPage - 1}
@@ -62,6 +67,6 @@ const tags = await getTags();
previousUrl={page.url.prev}
firstUrl={page.url.first}
lastUrl={page.url.last}
pagesUrl={(i) => i == 0 ? page.url.first : page.currentPage === page.lastPage ? page.url.current.replace(page.lastPage, i + 1) : page.url.last.replace(page.lastPage, i + 1)}
pagesUrl={(i) => (i == 0 ? page.url.first : page.currentPage === page.lastPage ? page.url.current.replace(page.lastPage, i + 1) : page.url.last.replace(page.lastPage, i + 1))}
/>
</PageLayout>
</PageLayout>