Improve test my knowledge

feat/ai-course-questions
Kamran Ahmed 3 weeks ago
parent 97cf388794
commit 8f1b4b8470
  1. 212
      src/components/GenerateCourse/TestMyKnowledgeAction.tsx

@ -116,31 +116,33 @@ export function TestMyKnowledgeAction(props: TestMyKnowledgeActionProps) {
return (
<div className="mt-10 flex flex-col gap-4">
<div className="flex items-center gap-2">
<button
className={cn(
'flex flex-shrink-0 items-center gap-2 rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900',
{
'bg-gray-100 text-gray-900': isKnowledgeTestOpen,
},
)}
onClick={() => {
if (isGenerating || isLoading) {
return;
}
if (!isKnowledgeTestOpen) {
setIsKnowledgeTestOpen(true);
generateAiLessonQuestions();
} else {
setIsKnowledgeTestOpen(false);
}
}}
>
<FlaskConicalIcon className="size-5 shrink-0" />
<span>Test My Knowledge</span>
</button>
</div>
{!isKnowledgeTestOpen && (
<div className="flex items-center gap-2">
<button
className={cn(
'flex flex-shrink-0 items-center gap-2 rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900',
{
'bg-gray-100 text-gray-900': isKnowledgeTestOpen,
},
)}
onClick={() => {
if (isGenerating || isLoading) {
return;
}
if (!isKnowledgeTestOpen) {
setIsKnowledgeTestOpen(true);
generateAiLessonQuestions();
} else {
setIsKnowledgeTestOpen(false);
}
}}
>
<FlaskConicalIcon className="size-5 shrink-0" />
<span>Test My Knowledge</span>
</button>
</div>
)}
{error && (
<div className="flex min-h-[200px] flex-col items-center justify-center gap-2 rounded-lg rounded-xl bg-red-50/80 p-5 text-red-500">
@ -258,6 +260,7 @@ export function ListQuestions(props: ListQuestionsProps) {
return (
<QuizItem
counter={activeQuestionIndex + 1}
totalQuestions={questions.length}
correctAnswerCount={correctAnswerCount}
isLoading={isGenerating}
@ -275,6 +278,7 @@ export function ListQuestions(props: ListQuestionsProps) {
type QuizItemProps = {
totalQuestions: number;
correctAnswerCount: number;
counter: number;
question: Question;
onOptionSelectChange?: (id: string, optionId: string) => void;
@ -292,9 +296,8 @@ export function QuizItem(props: QuizItemProps) {
const {
totalQuestions,
correctAnswerCount,
counter,
isLoading,
question,
onOptionSelectChange,
selectedOptionIds,
@ -322,87 +325,98 @@ export function QuizItem(props: QuizItemProps) {
return (
<div
className={cn('relative w-full rounded-lg border p-5 text-black', {
className={cn('relative w-full rounded-lg border text-black', {
'border-red-400': hasWrongAnswer,
'border-green-500': hasCorrectAnswer,
})}
>
{submitted && (
<span
className={cn(
'absolute right-2 top-2 rounded-lg px-2 py-1 text-sm text-gray-500',
{
'bg-red-100 text-red-500': hasWrongAnswer,
'bg-green-100 text-green-500': hasCorrectAnswer,
},
)}
>
{hasWrongAnswer ? 'Wrong' : 'Correct'}
<div className="flex items-center gap-4 rounded-t-lg bg-gray-100/40 p-4 border-b">
<span className="text-sm font-medium text-gray-700">
Question {counter} of {totalQuestions}
</span>
)}
<h3 className="mx-2 text-balance text-lg font-medium">
{title} {canMultiSelect ? '(Select Multiple)' : ''}
</h3>
<div className="mt-4 flex flex-col gap-1">
{options.map((option, index) => {
let status: QuizOptionStatus = 'default';
if (submitted) {
if (option.isCorrect) {
status = 'correct';
} else if (selectedOptionIds?.includes(option.id)) {
status = 'wrong';
}
} else {
if (selectedOptionIds?.includes(option.id)) {
status = 'selected';
}
}
return (
<QuizOption
key={index}
title={option.title}
status={status}
onSelect={() => onOptionSelectChange?.(questionId, option.id)}
submitted={submitted}
/>
);
})}
<div className="h-1.5 flex-1 rounded-full bg-gray-200">
<div
className="h-full rounded-full bg-black transition-all"
style={{ width: `${(counter / totalQuestions) * 100}%` }}
/>
</div>
{submitted && (
<span
className={cn('rounded-full px-2 py-0.5 text-xs font-medium', {
'bg-red-500 text-white': hasWrongAnswer,
'bg-green-500 text-white': hasCorrectAnswer,
})}
>
{hasWrongAnswer ? 'Wrong' : 'Correct'}
</span>
)}
</div>
<div className="mt-4 flex w-full items-center justify-between px-2">
<div className="text-gray-500">
{submitted ? (
<span>
You got {correctAnswerCount} out of {totalQuestions} correct.
<button
className="relative -top-0.5 ml-1 rounded-md bg-black px-2 py-0.5 text-xs uppercase tracking-wider text-white hover:bg-black/80"
onClick={onTryAgain}
>
Try again?
</button>
</span>
) : (
<span>Answer all questions to submit</span>
)}
<div className="p-5">
<h3 className="mx-2 text-balance text-lg font-medium">
{title} {canMultiSelect ? '(Select Multiple)' : ''}
</h3>
<div className="mt-4 flex flex-col gap-1">
{options.map((option, index) => {
let status: QuizOptionStatus = 'default';
if (submitted) {
if (option.isCorrect) {
status = 'correct';
} else if (selectedOptionIds?.includes(option.id)) {
status = 'wrong';
}
} else {
if (selectedOptionIds?.includes(option.id)) {
status = 'selected';
}
}
return (
<QuizOption
key={index}
title={option.title}
status={status}
onSelect={() => onOptionSelectChange?.(questionId, option.id)}
submitted={submitted}
/>
);
})}
</div>
<div className="flex gap-2">
<button
className="flex h-8 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pr-4 text-sm text-black hover:bg-black hover:text-white focus:outline-none max-sm:pr-2"
onClick={onPrevious}
>
<ChevronLeftIcon className="size-5 shrink-0" />
<span className="max-sm:hidden">Previous</span>
</button>
<button
className="flex h-8 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pl-4 text-sm text-black hover:bg-black hover:text-white focus:outline-none max-sm:pl-2"
onClick={onNext}
>
<span className="max-sm:hidden">Next</span>
<ChevronRightIcon className="size-5 shrink-0" />
</button>
<div className="mt-4 flex w-full items-center justify-between px-2">
<div className="text-gray-500">
{submitted ? (
<span>
You got {correctAnswerCount} out of {totalQuestions} correct.
<button
className="relative -top-0.5 ml-1 rounded-md bg-black px-2 py-0.5 text-xs uppercase tracking-wider text-white hover:bg-black/80"
onClick={onTryAgain}
>
Try again?
</button>
</span>
) : (
<span>Answer all questions to submit</span>
)}
</div>
<div className="flex gap-2">
<button
className="flex h-8 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pr-4 text-sm text-black hover:bg-black hover:text-white focus:outline-none max-sm:pr-2"
onClick={onPrevious}
>
<ChevronLeftIcon className="size-5 shrink-0" />
<span className="max-sm:hidden">Previous</span>
</button>
<button
className="flex h-8 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pl-4 text-sm text-black hover:bg-black hover:text-white focus:outline-none max-sm:pl-2"
onClick={onNext}
>
<span className="max-sm:hidden">Next</span>
<ChevronRightIcon className="size-5 shrink-0" />
</button>
</div>
</div>
</div>

Loading…
Cancel
Save