import React, { useRef, useState, useEffect } from "react"; import { ArrowDown, Check, BookOpen, AlertTriangle, Zap } from "lucide-react"; import { PracticeFromDataset } from "../../../components/lessons/LessonShell"; import { FORM_STRUCTURE_EASY, FORM_STRUCTURE_MEDIUM, } from "../../../data/rw/form-structure-sense"; import ClauseBreakdownWidget, { type ClauseExample, } from "../../../components/lessons/ClauseBreakdownWidget"; import DecisionTreeWidget, { type TreeScenario, type TreeNode, } from "../../../components/lessons/DecisionTreeWidget"; interface LessonProps { onFinish?: () => void; } // ── Clause Breakdown data ────────────────────────────────────────────────── const CLAUSE_EXAMPLES: ClauseExample[] = [ { title: "Parallel Structure — List", segments: [ { text: "The program requires", type: "subject", label: "Subject + Verb", }, { text: " attending lectures", type: "conjunction", label: "Gerund: ✓" }, { text: ",", type: "punct" }, { text: " completing assignments", type: "conjunction", label: "Gerund: ✓", }, { text: ",", type: "punct" }, { text: " and", type: "conjunction", label: "FANBOYS" }, { text: " passing the final exam", type: "conjunction", label: "Gerund: ✓ — all match", }, { text: ".", type: "punct" }, ], }, { title: "Misplaced Modifier", segments: [ { text: "Running through the park", type: "modifier", label: "Modifier: describes who is running", }, { text: ",", type: "punct" }, { text: " the sunset", type: "subject", label: "⚠ 'The sunset' can't run — modifier is misplaced!", }, { text: " was beautiful", type: "verb", label: "" }, { text: ".", type: "punct" }, ], }, { title: "Dangling Modifier — Fixed", segments: [ { text: "Running through the park", type: "modifier", label: "Modifier: describes who is running", }, { text: ",", type: "punct" }, { text: " she", type: "subject", label: "✓ 'She' is the one running — modifier now matches", }, { text: " watched the sunset", type: "verb", label: "" }, { text: ".", type: "punct" }, ], }, ]; // ── Decision Tree data ───────────────────────────────────────────────────── const STRUCTURE_TREE: TreeNode = { id: "root", question: "Is this a PARALLELISM or MODIFIER problem?", hint: "Parallelism: a list where elements don't match in form. Modifier: a descriptive phrase that's attached to the wrong noun.", yesLabel: "Parallelism — list items don't match", noLabel: "Modifier — descriptive phrase in wrong place", yes: { id: "parallelism", question: "What grammatical form do MOST items in the list use?", hint: "Identify the form of the majority: nouns? gerunds (-ing)? infinitives (to-)? adjectives?", yesLabel: "Gerunds (-ing forms) dominate", noLabel: "Nouns, infinitives, or adjectives dominate", yes: { id: "parallel-gerunds", result: "✓ Convert ALL list items to gerunds (-ing). 'The program requires attending, completing, and passing' — all match.", resultType: "correct", ruleRef: "[verb]-ing, [verb]-ing, and [verb]-ing", }, no: { id: "parallel-other", question: "Are the items a mix of infinitives (to-verb) and other forms?", yesLabel: "Yes — some 'to-verb', some don't match", noLabel: "No — nouns or adjectives are mixed", yes: { id: "parallel-infinitives", result: "✓ Convert ALL list items to infinitives (to + verb): 'to attend, to complete, and to pass.'", resultType: "correct", ruleRef: "to [verb], to [verb], and to [verb]", }, no: { id: "parallel-nouns", result: "✓ Make all items the same part of speech — all nouns, all adjectives, or all the same structure. The parallelism rule: match the form of the first item.", resultType: "correct", ruleRef: "[noun], [noun], and [noun] — all same form", }, }, }, no: { id: "modifier", question: "Is the modifier at the BEGINNING of the sentence (before the comma)?", hint: "Opening modifiers like 'Running through the park,' must be immediately followed by the noun/pronoun they describe.", yesLabel: "Yes — opens the sentence before a comma", noLabel: "No — modifier is elsewhere in the sentence", yes: { id: "opening-modifier", question: "Does the word immediately AFTER the comma refer to who/what is doing the action in the modifier?", yesLabel: "Yes — it matches", noLabel: "No — it doesn't make sense (dangling modifier)", yes: { id: "modifier-correct", result: "✓ The modifier is correctly placed. It immediately precedes the noun it describes.", resultType: "correct", ruleRef: "[Modifier phrase], [the noun it describes] [verb]...", }, no: { id: "dangling-modifier", result: "⚠ Dangling modifier! The noun after the comma must be the one performing the action in the phrase. Fix: rewrite so the correct subject follows the comma.", resultType: "warning", ruleRef: "Fix: '[Modifier], [WHO is doing it] [verb]'", }, }, no: { id: "mid-sentence-modifier", result: "⚠ Misplaced modifier! The modifier should be placed immediately next to what it describes. Move it closer to the word it modifies.", resultType: "warning", ruleRef: "Place modifier directly next to the word it describes", }, }, }; const TREE_SCENARIOS: TreeScenario[] = [ { label: "Sentence 1", sentence: "The program requires attending lectures, to complete assignments, and passing the final.", tree: STRUCTURE_TREE, }, { label: "Sentence 2", sentence: "Having reviewed all the evidence, a verdict was reached by the jury.", tree: STRUCTURE_TREE, }, { label: "Sentence 3", sentence: "She enjoys hiking, to read, and cooking on weekends.", tree: STRUCTURE_TREE, }, ]; // ── Lesson component ─────────────────────────────────────────────────────── const EBRWSentenceStructureLesson: React.FC = ({ onFinish }) => { const [activeSection, setActiveSection] = useState(0); const sectionsRef = useRef<(HTMLElement | null)[]>([]); useEffect(() => { const observers: IntersectionObserver[] = []; sectionsRef.current.forEach((el, idx) => { if (!el) return; const obs = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) setActiveSection(idx); }, { threshold: 0.3 }, ); obs.observe(el); observers.push(obs); }); return () => observers.forEach((o) => o.disconnect()); }, []); const scrollToSection = (index: number) => { setActiveSection(index); sectionsRef.current[index]?.scrollIntoView({ behavior: "smooth" }); }; const SectionMarker = ({ index, title, icon: Icon, }: { index: number; title: string; icon: React.ElementType; }) => { const isActive = activeSection === index; const isPast = activeSection > index; return ( ); }; return (
{/* Section 0 — Concept + Clause Breakdown */}
{ sectionsRef.current[0] = el; }} className="min-h-screen flex flex-col justify-center mb-24 pt-20 lg:pt-0" >
Standard English Conventions

