46 lines
1.5 KiB
JavaScript
46 lines
1.5 KiB
JavaScript
import React, { useEffect, useRef } from 'react';
|
|
import Card from '../ui/Card';
|
|
|
|
export default function ConceptExplainer({ content, onComplete }) {
|
|
const containerRef = useRef(null);
|
|
|
|
// Trigger completion when scrolled to the end
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
if (!containerRef.current) return;
|
|
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
|
if (scrollTop + clientHeight >= scrollHeight - 50) {
|
|
onComplete();
|
|
}
|
|
};
|
|
|
|
// Check initially in case content is short and doesn't need scrolling
|
|
if (containerRef.current && containerRef.current.scrollHeight <= containerRef.current.clientHeight) {
|
|
onComplete();
|
|
}
|
|
|
|
const currentRef = containerRef.current;
|
|
currentRef?.addEventListener('scroll', handleScroll);
|
|
return () => currentRef?.removeEventListener('scroll', handleScroll);
|
|
}, [onComplete]);
|
|
|
|
return (
|
|
<Card className="w-full h-[60vh] flex flex-col p-0">
|
|
<div className="p-6 border-b border-bg-warm">
|
|
<h2 className="text-xl font-bold">Concept Explainer</h2>
|
|
</div>
|
|
<div
|
|
className="flex-1 overflow-y-auto p-6 prose dark:prose-invert"
|
|
ref={containerRef}
|
|
>
|
|
{content?.sections?.map((section, i) => (
|
|
<div key={i} className="mb-6">
|
|
<h3>{section.title}</h3>
|
|
<div dangerouslySetInnerHTML={{ __html: section.content }} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|