From f29dbe0c9f4325a67ba8234f9dad6a171d4922cc Mon Sep 17 00:00:00 2001 From: "diana.dolgolyova" Date: Sun, 15 Mar 2026 22:54:15 +0300 Subject: [PATCH] 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 --- src/components/sections/team/TeamProfile.tsx | 66 +++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/components/sections/team/TeamProfile.tsx b/src/components/sections/team/TeamProfile.tsx index 857807a..de92cb6 100644 --- a/src/components/sections/team/TeamProfile.tsx +++ b/src/components/sections/team/TeamProfile.tsx @@ -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(); + // Extract trainer's groups from schedule using groupId + const groupMap = new Map(); 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(); + 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(); + 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) => (

{g.type}

-
- - {g.days.join(", ")} · {g.time} +
+ {g.merged.map((m, mi) => ( +
+ + {m.days.join(", ")} + {m.times.join(", ")} +
+ ))}
@@ -198,7 +244,7 @@ export function TeamProfile({ member, onBack, schedule }: TeamProfileProps) { )}