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'; import { AccountNotFound } from '~/components/account-not-found'; 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 ; 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 */}

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 */}
Kurstag
Frei
Heute
{/* 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'}
))}
)}
); }