"use client"; import { useId, useMemo, useState } from "react"; import type { StageSectionConfig, SelectOption } from "@/types/form"; import type { UseFormRegister, FieldValues, FieldErrors } from "react-hook-form"; import { FieldRenderer } from "./fields/FieldRenderer"; import { MatrixGroup } from "./MatrixGroup"; import { evaluate } from "@/lib/conditional"; interface StageSectionProps { section: StageSectionConfig; register: UseFormRegister; errors: FieldErrors; /** Live form values, used to evaluate per-field visibility rules. */ formValues: Record; /** Whether this is the section that matches the current org stage (for the "current" badge). */ isCurrent: boolean; /** Whether the section starts open. */ defaultOpen: boolean; /** Option groups fetched from CiviCRM, keyed by option_group_id. */ options: Record; } /** * One accordion card per stage section. Renders all fields whose individual * visibility rules pass. The section's own visibility is decided by the * parent EngagementForm; if rendered, it's visible. */ export function StageSection({ section, register, errors, formValues, isCurrent, defaultOpen, options, }: StageSectionProps) { const [open, setOpen] = useState(defaultOpen); const headingId = useId(); const panelId = useId(); // Names of fields that appear inside any matrix group; excluded from the // standalone per-field grid so they don't render twice. const matrixFieldNames = useMemo(() => { const names = new Set(); for (const m of section.matrixGroups ?? []) { for (const row of m.rows) for (const f of row.fields) names.add(f); } return names; }, [section.matrixGroups]); const visibleFields = section.fields.filter( (f) => evaluate(f.visibleWhen, formValues) && !matrixFieldNames.has(f.name), ); return (

); } function RankBadge({ rank, isCurrent }: { rank: number; isCurrent: boolean }) { return ( {rank} ); } function Chevron({ open }: { open: boolean }) { return ( ); }