310 lines
14 KiB
TypeScript
310 lines
14 KiB
TypeScript
import React, { useRef, useState, useEffect } from "react";
|
|
import { ArrowDown, Check, BookOpen, AlertTriangle, Zap } from "lucide-react";
|
|
import EvidenceHunterWidget, {
|
|
type EvidenceExercise,
|
|
} from "../../../components/lessons/EvidenceHunterWidget";
|
|
import { PracticeFromDataset } from "../../../components/lessons/LessonShell";
|
|
import {
|
|
TEXT_STRUCTURE_EASY,
|
|
TEXT_STRUCTURE_MEDIUM,
|
|
} from "../../../data/rw/text-structure-purpose";
|
|
|
|
interface LessonProps {
|
|
onFinish?: () => void;
|
|
}
|
|
|
|
const EVIDENCE_EXERCISES: EvidenceExercise[] = [
|
|
{
|
|
question: "What is the primary purpose of sentence 4 in this passage?",
|
|
passage: [
|
|
"Automation has already transformed manufacturing, eliminating millions of repetitive assembly-line jobs over the past three decades.",
|
|
"Optimists argue that, just as industrialization created new types of work, AI will generate new categories of employment.",
|
|
"Economists at the Brookings Institution project that 36 million American jobs face high exposure to automation within the next decade.",
|
|
"Yet history offers a cautionary note: the transition from agricultural to industrial economies, though ultimately beneficial, caused decades of widespread unemployment and social upheaval.",
|
|
"Without deliberate policy intervention, the current transition may prove equally disruptive.",
|
|
],
|
|
evidenceIndex: 3,
|
|
explanation:
|
|
'Sentence 4 serves to qualify and complicate the optimists\' argument in sentence 2 — it concedes that historical transitions were ultimately beneficial, but shows they were also extremely disruptive. This is a "concession and complication" move. On the SAT, look for words like "yet," "however," "though" that signal this function.',
|
|
},
|
|
{
|
|
question:
|
|
"Which sentence most clearly establishes the author's central perspective in this passage?",
|
|
passage: [
|
|
"In 1905, Einstein published four papers that would revolutionize physics.",
|
|
"Among them was the special theory of relativity, which overturned Newtonian mechanics that had stood unchallenged for over 200 years.",
|
|
"Physicists at the time were deeply skeptical — the implications were simply too radical to accept without extensive verification.",
|
|
"Science, at its best, is not a collection of fixed truths but an evolving conversation shaped by evidence, argument, and the occasional genius willing to question everything.",
|
|
"Einstein's annus mirabilis remains the most dramatic example of this process in modern science.",
|
|
],
|
|
evidenceIndex: 3,
|
|
explanation:
|
|
"Sentence 4 is where the author steps back from narrating events to state their own perspective on what science is: an evolving conversation. This is a craft move — transitioning from historical account to authorial commentary. The SAT often places the author's stated viewpoint in the middle or end of a passage, not the beginning.",
|
|
},
|
|
{
|
|
question: "What is the structural function of sentence 2 in this passage?",
|
|
passage: [
|
|
"Digital misinformation spreads with unprecedented speed on social media platforms.",
|
|
"A landmark MIT study found that false news spreads six times faster on Twitter than true news.",
|
|
"The researchers attribute this difference to the novelty and emotional resonance of misinformation — falsehoods are simply more surprising and engaging than accurate reporting.",
|
|
"This poses serious challenges for democracies that depend on an informed citizenry.",
|
|
"Platform companies and legislators are still struggling to find effective interventions.",
|
|
],
|
|
evidenceIndex: 1,
|
|
explanation:
|
|
"Sentence 2 provides specific quantitative evidence (the MIT study) to support the claim made in sentence 1. Its function is to substantiate — to give a concrete, credible example that proves the opening assertion. On SAT craft questions, sentences that cite studies, statistics, or expert sources typically function as evidence or support.",
|
|
},
|
|
];
|
|
|
|
const EBRWCraftStructureLesson: React.FC<LessonProps> = ({ 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 = (i: number) => {
|
|
setActiveSection(i);
|
|
sectionsRef.current[i]?.scrollIntoView({ behavior: "smooth" });
|
|
};
|
|
|
|
const SectionMarker = ({
|
|
index,
|
|
title,
|
|
icon: Icon,
|
|
}: {
|
|
index: number;
|
|
title: string;
|
|
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
|
|
}) => {
|
|
const isActive = activeSection === index;
|
|
const isPast = activeSection > index;
|
|
return (
|
|
<button
|
|
onClick={() => scrollToSection(index)}
|
|
className={`flex items-center gap-3 p-3 w-full rounded-lg text-left transition-all ${isActive ? "bg-fuchsia-50" : "hover:bg-slate-50"}`}
|
|
>
|
|
<div
|
|
className={`w-8 h-8 rounded-full flex items-center justify-center shrink-0 ${isActive ? "bg-fuchsia-600 text-white" : isPast ? "bg-fuchsia-400 text-white" : "bg-slate-200 text-slate-500"}`}
|
|
>
|
|
{isPast ? (
|
|
<Check className="w-4 h-4" />
|
|
) : (
|
|
<Icon className="w-4 h-4" />
|
|
)}
|
|
</div>
|
|
<p
|
|
className={`text-sm font-bold ${isActive ? "text-fuchsia-900" : "text-slate-600"}`}
|
|
>
|
|
{title}
|
|
</p>
|
|
</button>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col lg:flex-row min-h-screen">
|
|
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
|
|
<nav className="space-y-2 pt-6">
|
|
<SectionMarker index={0} title="Craft & Purpose" icon={BookOpen} />
|
|
<SectionMarker
|
|
index={1}
|
|
title="Evidence Hunter"
|
|
icon={AlertTriangle}
|
|
/>
|
|
<SectionMarker index={2} title="Practice Quiz" icon={Zap} />
|
|
</nav>
|
|
</aside>
|
|
|
|
<div className="flex-1 lg:ml-64 p-6 md:p-12 max-w-4xl mx-auto">
|
|
{/* Section 0: Craft & Purpose */}
|
|
<section
|
|
ref={(el) => {
|
|
sectionsRef.current[0] = el;
|
|
}}
|
|
className="min-h-screen flex flex-col justify-center mb-24 pt-20 lg:pt-0"
|
|
>
|
|
<div className="inline-flex items-center gap-2 bg-fuchsia-100 text-fuchsia-700 px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider mb-4">
|
|
Craft & Structure
|
|
</div>
|
|
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
|
|
Craft & Purpose
|
|
</h2>
|
|
<p className="text-lg text-slate-500 mb-8">
|
|
SAT craft questions ask WHY the author made a choice — not WHAT the
|
|
text says. Master the four analytical lenses below to handle every
|
|
question type.
|
|
</p>
|
|
|
|
{/* Rule Grid */}
|
|
<div className="rounded-2xl p-6 mb-8 bg-fuchsia-50 border border-fuchsia-200 space-y-5">
|
|
<h3 className="text-lg font-bold text-fuchsia-900">
|
|
Four Analytical Lenses
|
|
</h3>
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
{[
|
|
{
|
|
title: "Author's Purpose",
|
|
body: "Why did the author include THIS paragraph, sentence, or detail? Options: to introduce, contrast, provide evidence, concede, qualify, or conclude.",
|
|
},
|
|
{
|
|
title: "Transition Function",
|
|
body: "What does this sentence DO in relation to what came before? Contrast? Continuation? Consequence?",
|
|
},
|
|
{
|
|
title: "Point of View",
|
|
body: "What is the narrator's or author's perspective? First person (I/we) vs. third person (objective or omniscient).",
|
|
},
|
|
{
|
|
title: "Rhetorical Effect",
|
|
body: "How does the author create impact? Through analogy, anecdote, expert citation, rhetorical question, or repetition?",
|
|
},
|
|
].map((rule, i) => (
|
|
<div
|
|
key={i}
|
|
className="bg-white rounded-xl p-4 border border-fuchsia-100"
|
|
>
|
|
<p className="text-sm font-bold text-fuchsia-800 mb-1">
|
|
{rule.title}
|
|
</p>
|
|
<p className="text-xs text-slate-600 leading-relaxed">
|
|
{rule.body}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Static annotation visual */}
|
|
<div className="rounded-2xl p-6 mb-8 bg-fuchsia-50 border border-fuchsia-200 space-y-3">
|
|
<h3 className="text-lg font-bold text-fuchsia-900 mb-1">
|
|
How to Annotate a Craft Question
|
|
</h3>
|
|
<div className="bg-fuchsia-100 rounded-xl p-4 border border-fuchsia-200">
|
|
<p className="text-xs font-bold text-fuchsia-800 mb-1">
|
|
Question type:
|
|
</p>
|
|
<p className="text-sm text-fuchsia-900">
|
|
"The main purpose of the third paragraph is to..."
|
|
</p>
|
|
</div>
|
|
<div className="bg-green-100 rounded-xl p-4 border border-green-200">
|
|
<p className="text-xs font-bold text-green-800 mb-1">Strategy:</p>
|
|
<p className="text-sm text-green-900">
|
|
Read the paragraph. Then ask: does it introduce an idea, provide
|
|
evidence, counter an argument, or conclude?
|
|
</p>
|
|
</div>
|
|
<div className="bg-orange-100 rounded-xl p-4 border border-orange-200">
|
|
<p className="text-xs font-bold text-orange-800 mb-1">Trap:</p>
|
|
<p className="text-sm text-orange-900">
|
|
Confusing a detail's FUNCTION with its CONTENT. "To describe X"
|
|
is content. "To provide evidence for the claim in paragraph 2"
|
|
is function.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Trap callout */}
|
|
<div className="bg-red-50 border border-red-200 rounded-xl p-5 mb-8">
|
|
<p className="text-sm font-bold text-red-800 mb-1">
|
|
SAT Craft Question Trap
|
|
</p>
|
|
<p className="text-sm text-slate-700">
|
|
SAT craft questions ask WHY the author made a choice, not WHAT the
|
|
text says. Always frame your thinking in terms of author intent.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Golden Rule */}
|
|
<div className="bg-fuchsia-900 rounded-2xl p-6 mb-8">
|
|
<p className="text-xs font-bold text-fuchsia-300 uppercase tracking-wider mb-2">
|
|
Golden Rule
|
|
</p>
|
|
<p className="text-base font-bold text-white">
|
|
Every element has a structural job. Identify it: introduce,
|
|
evidence, concede, contrast, conclude, qualify, or illustrate.
|
|
</p>
|
|
</div>
|
|
|
|
<button
|
|
onClick={() => scrollToSection(1)}
|
|
className="mt-4 group flex items-center text-fuchsia-600 font-bold hover:text-fuchsia-800 transition-colors"
|
|
>
|
|
Next: Evidence Hunter{" "}
|
|
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
|
</button>
|
|
</section>
|
|
|
|
{/* Section 1: Evidence Hunter */}
|
|
<section
|
|
ref={(el) => {
|
|
sectionsRef.current[1] = el;
|
|
}}
|
|
className="min-h-screen flex flex-col justify-center mb-24"
|
|
>
|
|
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
|
|
Evidence Hunter
|
|
</h2>
|
|
<p className="text-lg text-slate-500 mb-8">
|
|
Read each passage. Identify the sentence that serves the stated
|
|
structural purpose, then reveal the explanation.
|
|
</p>
|
|
<EvidenceHunterWidget
|
|
exercises={EVIDENCE_EXERCISES}
|
|
accentColor="fuchsia"
|
|
/>
|
|
<button
|
|
onClick={() => scrollToSection(2)}
|
|
className="mt-12 group flex items-center text-fuchsia-600 font-bold hover:text-fuchsia-800 transition-colors"
|
|
>
|
|
Next: Practice Quiz{" "}
|
|
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
|
</button>
|
|
</section>
|
|
|
|
{/* Section 2: Practice Quiz */}
|
|
<section
|
|
ref={(el) => {
|
|
sectionsRef.current[2] = el;
|
|
}}
|
|
className="min-h-screen flex flex-col justify-center mb-24"
|
|
>
|
|
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
|
Practice Quiz
|
|
</h2>
|
|
{TEXT_STRUCTURE_EASY.slice(0, 2).map((q) => (
|
|
<PracticeFromDataset key={q.id} question={q} color="fuchsia" />
|
|
))}
|
|
{TEXT_STRUCTURE_MEDIUM.slice(0, 1).map((q) => (
|
|
<PracticeFromDataset key={q.id} question={q} color="fuchsia" />
|
|
))}
|
|
<div className="mt-8 text-center">
|
|
<button
|
|
onClick={onFinish}
|
|
className="px-6 py-3 bg-fuchsia-900 text-white font-bold rounded-full hover:bg-fuchsia-700 transition-colors"
|
|
>
|
|
Finish Lesson
|
|
</button>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default EBRWCraftStructureLesson;
|