fix: clickable trainers in day cards, remove trainer dropdown, fix layout shift

- Remove trainer dropdown from filter bar — filter by clicking names in schedule cards
- Make trainer/type clickable in DayCard with gold highlight on active filter
- Fix showcase layout shift: track max detail height to prevent section from shrinking
- Remove key-based grid remount that re-triggered Reveal animations on filter change

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 21:52:56 +03:00
parent 46ad10e8a0
commit 03f0524ba3
2 changed files with 28 additions and 10 deletions

View File

@@ -283,7 +283,6 @@ export function Schedule({ data: schedule, classItems }: ScheduleProps) {
{/* Desktop: grid layout */}
<Reveal>
<div
key={`${locationMode}-${filterTrainer}-${filterType}-${filterStatus}`}
className={`mt-8 hidden sm:grid grid-cols-1 gap-3 px-4 sm:px-6 lg:px-8 xl:px-6 ${filteredDays.length >= 7 ? "sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-7" : filteredDays.length >= 6 ? "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6" : filteredDays.length >= 4 ? "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5" : filteredDays.length === 3 ? "sm:grid-cols-2 lg:grid-cols-3" : filteredDays.length === 2 ? "sm:grid-cols-2" : "justify-items-center"}`}
style={filteredDays.length === 1 ? undefined : filteredDays.length <= 3 && filteredDays.length > 0 ? { maxWidth: filteredDays.length * 340 + (filteredDays.length - 1) * 12, marginInline: "auto" } : undefined}
>

View File

@@ -25,10 +25,24 @@ export function ShowcaseLayout<T>({
const selectorRef = useRef<HTMLDivElement>(null);
const activeItemRef = useRef<HTMLButtonElement>(null);
const detailRef = useRef<HTMLDivElement>(null);
const detailWrapRef = useRef<HTMLDivElement>(null);
const [minHeight, setMinHeight] = useState<number | undefined>(undefined);
const measuredHeights = useRef<number[]>([]);
const [isUserInteracting, setIsUserInteracting] = useState(false);
const [displayIndex, setDisplayIndex] = useState(activeIndex);
const [fading, setFading] = useState(false);
// Track max height across all seen items to prevent shrinking
useEffect(() => {
if (!detailRef.current || fading) return;
const h = detailRef.current.offsetHeight;
measuredHeights.current[displayIndex] = h;
const maxH = Math.max(...measuredHeights.current.filter(Boolean));
if (maxH > (minHeight ?? 0)) {
setMinHeight(maxH);
}
}, [displayIndex, fading]);
useEffect(() => {
if (activeIndex === displayIndex) return;
setFading(true);
@@ -115,6 +129,10 @@ export function ShowcaseLayout<T>({
>
{/* Detail area */}
<div className="lg:w-[60%]">
<div
ref={detailWrapRef}
style={minHeight != null ? { minHeight } : undefined}
>
<div
ref={detailRef}
className={`transition-all duration-300 ease-out ${
@@ -127,6 +145,7 @@ export function ShowcaseLayout<T>({
>
{renderDetail(items[displayIndex], displayIndex)}
</div>
</div>
{/* Counter */}
{counter && (