From c39256b1a0ff61f700ec6fe16fc8e29d21b748ce Mon Sep 17 00:00:00 2001 From: Tudor Sitaru Date: Thu, 16 Apr 2026 16:06:21 +0100 Subject: [PATCH] feat(home): sort countdown chips by days remaining, fade in after hydration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chips now sort soonest-first at hydration time so the most urgent deadline always appears first. The rail is hidden (opacity 0) until the useEffect populates and sorts the chips, then fades in — avoiding any visible layout shift from the reorder. Co-Authored-By: Claude Sonnet 4.6 --- nextjs-app/components/HomeView.tsx | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/nextjs-app/components/HomeView.tsx b/nextjs-app/components/HomeView.tsx index ebdbc01..8c8bd89 100644 --- a/nextjs-app/components/HomeView.tsx +++ b/nextjs-app/components/HomeView.tsx @@ -77,7 +77,9 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp const mapParamsRef = useRef(''); const [geoState, setGeoState] = useState<'idle' | 'requesting' | 'error'>('idle'); const [geoError, setGeoError] = useState(null); - const [chipDays, setChipDays] = useState<(number | null)[]>(ADMISSIONS_CHIPS.map(() => null)); + const [sortedChips, setSortedChips] = useState>( + ADMISSIONS_CHIPS.map(c => ({ chip: c, days: null })) + ); const hasSearch = searchParams.get('search') || searchParams.get('postcode'); const isLocationSearch = !!searchParams.get('postcode'); @@ -140,9 +142,11 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp .catch(() => {}); }, []); - // Compute admissions countdown days client-side to avoid SSR mismatch + // Compute admissions countdown days client-side and sort soonest-first to avoid SSR mismatch useEffect(() => { - setChipDays(ADMISSIONS_CHIPS.map(c => daysUntil(c.month, c.day))); + const withDays = ADMISSIONS_CHIPS.map(c => ({ chip: c, days: daysUntil(c.month, c.day) })); + withDays.sort((a, b) => (a.days ?? Infinity) - (b.days ?? Infinity)); + setSortedChips(withDays); }, []); const handleLoadMore = async () => { @@ -292,9 +296,14 @@ export function HomeView({ initialSchools, filters, totalSchools }: HomeViewProp Key admissions deadlines Full admissions guide → -
- {ADMISSIONS_CHIPS.map((chip, i) => { - const days = chipDays[i]; +
+ {sortedChips.map(({ chip, days }) => { const isUrgent = days !== null && days <= 14; const chipClass = [ styles.countdownChip,