From 8154a59014688c771d631009ebf95e95dc4a9075 Mon Sep 17 00:00:00 2001 From: Tudor Sitaru Date: Thu, 16 Apr 2026 09:11:47 +0100 Subject: [PATCH] fix(compare): prevent auto-phase from overriding manual tab selection Once the user explicitly clicks a phase tab, suppress auto-phase detection so switching to Secondary (or Primary) can't be snapped back by the effect that fires when comparisonData re-fetches. Co-Authored-By: Claude Sonnet 4.6 --- nextjs-app/components/ComparisonView.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nextjs-app/components/ComparisonView.tsx b/nextjs-app/components/ComparisonView.tsx index 6d3bcd8..abacf69 100644 --- a/nextjs-app/components/ComparisonView.tsx +++ b/nextjs-app/components/ComparisonView.tsx @@ -5,7 +5,7 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { useRouter, usePathname, useSearchParams } from 'next/navigation'; import { useComparison } from '@/hooks/useComparison'; import { ComparisonChart } from './ComparisonChart'; @@ -59,6 +59,9 @@ export function ComparisonView({ const [comparisonData, setComparisonData] = useState(initialData); const [shareConfirm, setShareConfirm] = useState(false); const [comparePhase, setComparePhase] = useState<'primary' | 'secondary'>('primary'); + // Tracks whether the user has explicitly clicked a phase tab. + // While true, auto-phase detection is suppressed so manual selections aren't overridden. + const phaseLockedByUser = useRef(false); // Seed context from initialData when component mounts and localStorage is empty useEffect(() => { @@ -124,6 +127,7 @@ export function ComparisonView({ // needs to follow, otherwise all secondary cards show "–" for a primary-only field. useEffect(() => { if (!comparisonData || selectedSchools.length === 0) return; + if (phaseLockedByUser.current) return; const newPhase = secondarySchools.length > primarySchools.length ? 'secondary' : 'primary'; setComparePhase(newPhase); // Only reset the metric when it doesn't belong to the newly detected phase. @@ -138,6 +142,7 @@ export function ComparisonView({ }, [comparisonData]); // eslint-disable-line react-hooks/exhaustive-deps const handlePhaseChange = (phase: 'primary' | 'secondary') => { + phaseLockedByUser.current = true; setComparePhase(phase); const defaultMetric = phase === 'secondary' ? 'attainment_8_score' : 'rwm_expected_pct'; setSelectedMetric(defaultMetric);