Sentence Structure

See how sentences are built — then learn exactly where parallelism breaks and modifiers go wrong.

{/* Rule summary grid */}
{[ { num: 1, rule: "Parallelism in Lists", desc: "All list items must match: all gerunds, all infinitives, all nouns, etc.", }, { num: 2, rule: "Parallel Comparisons", desc: "'more X than Y' — X and Y must be the same type (comparing like to like).", }, { num: 3, rule: "Opening Modifier Rule", desc: "The noun immediately after a comma must be what the modifier describes.", }, { num: 4, rule: "Squinting Modifiers", desc: "A modifier must be placed unambiguously next to what it modifies.", }, ].map((r) => (
{r.num} {r.rule}

{r.desc}

))}
{/* Clause Breakdown */}

Sentence Anatomy

Hover over any colored span to see its label. Use the tabs to switch between examples.

{/* SAT Traps */}

Common SAT Traps

{[ { label: "Subtle Parallelism Break", desc: "'researching, to analyze, and write' — the break ('to analyze') looks acceptable but breaks the gerund pattern.", }, { label: "Dangling Modifier", desc: "'Having reviewed the evidence, a verdict was reached' — the verdict didn't review anything. The jury did.", }, { label: "Squinting Modifier", desc: "A modifier placed between two clauses so it's unclear which one it modifies.", }, ].map((t) => (

{t.label}

{t.desc}

))}

Golden Rule

Parallel structure and modifiers both follow one principle: every part of a sentence must connect clearly and consistently to what it describes or lists. Mismatch in form or placement = SAT error.

{/* Section 1 — Decision Tree */}
{ sectionsRef.current[1] = el; }} className="min-h-screen flex flex-col justify-center mb-24" >

Decision Tree Lab

Work through the grammar logic one question at a time. Click your answer at each step.

{/* Section 2 — Quiz */}
{ sectionsRef.current[2] = el; }} className="min-h-screen flex flex-col justify-center mb-24" >

Practice Questions

{FORM_STRUCTURE_EASY.slice(6, 8).map((q) => ( ))} {FORM_STRUCTURE_MEDIUM.slice(3, 4).map((q) => ( ))}
); }; export default EBRWSentenceStructureLesson;