parent
ca0708ab46
commit
cf26debab4
6 changed files with 93 additions and 132 deletions
@ -1,39 +0,0 @@ |
||||
import { |
||||
ResizableHandle, |
||||
ResizablePanel, |
||||
ResizablePanelGroup, |
||||
} from '../Resizable'; |
||||
import { SqlCodeEditor } from '../SqlCodeEditor/SqlCodeEditor'; |
||||
import type { ReactNode } from 'react'; |
||||
import type { LessonFileType } from '../../lib/course'; |
||||
import { LessonView } from './LessonView'; |
||||
|
||||
type ChallengeViewProps = { |
||||
lesson: LessonFileType; |
||||
children: ReactNode; |
||||
}; |
||||
|
||||
export function ChallengeView(props: ChallengeViewProps) { |
||||
const { children, lesson } = props; |
||||
|
||||
const { frontmatter } = lesson; |
||||
const { defaultValue, initSteps, expectedResults } = frontmatter; |
||||
|
||||
return ( |
||||
<ResizablePanelGroup direction="horizontal"> |
||||
<ResizablePanel defaultSize={60} minSize={20}> |
||||
<LessonView>{children}</LessonView> |
||||
</ResizablePanel> |
||||
|
||||
<ResizableHandle withHandle={true} /> |
||||
|
||||
<ResizablePanel defaultSize={40} minSize={20}> |
||||
<SqlCodeEditor |
||||
defaultValue={defaultValue} |
||||
initSteps={initSteps} |
||||
expectedResults={expectedResults} |
||||
/> |
||||
</ResizablePanel> |
||||
</ResizablePanelGroup> |
||||
); |
||||
} |
@ -0,0 +1,86 @@ |
||||
import { lazy, type ReactNode } from 'react'; |
||||
import type { LessonFileType } from '../../lib/course'; |
||||
import { CourseLayout, type CourseLayoutProps } from './CourseLayout'; |
||||
import { |
||||
ResizableHandle, |
||||
ResizablePanel, |
||||
ResizablePanelGroup, |
||||
} from '../Resizable'; |
||||
|
||||
const SqlCodeEditor = lazy(() => |
||||
import('../SqlCodeEditor/SqlCodeEditor').then((module) => ({ |
||||
default: module.SqlCodeEditor, |
||||
})), |
||||
); |
||||
|
||||
const QuizView = lazy(() => |
||||
import('./QuizView').then((module) => ({ |
||||
default: module.QuizView, |
||||
})), |
||||
); |
||||
|
||||
type CourseViewProps = Omit<CourseLayoutProps, 'children'> & { |
||||
lesson: LessonFileType; |
||||
children?: ReactNode; |
||||
}; |
||||
|
||||
export function CourseView(props: CourseViewProps) { |
||||
const { lesson, children, ...courseLayoutProps } = props; |
||||
|
||||
const { frontmatter } = lesson; |
||||
const lessonType = frontmatter.type; |
||||
|
||||
const { defaultValue, initSteps, expectedResults } = frontmatter; |
||||
const isTextualLesson = [ |
||||
'lesson', |
||||
'lesson-challenge', |
||||
'lesson-quiz', |
||||
].includes(lessonType); |
||||
|
||||
return ( |
||||
<CourseLayout {...courseLayoutProps}> |
||||
<ResizablePanelGroup direction="horizontal"> |
||||
{children && (isTextualLesson || lessonType === 'challenge') && ( |
||||
<ResizablePanel |
||||
defaultSize={lessonType === 'lesson' ? 100 : 60} |
||||
minSize={20} |
||||
> |
||||
<div className="relative h-full"> |
||||
<div className="absolute inset-0 overflow-y-auto [scrollbar-color:#3f3f46_#27272a;]"> |
||||
<div className="mx-auto max-w-xl p-4"> |
||||
<div className="course-content prose prose-lg prose-invert mt-8 text-zinc-300 prose-headings:mb-3 prose-headings:mt-8 prose-code:text-zinc-100 prose-li:my-1 prose-thead:border-zinc-800 prose-tr:border-zinc-800"> |
||||
{children} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</ResizablePanel> |
||||
)} |
||||
|
||||
{lessonType !== 'lesson' && ( |
||||
<> |
||||
<ResizableHandle withHandle={true} /> |
||||
|
||||
<ResizablePanel |
||||
defaultSize={lessonType === 'quiz' ? 100 : 40} |
||||
minSize={20} |
||||
> |
||||
{(lessonType === 'challenge' || |
||||
lessonType === 'lesson-challenge') && ( |
||||
<SqlCodeEditor |
||||
defaultValue={defaultValue} |
||||
initSteps={initSteps} |
||||
expectedResults={expectedResults} |
||||
/> |
||||
)} |
||||
|
||||
{(lessonType === 'quiz' || lessonType === 'lesson-quiz') && ( |
||||
<QuizView lesson={lesson} /> |
||||
)} |
||||
</ResizablePanel> |
||||
</> |
||||
)} |
||||
</ResizablePanelGroup> |
||||
</CourseLayout> |
||||
); |
||||
} |
@ -1,33 +0,0 @@ |
||||
import { |
||||
ResizableHandle, |
||||
ResizablePanel, |
||||
ResizablePanelGroup, |
||||
} from '../Resizable'; |
||||
import { SqlCodeEditor } from '../SqlCodeEditor/SqlCodeEditor'; |
||||
import type { ReactNode } from 'react'; |
||||
import type { LessonFileType } from '../../lib/course'; |
||||
import { LessonView } from './LessonView'; |
||||
import { QuizView } from './QuizView'; |
||||
|
||||
type LessonQuizViewProps = { |
||||
lesson: LessonFileType; |
||||
children: ReactNode; |
||||
}; |
||||
|
||||
export function LessonQuizView(props: LessonQuizViewProps) { |
||||
const { children, lesson } = props; |
||||
|
||||
return ( |
||||
<ResizablePanelGroup direction="horizontal"> |
||||
<ResizablePanel defaultSize={50} minSize={20}> |
||||
<LessonView>{children}</LessonView> |
||||
</ResizablePanel> |
||||
|
||||
<ResizableHandle withHandle={true} /> |
||||
|
||||
<ResizablePanel defaultSize={50} minSize={20}> |
||||
<QuizView lesson={lesson} /> |
||||
</ResizablePanel> |
||||
</ResizablePanelGroup> |
||||
); |
||||
} |
@ -1,21 +0,0 @@ |
||||
import { type ReactNode } from 'react'; |
||||
|
||||
type LessonViewProps = { |
||||
children: ReactNode; |
||||
}; |
||||
|
||||
export function LessonView(props: LessonViewProps) { |
||||
const { children } = props; |
||||
|
||||
return ( |
||||
<div className="relative h-full"> |
||||
<div className="absolute inset-0 overflow-y-auto [scrollbar-color:#3f3f46_#27272a;]"> |
||||
<div className="mx-auto max-w-xl p-4"> |
||||
<div className="course-content prose prose-lg prose-invert mt-8 text-zinc-300 prose-headings:mb-3 prose-headings:mt-8 prose-code:text-zinc-100 prose-li:my-1 prose-thead:border-zinc-800 prose-tr:border-zinc-800"> |
||||
{children} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
Loading…
Reference in new issue