feat(lessons): add lessons from client db
This commit is contained in:
309
src/pages/student/lessons/EBRWCraftStructureLesson.tsx
Normal file
309
src/pages/student/lessons/EBRWCraftStructureLesson.tsx
Normal file
@ -0,0 +1,309 @@
|
||||
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.ElementType;
|
||||
}) => {
|
||||
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;
|
||||
Reference in New Issue
Block a user