site/src/components/competitions/CalendarView.tsx

88 lines
3.4 KiB
TypeScript

"use client";
import React, { useEffect, useState } from "react";
type Event = { title: string; date: string; location?: string; signupUrl?: string; signups?: boolean | "soon" };
export function CalendarView() {
const [events, setEvents] = useState<Event[]>([]);
useEffect(() => {
(async () => {
try {
const res = await fetch("/api/content?path=pt/competicoes/future.json");
const json = await res.json();
setEvents(json.events ?? []);
} catch {}
})();
}, []);
// Parse DD/MM/YYYY format
const parseDate = (dateStr: string) => {
const parts = dateStr.split('/');
if (parts.length === 3) {
return new Date(parseInt(parts[2]), parseInt(parts[1]) - 1, parseInt(parts[0]));
}
return new Date(dateStr);
};
// Simple month grid from provided future events
const byMonth = events.reduce<Record<string, Event[]>>((acc, e) => {
const month = parseDate(e.date).toLocaleString("pt-PT", { month: "long", year: "numeric" });
acc[month] ??= [];
acc[month].push(e);
return acc;
}, {});
return (
<section aria-labelledby="calendar-title">
<h2 id="calendar-title" className="text-xl font-semibold">Calendário</h2>
<div className="grid gap-4 md:grid-cols-2 mt-2">
{Object.entries(byMonth).map(([m, items]) => (
<div key={m} className="border p-3">
<h3 className="font-bold">{m}</h3>
<ul className="mt-2 space-y-1">
{items.map((e, idx) => (
<li key={idx}>
<strong>{e.title}</strong> {parseDate(e.date).toLocaleDateString("pt-PT")}
{e.location && <span className="ml-2">({e.location})</span>}
{e.signups === true && (
<button
onClick={() => window.open(e.signupUrl, '_blank')}
className="ml-2 px-3 py-1 bg-green-600 text-white rounded hover:bg-green-700 transition-colors"
>
Inscrição
</button>
)}
{e.signups === false && (
<div className="ml-2 inline-block">
<button
onClick={() => alert('As inscrições para esta competição estão encerradas')}
className="px-3 py-1 bg-red-300 text-red-700 rounded cursor-not-allowed opacity-70"
title="As inscrições estão encerradas"
>
Inscrição
</button>
<span className="ml-2 text-sm text-red-600">(Encerradas)</span>
</div>
)}
{e.signups === "soon" && (
<div className="ml-2 inline-block">
<button
onClick={() => alert('As inscrições para esta competição abrem em breve')}
className="px-3 py-1 bg-yellow-300 text-yellow-700 rounded cursor-not-allowed opacity-70"
title="As inscrições abrem em breve"
>
Inscrição
</button>
<span className="ml-2 text-sm text-yellow-600">(Em breve)</span>
</div>
)}
</li>
))}
</ul>
</div>
))}
</div>
</section>
);
}