Spaces:
Running
Running
| import { useState } from 'react'; | |
| import { useForm } from '../../context/FormContext'; | |
| import FillBlank from '../fields/FillBlank'; | |
| import CheckboxGroup from '../fields/CheckboxGroup'; | |
| import ExerciseList from '../fields/ExerciseList'; | |
| import TextInput from '../fields/TextInput'; | |
| import StaticText from '../fields/StaticText'; | |
| import { ChevronDown, ChevronRight } from 'lucide-react'; | |
| import * as Icons from 'lucide-react'; | |
| function getIcon(name, size = 20) { | |
| const Icon = Icons[name]; | |
| return Icon ? <Icon size={size} /> : null; | |
| } | |
| function FieldRenderer({ field, sectionId }) { | |
| switch (field.type) { | |
| case 'fill-blank': | |
| return <FillBlank field={field} sectionId={sectionId} />; | |
| case 'checkbox-group': | |
| return <CheckboxGroup field={field} sectionId={sectionId} />; | |
| case 'exercise-list': | |
| return <ExerciseList field={field} sectionId={sectionId} />; | |
| case 'text': | |
| case 'number': | |
| return <TextInput field={field} sectionId={sectionId} />; | |
| case 'static': | |
| return <StaticText field={field} />; | |
| default: | |
| return null; | |
| } | |
| } | |
| export default function SectionRenderer({ section }) { | |
| const { formState, toggleSection } = useForm(); | |
| const isEnabled = formState.enabledSections[section.id] !== false; | |
| const [collapsedSubs, setCollapsedSubs] = useState({}); | |
| const toggleSubsection = (subId) => { | |
| setCollapsedSubs(prev => ({ ...prev, [subId]: !prev[subId] })); | |
| }; | |
| return ( | |
| <div className="section" id={`section-${section.id}`}> | |
| <div className="section__header"> | |
| <div className="section__header-icon"> | |
| {getIcon(section.icon, 20)} | |
| </div> | |
| <h2 className="section__title">{section.title}</h2> | |
| {section.cptCode && ( | |
| <span className="section__cpt">{section.cptCode}</span> | |
| )} | |
| <div className="section__toggle"> | |
| <div | |
| className={`toggle-switch ${isEnabled ? 'toggle-switch--active' : ''}`} | |
| onClick={() => toggleSection(section.id)} | |
| role="switch" | |
| aria-checked={isEnabled} | |
| title={isEnabled ? 'Disable section' : 'Enable section'} | |
| /> | |
| </div> | |
| </div> | |
| <div className={!isEnabled ? 'section-disabled' : ''}> | |
| {section.subsections.map(sub => { | |
| const isCollapsed = collapsedSubs[sub.id]; | |
| return ( | |
| <div className="subsection" key={sub.id} id={`subsection-${sub.id}`}> | |
| <button | |
| className="collapsible-trigger" | |
| onClick={() => toggleSubsection(sub.id)} | |
| type="button" | |
| > | |
| <span className="subsection__title" style={{ margin: 0 }}> | |
| <span className="subsection__title-dot" /> | |
| {sub.title} | |
| </span> | |
| <span className={`collapsible-trigger__icon ${!isCollapsed ? 'collapsible-trigger__icon--open' : ''}`}> | |
| <ChevronDown size={16} /> | |
| </span> | |
| </button> | |
| {!isCollapsed && ( | |
| <div style={{ paddingTop: 'var(--space-3)' }}> | |
| {sub.fields.map(field => ( | |
| <FieldRenderer | |
| key={field.id} | |
| field={field} | |
| sectionId={section.id} | |
| /> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| ); | |
| } | |