feat: min/max participants — shared ParticipantLimits component
- New ParticipantLimits component in FormField.tsx (reusable) - Used in both Open Day settings and MC editor — identical layout - Open Day: event-level min/max (DB migration 15) - MC: per-event min/max (JSON fields) - Public: waiting list when full, spots counter, amber success modal
This commit is contained in:
@@ -93,6 +93,7 @@ export function OpenDay({ data }: OpenDayProps) {
|
||||
<ClassCard
|
||||
key={cls.id}
|
||||
cls={cls}
|
||||
maxParticipants={event.maxParticipants}
|
||||
onSignup={setSignup}
|
||||
/>
|
||||
))}
|
||||
@@ -137,9 +138,11 @@ export function OpenDay({ data }: OpenDayProps) {
|
||||
|
||||
function ClassCard({
|
||||
cls,
|
||||
maxParticipants = 0,
|
||||
onSignup,
|
||||
}: {
|
||||
cls: OpenDayClass;
|
||||
maxParticipants?: number;
|
||||
onSignup: (info: { classId: number; label: string }) => void;
|
||||
}) {
|
||||
const label = `${cls.style} · ${cls.trainer} · ${cls.startTime}–${cls.endTime}`;
|
||||
@@ -161,8 +164,10 @@ function ClassCard({
|
||||
);
|
||||
}
|
||||
|
||||
const isFull = maxParticipants > 0 && cls.bookingCount >= maxParticipants;
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-white/10 bg-neutral-900 p-4 transition-all hover:border-gold/20">
|
||||
<div className={`rounded-xl border p-4 transition-all ${isFull ? "border-white/5 bg-neutral-900/50" : "border-white/10 bg-neutral-900 hover:border-gold/20"}`}>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="flex-1 min-w-0">
|
||||
<span className="text-xs text-gold font-medium">{cls.startTime}–{cls.endTime}</span>
|
||||
@@ -171,12 +176,21 @@ function ClassCard({
|
||||
<Users size={10} />
|
||||
{cls.trainer}
|
||||
</p>
|
||||
{maxParticipants > 0 && (
|
||||
<p className={`text-[10px] mt-1 ${isFull ? "text-amber-400" : "text-neutral-500"}`}>
|
||||
{cls.bookingCount}/{maxParticipants} мест
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => onSignup({ classId: cls.id, label })}
|
||||
className="shrink-0 rounded-full bg-gold/10 border border-gold/20 px-4 py-2 text-xs font-medium text-gold hover:bg-gold/20 transition-colors cursor-pointer"
|
||||
className={`shrink-0 rounded-full px-4 py-2 text-xs font-medium transition-colors cursor-pointer ${
|
||||
isFull
|
||||
? "bg-amber-500/10 border border-amber-500/20 text-amber-400 hover:bg-amber-500/20"
|
||||
: "bg-gold/10 border border-gold/20 text-gold hover:bg-gold/20"
|
||||
}`}
|
||||
>
|
||||
Записаться
|
||||
{isFull ? "Лист ожидания" : "Записаться"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user