cdrdpyj/src/pages/[locale]/[section]/index.astro

242 lines
9.5 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 DynamicForm from "@/components/forms/DynamicForm.vue";
import { createTranslator, getRouteKeyFromSlug } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
const { locale, section } = Astro.params;
const routeKey = getRouteKeyFromSlug(section);
if (routeKey === "formulario") {
if (!["es", "en", "pt"].includes(Astro.currentLocale)) {
return Astro.redirect(`/${Astro.currentLocale}/`);
}
} else if (routeKey === "terminos") {
// rendered client-side
} else {
var items = await getCollection(routeKey, (post)=>{
const currentLocale = Astro.currentLocale;
return post.data.locale == currentLocale
});
var 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)
});
var 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() : [];
var allYears = routeKey === "news" ? [...new Set(
sortedPosts.map(p => new Date(p.data.date).getFullYear())
)].sort((a, b) => b - a) : [];
}
---
<MainLayout title={routeKey === "formulario" ? tl("form.page_title") : routeKey === "terminos" ? tl("terminos.title") : undefined}>
{routeKey === "formulario" && (
<div class="pt-16 relative container mx-auto">
<Header />
</div>
)}
{routeKey !== "formulario" && (
<div class="top-16 relative mb container mx-auto">
<Header />
</div>
)}
{routeKey === "formulario" && (
<main class="min-h-screen py-16 px-4">
<div class="md:container mx-auto">
<h1 class="text-3xl lg:text-4xl font-bold font-secondary text-[#EBE6D2] text-center mb-4 md:mb-9">
{tl("form.page_title")}
</h1>
<DynamicForm client:load locale={Astro.currentLocale} turnstileSiteKey={import.meta.env.TURNSTILE_SITE_KEY} />
</div>
</main>
)}
{routeKey === "terminos" && (
<main class="min-h-screen py-16 px-4">
<div class="md:container mx-auto">
<h1 class="text-3xl lg:text-4xl font-bold font-secondary text-[#EBE6D2] text-center mb-4 md:mb-9">
{tl("terminos.title")}
</h1>
<div id="reglamento-content" class="reglamento-content bg-white p-6 md:p-10 max-w-4xl mx-auto" data-locale={Astro.currentLocale}>
<p class="text-gray-500 text-center">{tl("terminos.text")}...</p>
</div>
</div>
</main>
)}
{routeKey !== "formulario" && routeKey !== "terminos" && (
<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 hideContact={routeKey === "formulario"} />
</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();
});
}
}
const reglamentoContainer = document.getElementById('reglamento-content');
if (reglamentoContainer) {
const locale = reglamentoContainer.dataset.locale || 'es';
const locales = [locale, 'es'];
(async () => {
for (const l of locales) {
try {
const res = await fetch(`/reglamento/${l}.html`);
if (res.ok) {
reglamentoContainer.innerHTML = await res.text();
return;
}
} catch {}
}
reglamentoContainer.innerHTML = '<p class="text-red-500 text-center">Error al cargar el reglamento</p>';
})();
}
document.addEventListener('astro:page-load', () => {
initTags();
initYearFilter();
});
if (document.readyState === 'complete') {
initTags();
initYearFilter();
}
</script>