fix: update current lesson store

feat/course
Arik Chakma 1 month ago
parent e11ac4bf84
commit ac1da1be10
  1. 34
      src/components/Course/CourseLayout.tsx
  2. 14
      src/components/Course/QuizView.tsx
  3. 15
      src/components/SqlCodeEditor/SqlCodeEditor.tsx
  4. 9
      src/lib/course.ts
  5. 13
      src/stores/course.ts

@ -1,13 +1,13 @@
import { ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';
import { CourseSidebar, type CourseSidebarProps } from './CourseSidebar';
import { useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import {
useCompleteLessonMutation,
useCourseProgress,
} from '../../hooks/use-course';
import { NextLessonAlertModal } from './NextLessonAlertModal';
import { useStore } from '@nanostores/react';
import { lessonSubmitStatus } from '../../stores/course';
import { currentLesson } from '../../stores/course';
import { getPercentage } from '../../helper/number';
type CourseLayoutProps = {
@ -18,7 +18,7 @@ export function CourseLayout(props: CourseLayoutProps) {
const { children, ...sidebarProps } = props;
const { chapters, courseId, chapterId, lessonId, lesson } = sidebarProps;
const $lessonSubmitStatus = useStore(lessonSubmitStatus);
const $currentLesson = useStore(currentLesson);
const [showNextWarning, setShowNextWarning] = useState(false);
const { data: courseProgress } = useCourseProgress(courseId);
@ -85,6 +85,21 @@ export function CourseLayout(props: CourseLayoutProps) {
);
};
useEffect(() => {
if ($currentLesson) {
return;
}
currentLesson.set({
courseId,
chapterId,
lessonId,
lessonType: lesson.frontmatter.type,
challengeStatus: 'pending',
quizStatus: 'pending',
});
}, [$currentLesson]);
return (
<>
{showNextWarning && (
@ -123,9 +138,18 @@ export function CourseLayout(props: CourseLayoutProps) {
<button
className="flex items-center gap-1 rounded-lg border border-zinc-800 px-2 py-1.5 text-sm leading-none disabled:opacity-60"
onClick={() => {
const isQuizPending =
($currentLesson?.lessonType === 'lesson-quiz' ||
$currentLesson?.lessonType === 'quiz') &&
$currentLesson?.quizStatus === 'pending';
const isChallengePending =
($currentLesson?.lessonType === 'lesson-challenge' ||
$currentLesson?.lessonType === 'challenge') &&
$currentLesson?.challengeStatus === 'pending';
if (
$lessonSubmitStatus === 'idle' &&
lesson?.frontmatter?.type !== 'lesson' &&
(isQuizPending || isChallengePending) &&
!isCurrentLessonCompleted
) {
setShowNextWarning(true);

@ -2,7 +2,8 @@ import { useState } from 'react';
import { Circle, CircleCheck, CircleX } from 'lucide-react';
import { cn } from '../../lib/classname';
import type { LessonFileType } from '../../lib/course';
import { lessonSubmitStatus } from '../../stores/course';
import { currentLesson } from '../../stores/course';
import { useStore } from '@nanostores/react';
type QuizViewProps = {
lesson: LessonFileType;
@ -18,6 +19,7 @@ export function QuizView(props: QuizViewProps) {
Record<number, number | undefined>
>({});
const $currentLesson = useStore(currentLesson);
const [isSubmitted, setIsSubmitted] = useState(false);
const isAllAnswered =
@ -80,7 +82,15 @@ export function QuizView(props: QuizViewProps) {
disabled={isSubmitted || !isAllAnswered}
onClick={() => {
setIsSubmitted(true);
lessonSubmitStatus.set('submitted');
if (!$currentLesson) {
console.error('FIX: update current lesson');
return;
}
currentLesson.set({
...$currentLesson,
quizStatus: 'correct',
});
}}
>
Submit my Answers

@ -13,7 +13,8 @@ import { keymap } from '@codemirror/view';
import { Check, type LucideIcon, Play, WandSparkles, X } from 'lucide-react';
import { useSqlite } from './use-sqlite';
import { cn } from '../../lib/classname';
import { lessonSubmitStatus } from '../../stores/course';
import { currentLesson } from '../../stores/course';
import { useStore } from '@nanostores/react';
export type SqlCodeEditorProps = {
defaultValue?: string;
@ -25,6 +26,7 @@ export type SqlCodeEditorProps = {
export function SqlCodeEditor(props: SqlCodeEditorProps) {
const { defaultValue, initSteps = [], expectedResults } = props;
const $currentLesson = useStore(currentLesson);
const editorRef = useRef<HTMLDivElement>(null);
const [queryResults, setQueryResults] = useState<QueryExecResult[] | null>(
null,
@ -181,7 +183,16 @@ export function SqlCodeEditor(props: SqlCodeEditorProps) {
setQueryResults(results);
setQueryError(error);
setIsSubmitted(true);
lessonSubmitStatus.set(error ? 'wrong' : 'submitted');
if (!$currentLesson) {
console.error('FIX: update current lesson');
return;
}
currentLesson.set({
...$currentLesson,
challengeStatus: error ? 'wrong' : 'correct',
});
}}
/>
</div>

@ -6,11 +6,18 @@ export interface CourseFrontmatter {
description: string;
}
export type AllowedLessonType =
| 'lesson'
| 'challenge'
| 'quiz'
| 'lesson-challenge'
| 'lesson-quiz';
export type LessonFrontmatter = {
title: string;
description: string;
order: number;
type: 'lesson' | 'challenge' | 'quiz' | 'lesson-challenge' | 'lesson-quiz';
type: AllowedLessonType;
defaultValue?: string;
initSteps?: string[];

@ -1,4 +1,13 @@
import { atom } from 'nanostores';
import type { AllowedLessonType } from '../lib/course';
export type LessonSubmitStatus = 'idle' | 'submitting' | 'submitted' | 'wrong';
export const lessonSubmitStatus = atom<LessonSubmitStatus>('idle');
export type CurrentLessonType = {
courseId: string;
chapterId: string;
lessonId: string;
lessonType: AllowedLessonType;
challengeStatus?: 'pending' | 'wrong' | 'correct';
quizStatus?: 'pending' | 'wrong' | 'correct';
};
export const currentLesson = atom<CurrentLessonType | null>(null);

Loading…
Cancel
Save