Merge pull request #96 from Since-3/bug/fix-latest-bugs

Bug/fix latest bugs
This commit is contained in:
Rajpreet0 2026-05-12 19:02:41 +02:00 • committed by GitHub
commit 35c2cf8832
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 40 deletions

View file

@ -41,7 +41,10 @@ export const publishedCourseSchema = z
date: z.string().min(1, "Datum ist erforderlich"),
timeFrom: z.string().min(1, "Anfangszeit ist erforderlich"),
timeTo: z.string().min(1, "Endzeit ist erforderlich"),
trainers: z.array(z.string()).min(1, "Mindestens ein Trainer muss ausgewählt werden"),
trainers: z
.array(z.string())
.min(1, "Mindestens ein Trainer muss ausgewählt werden")
.optional(),
room: z.string().min(1, "Raum ist erforderlich"),
description: z.string().optional(),
maxParticipants: z

View file

@ -2,7 +2,7 @@
import { useState, useEffect } from "react";
import Image from "next/image";
import { Clock, MapPin, Users, Mail, Phone } from "lucide-react";
import { Clock, MapPin, Users, Mail, Phone, DoorOpen, Info } from "lucide-react";
import { Button } from "@/src/components/ui/button";
import { Dialog, DialogContent, DialogTitle } from "@/src/components/ui/dialog";
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
@ -204,25 +204,36 @@ const BookingDialog = ({
</span>
{/* Info rows */}
<div className="flex flex-col gap-2.5 text-sm text-gray-700">
<div className="flex flex-col gap-4 text-sm text-gray-700">
<div className="flex items-center gap-2.5">
<Clock size={15} className="text-gray-400 shrink-0" />
<span>
{course.timeFrom} – {course.timeTo} Uhr
<b>Uhrzeit:</b> {course.timeFrom} – {course.timeTo}
</span>
</div>
{(course.roomName || business?.address) && (
{course.roomName && (
<div className="flex items-center gap-2.5">
<DoorOpen size={15} className="text-gray-400 shrink-0" />
<span>
<b>Raum:</b> {course.roomName}
</span>
</div>
)}
{business?.address && (
<div className="flex items-center gap-2.5">
<MapPin size={15} className="text-gray-400 shrink-0" />
<span>{course.roomName ?? business?.address}</span>
<span>
<b>Ort:</b> {business?.address}
</span>
</div>
)}
<div className="flex items-center gap-2.5">
<Users size={15} className="text-gray-400 shrink-0" />
<span>
Teilnehmer: {safeCurrent}/{safeMax}
<b>Teilnehmer:</b> {safeCurrent}/{safeMax}
{isFull && <span className="ml-2 text-red-600 font-medium">· Ausgebucht</span>}
</span>
</div>
@ -231,7 +242,7 @@ const BookingDialog = ({
<div className="flex items-center gap-2.5">
<Mail size={15} className="text-gray-400 shrink-0" />
<a href={`mailto:${business.email}`} className="hover:underline text-gray-700">
{business.email}
<b>Email:</b> {business.email}
</a>
</div>
)}
@ -246,10 +257,16 @@ const BookingDialog = ({
)}
{course.description && (
<div
className="prose prose-sm max-w-none text-gray-600"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(course.description) }}
/>
<div className="flex items-start gap-2.5">
<Info size={15} className="text-gray-400 shrink-0 mt-0.5" />
<div>
<b>Was Sie beachten sollten:</b>
<div
className="prose prose-sm max-w-none text-gray-600 mt-1"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(course.description) }}
/>
</div>
</div>
)}
</div>
@ -288,7 +305,7 @@ const PublicCourseCard = ({ course, business }: PublicCourseCardProps) => {
const formattedDate = new Date(course.date).toLocaleDateString("de-DE", {
weekday: "long",
year: "numeric",
month: "long",
month: "numeric",
day: "numeric",
});
@ -301,7 +318,10 @@ const PublicCourseCard = ({ course, business }: PublicCourseCardProps) => {
return (
<>
<div className="bg-white border border-gray-200 rounded-xl p-5 shadow-sm hover:shadow-md transition flex flex-col gap-4">
<div
onClick={() => setDialogOpen(true)}
className="bg-white border border-gray-200 rounded-xl p-5 shadow-sm hover:shadow-md transition flex flex-col gap-4"
>
<div className="flex items-center justify-between">
<p className="text-gray-500 text-sm">{formattedDate}</p>
<p className="text-gray-500 text-sm">

View file

@ -123,6 +123,7 @@ const BusinessPublicView = ({
weekday: "long",
day: "numeric",
month: "long",
year: "numeric",
});
return (
@ -148,31 +149,10 @@ const BusinessPublicView = ({
{/* Main content */}
<div className="max-w-6xl mx-auto px-6 py-10">
{/* Datum + Sport-Tabs — über beiden Spalten */}
<div className="mb-4">
<h2 className="text-2xl font-semibold text-gray-900 mb-1">{formattedSelectedDate}</h2>
{allSports.length > 1 && (
<div className="flex flex-wrap gap-2 mt-3">
{allSports.map((sport) => (
<button
key={sport}
onClick={() => setActiveSport(sport)}
className={`px-4 py-1.5 rounded-full text-sm font-medium transition-colors ${
resolvedSport === sport
? "bg-gray-900 text-white"
: "bg-white border border-gray-200 text-gray-600 hover:border-gray-400"
}`}
>
{sport === "Alle" ? "Alle" : capitalize(sport)}
</button>
))}
</div>
)}
</div>
<div className="flex flex-col lg:flex-row gap-8 lg:items-start">
{/* Standing calendar */}
{/* Left: sticky calendar */}
<div className="lg:sticky lg:top-6 shrink-0 w-full lg:w-auto">
<h2 className="text-2xl font-semibold text-gray-900 mb-3">{formattedSelectedDate}</h2>
<div className="bg-white border border-gray-200 rounded-xl shadow-sm p-4 flex justify-center">
<Calendar
mode="single"
@ -185,8 +165,30 @@ const BusinessPublicView = ({
</div>
</div>
{/* Courses panel */}
{/* Right: filter + cards */}
<div className="flex-1 min-w-0">
{/* Filter bündig mit Kalender-Oberkante (gleiche mb wie h2 links) */}
<div className="mb-4 mt-11">
{allSports.length > 1 && (
<div className="flex flex-wrap gap-2 mt-3">
{allSports.map((sport) => (
<button
key={sport}
onClick={() => setActiveSport(sport)}
className={`px-4 py-1.5 rounded-full text-sm font-medium transition-colors ${
resolvedSport === sport
? "bg-gray-900 text-white"
: "bg-white border border-gray-200 text-gray-600 hover:border-gray-400"
}`}
>
{sport === "Alle" ? "Alle" : capitalize(sport)}
</button>
))}
</div>
)}
</div>
{/* Courses */}
{isPending ? (
<div className="flex justify-center py-16">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500" />

View file

@ -195,8 +195,6 @@ const CourseCreateView = ({
newErrors.timeTo = "Endzeit muss nach der Anfangszeit liegen";
}
if (trainers.length > 0 && selectedTrainers.length === 0)
newErrors.trainers = "Mindestens ein Trainer muss ausgewählt werden";
if (!selectedRoom) newErrors.room = "Raum ist erforderlich";
const maxPart = parseInt(maxParticipants);