import Link from 'next/link';
import { ArrowLeft, ChevronLeft, ChevronRight } from 'lucide-react';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import { createCourseManagementApi } from '@kit/course-management/api';
import { CmsPageShell } from '~/components/cms-page-shell';
interface PageProps {
params: Promise<{ account: string }>;
}
const WEEKDAYS = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'];
const MONTH_NAMES = [
'Januar',
'Februar',
'März',
'April',
'Mai',
'Juni',
'Juli',
'August',
'September',
'Oktober',
'November',
'Dezember',
];
function getDaysInMonth(year: number, month: number): number {
return new Date(year, month + 1, 0).getDate();
}
function getFirstWeekday(year: number, month: number): number {
const day = new Date(year, month, 1).getDay();
return day === 0 ? 6 : day - 1;
}
export default async function CourseCalendarPage({ params }: PageProps) {
const { account } = await params;
const client = getSupabaseServerClient();
const { data: acct } = await client
.from('accounts')
.select('id')
.eq('slug', account)
.single();
if (!acct) return
Konto nicht gefunden
;
const api = createCourseManagementApi(client);
const courses = await api.listCourses(acct.id, { page: 1, pageSize: 100 });
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const daysInMonth = getDaysInMonth(year, month);
const firstWeekday = getFirstWeekday(year, month);
// Build set of days that have running courses
const courseDates = new Set();
for (const course of courses.data) {
const c = course as Record;
if (c.status === 'cancelled') continue;
const startDate = c.start_date ? new Date(String(c.start_date)) : null;
const endDate = c.end_date ? new Date(String(c.end_date)) : null;
if (!startDate) continue;
const courseStart = startDate;
const courseEnd = endDate ?? startDate;
for (let d = 1; d <= daysInMonth; d++) {
const dayDate = new Date(year, month, d);
if (dayDate >= courseStart && dayDate <= courseEnd) {
courseDates.add(d);
}
}
}
// Build calendar grid
const cells: Array<{ day: number | null; hasCourse: boolean; isToday: boolean }> = [];
for (let i = 0; i < firstWeekday; i++) {
cells.push({ day: null, hasCourse: false, isToday: false });
}
for (let d = 1; d <= daysInMonth; d++) {
cells.push({
day: d,
hasCourse: courseDates.has(d),
isToday: d === now.getDate() && month === now.getMonth() && year === now.getFullYear(),
});
}
while (cells.length % 7 !== 0) {
cells.push({ day: null, hasCourse: false, isToday: false });
}
const activeCourses = courses.data.filter(
(c: Record) =>
c.status === 'open' || c.status === 'running',
);
return (
{/* Header */}
Kurskalender
Kurstermine im Überblick
{/* Month Calendar */}
{MONTH_NAMES[month]} {year}
{/* Weekday Header */}
{WEEKDAYS.map((day) => (
{day}
))}
{/* Calendar Grid */}
{cells.map((cell, idx) => (
{cell.day !== null && (
<>
{cell.day}
{cell.hasCourse && (
)}
>
)}
))}
{/* Legend */}
{/* Active Courses this Month */}
Aktive Kurse ({activeCourses.length})
{activeCourses.length === 0 ? (
Keine aktiven Kurse in diesem Monat.
) : (
{activeCourses.map((course: Record
) => (
{String(course.name)}
{course.start_date
? new Date(String(course.start_date)).toLocaleDateString('de-DE')
: '—'}{' '}
–{' '}
{course.end_date
? new Date(String(course.end_date)).toLocaleDateString('de-DE')
: '—'}
{String(course.status) === 'running' ? 'Laufend' : 'Offen'}
))}
)}
);
}