Files
school_compare/nextjs-app/components/school/sectionShared.tsx
T
TudorandClaude Opus 5 a7f6ff4035 refactor(detail): extract sections as server components
Moves ~1,300 lines of section markup out of the two client views into
components/school/, mirroring the components/compare/ layout. Twelve section
components plus shared primitives, all server components. The only client
file is AdmissionsViewToggle, which owns the hidden/aria-pressed state and
receives both views as server-rendered children.

JSX was extracted mechanically rather than retyped, so the markup the CSS
modules depend on is verbatim.

Sharing follows measured similarity, not assumption:
- Finances (91%) shared. The secondary premises-cost card is gated behind a
  prop so primary pages are unchanged; enabling it is a one-line follow-up.
- Ofsted (80%) shared, but behind a variant prop. The headline similarity hid
  a real fork: on a school with no overall grade the primary page shows a
  "Not rated" badge while the secondary shows a four-area OEIF panel, and the
  disclaimer copy differs. Both preserved exactly; reconciling them is a
  human decision, not a side effect of a move.
- Admissions (14%) and History (40%) kept separate.

Not yet wired up -- the old views still render.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:33:28 +01:00

44 lines
1.3 KiB
TypeScript

/**
* Shared primitives for the school detail sections, mirroring
* components/compare/sectionShared.tsx.
*
* Deliberately minimal: the sections were extracted as verbatim moves from the
* two detail views, so wrapping their markup in heavyweight primitives would
* risk changing the DOM the CSS modules depend on. This provides only the
* outer <section> shell every section shares, plus the stylesheet.
*
* All section components are SERVER components — no 'use client' anywhere in
* this directory except AdmissionsViewToggle.
*/
import type { ReactNode } from 'react';
import styles from './schoolSections.module.css';
export const sectionStyles = styles;
/** Tone class for a progress score: positive, negative, or neutral. */
export function progressClass(val: number | null | undefined): string {
if (val == null) return '';
if (val > 0) return styles.progressPositive;
if (val < 0) return styles.progressNegative;
return '';
}
/**
* The section shell. `id` must match the id buildNavItems emits, because the
* sticky nav's scroll-spy locates sections with document.getElementById.
*/
export function Section({
id,
children,
}: {
id: string;
children: ReactNode;
}) {
return (
<section id={id} className={styles.card}>
{children}
</section>
);
}