fix: use groupId for trainer bio schedule groups

Group extraction now uses groupId (from admin panel) instead of
type+time heuristic, with mergeSlotsByDay for proper day/time display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-15 22:54:15 +03:00
parent 340a1d2f7f
commit f29dbe0c9f

View File

@@ -37,24 +37,65 @@ export function TeamProfile({ member, onBack, schedule }: TeamProfileProps) {
const hasExperience = member.experience && member.experience.length > 0;
const hasEducation = member.education && member.education.length > 0;
// Extract trainer's groups from schedule, grouped by type + time + location
const groupMap = new Map<string, { type: string; time: string; location: string; address: string; days: string[]; level?: string; recruiting?: boolean }>();
// Extract trainer's groups from schedule using groupId
const groupMap = new Map<string, { type: string; location: string; address: string; slots: { day: string; dayShort: string; time: string }[]; level?: string; recruiting?: boolean }>();
schedule?.forEach(location => {
location.days.forEach(day => {
day.classes
.filter(c => c.trainer === member.name)
.forEach(c => {
const key = `${c.type}|${c.time}|${location.name}`;
const key = c.groupId
? `${c.groupId}||${location.name}`
: `${c.trainer}||${c.type}||${location.name}`;
const existing = groupMap.get(key);
if (existing) {
if (!existing.days.includes(day.dayShort)) existing.days.push(day.dayShort);
existing.slots.push({ day: day.day, dayShort: day.dayShort, time: c.time });
if (c.level && !existing.level) existing.level = c.level;
if (c.recruiting) existing.recruiting = true;
} else {
groupMap.set(key, { type: c.type, time: c.time, location: location.name, address: location.address, days: [day.dayShort], level: c.level, recruiting: c.recruiting });
groupMap.set(key, {
type: c.type,
location: location.name,
address: location.address,
slots: [{ day: day.day, dayShort: day.dayShort, time: c.time }],
level: c.level,
recruiting: c.recruiting,
});
}
});
});
});
const uniqueGroups = Array.from(groupMap.values());
const uniqueGroups = Array.from(groupMap.values()).map(g => {
// Merge slots by day, then merge days with identical time sets
const dayMap = new Map<string, { dayShort: string; times: string[] }>();
const dayOrder: string[] = [];
for (const s of g.slots) {
const existing = dayMap.get(s.day);
if (existing) {
if (!existing.times.includes(s.time)) existing.times.push(s.time);
} else {
dayMap.set(s.day, { dayShort: s.dayShort, times: [s.time] });
dayOrder.push(s.day);
}
}
for (const entry of dayMap.values()) entry.times.sort();
const merged: { days: string[]; times: string[] }[] = [];
const used = new Set<string>();
for (const day of dayOrder) {
if (used.has(day)) continue;
const entry = dayMap.get(day)!;
const timeKey = entry.times.join("|");
const days = [entry.dayShort];
used.add(day);
for (const other of dayOrder) {
if (used.has(other)) continue;
const o = dayMap.get(other)!;
if (o.times.join("|") === timeKey) { days.push(o.dayShort); used.add(other); }
}
merged.push({ days, times: entry.times });
}
return { ...g, merged };
});
const hasGroups = uniqueGroups.length > 0;
const hasBio = hasVictories || hasExperience || hasEducation || hasGroups;
@@ -181,9 +222,14 @@ export function TeamProfile({ member, onBack, schedule }: TeamProfileProps) {
{uniqueGroups.map((g, i) => (
<div key={i} className="w-48 shrink-0 rounded-xl border border-white/[0.08] bg-white/[0.03] p-3 space-y-1.5">
<p className="text-xs font-semibold uppercase tracking-wider text-white/80">{g.type}</p>
<div className="flex items-center gap-1.5 text-xs text-white/50">
<Clock size={11} />
{g.days.join(", ")} · {g.time}
<div className="space-y-0.5">
{g.merged.map((m, mi) => (
<div key={mi} className="flex items-center gap-1.5 text-xs text-white/50">
<Clock size={11} className="shrink-0" />
<span className="font-medium text-white/70">{m.days.join(", ")}</span>
<span>{m.times.join(", ")}</span>
</div>
))}
</div>
<div className="flex items-start gap-1.5 text-xs text-white/40">
<MapPin size={11} className="mt-0.5 shrink-0" />
@@ -198,7 +244,7 @@ export function TeamProfile({ member, onBack, schedule }: TeamProfileProps) {
</span>
)}
<button
onClick={() => setBookingGroup(`${g.type}, ${g.days.join("/")} ${g.time}`)}
onClick={() => setBookingGroup(`${g.type}, ${g.merged.map(m => m.days.join("/")).join(", ")} ${g.merged[0]?.times[0] ?? ""}`)}
className="w-full mt-1 rounded-lg bg-gold/15 border border-gold/25 py-1.5 text-[11px] font-semibold text-gold hover:bg-gold/25 transition-colors cursor-pointer"
>
Записаться