-
{g.type}
-
- {g.merged.map((m, mi) => (
-
-
- {m.days.join(", ")}
- {m.times.join(", ")}
-
- ))}
-
-
-
- {g.location} · {g.address.replace(/^г\.\s*\S+,\s*/, "")}
-
- {g.level && (
-
{g.level}
- )}
- {g.recruiting && (
-
- Набор открыт
-
- )}
-
+
+ setBookingGroup(`${g.type}, ${g.merged.map(m => m.days.join("/")).join(", ")} ${g.merged[0]?.times[0] ?? ""}`)}
+ />
))}
diff --git a/src/components/ui/GroupCard.tsx b/src/components/ui/GroupCard.tsx
new file mode 100644
index 0000000..1e1dea3
--- /dev/null
+++ b/src/components/ui/GroupCard.tsx
@@ -0,0 +1,124 @@
+import { MapPin } from "lucide-react";
+import { shortAddress } from "@/components/sections/schedule/constants";
+
+export interface GroupCardSlot {
+ days: string[];
+ times: string[];
+}
+
+export interface GroupCardProps {
+ type: string;
+ level?: string;
+ recruiting?: boolean;
+ hasSlots?: boolean;
+ address?: string;
+ location?: string;
+ merged: GroupCardSlot[];
+ dotColor?: string;
+ /** Compact mode for small cards (e.g. trainer bio scroll row) */
+ compact?: boolean;
+ /** Show location badge */
+ showLocation?: boolean;
+ /** Extra badges (e.g. "Сегодня") rendered after level badge */
+ extraBadges?: React.ReactNode;
+ /** Click handler for type name (e.g. filter toggle in schedule) */
+ onTypeClick?: () => void;
+ /** Click handler for book button */
+ onBook?: () => void;
+}
+
+export function GroupCard({
+ type,
+ level,
+ recruiting,
+ hasSlots,
+ address,
+ location,
+ merged,
+ dotColor = "bg-gold",
+ compact = false,
+ showLocation = true,
+ extraBadges,
+ onTypeClick,
+ onBook,
+}: GroupCardProps) {
+ const dot = compact ? "h-2 w-2" : "h-2.5 w-2.5";
+ const typeCls = compact ? "text-xs" : "text-sm";
+ const dayPad = compact ? "px-1.5 py-px text-[10px] min-w-[40px]" : "px-2 py-0.5 text-[11px] min-w-[52px]";
+ const timeCls = compact ? "text-xs" : "text-sm font-medium";
+ const badgeSize = compact ? "px-2 py-0.5 text-[9px]" : "px-2.5 py-0.5 text-[10px]";
+ const locSize = compact ? "px-2 py-0.5 text-[9px]" : "px-2.5 py-0.5 text-[10px]";
+ const locIcon = compact ? 8 : 9;
+
+ const levelBadge = level ? (
+
+ {level}
+
+ ) : null;
+
+ const typeContent = (
+ <>
+
+
{type}
+ {levelBadge}
+ >
+ );
+
+ return (
+
+ {/* Type + level + status badges + extras */}
+
+ {onTypeClick ? (
+
+ ) : (
+ {typeContent}
+ )}
+ {hasSlots && (
+
+ есть места
+
+ )}
+ {recruiting && (
+
+ набор
+
+ )}
+ {showLocation && (address || location) && (
+
+
+ {shortAddress(address || location || "")}
+
+ )}
+ {extraBadges}
+
+
+ {/* Schedule rows */}
+
+ {merged.map((m, i) => (
+
+
+ {m.days.join(", ")}
+
+
+ {m.times.join(", ")}
+
+
+ ))}
+
+
+ {/* Book button */}
+ {onBook && (
+ compact ? (
+
+ ) : null
+ )}
+
+ );
+}