mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-02 13:52:46 +02:00
wip
This commit is contained in:
@@ -2,13 +2,15 @@ import type { QuizQuestion } from '../../queries/ai-quiz';
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { cn } from '../../lib/classname';
|
import { cn } from '../../lib/classname';
|
||||||
import { CheckIcon, XIcon, InfoIcon } from 'lucide-react';
|
import { CheckIcon, XIcon, InfoIcon } from 'lucide-react';
|
||||||
|
import { markdownToHtml } from '../../lib/markdown';
|
||||||
|
|
||||||
type AIMCQQuestionProps = {
|
type AIMCQQuestionProps = {
|
||||||
question: QuizQuestion;
|
question: QuizQuestion;
|
||||||
|
onNextQuestion?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function AIMCQQuestion(props: AIMCQQuestionProps) {
|
export function AIMCQQuestion(props: AIMCQQuestionProps) {
|
||||||
const { question } = props;
|
const { question, onNextQuestion } = props;
|
||||||
const { title: questionText, options, answerExplanation } = question;
|
const { title: questionText, options, answerExplanation } = question;
|
||||||
|
|
||||||
const [selectedOptions, setSelectedOptions] = useState<number[]>([]);
|
const [selectedOptions, setSelectedOptions] = useState<number[]>([]);
|
||||||
@@ -32,18 +34,29 @@ export function AIMCQQuestion(props: AIMCQQuestionProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
|
if (isSubmitted) {
|
||||||
|
onNextQuestion?.();
|
||||||
|
setSelectedOptions([]);
|
||||||
|
setIsSubmitted(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setIsSubmitted(true);
|
setIsSubmitted(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const canSubmit = selectedOptions.length > 0;
|
const canSubmit = selectedOptions.length > 0;
|
||||||
|
const titleHtml = markdownToHtml(questionText, false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-4xl font-medium">{questionText}</h3>
|
<div
|
||||||
|
className="prose prose-lg prose-p:text-4xl prose-p:font-medium prose-p:my-4 prose-pre:my-0 prose-p:prose-code:text-4xl! prose-p:prose-code:px-3 prose-p:prose-code:rounded-lg prose-p:prose-code:border prose-p:prose-code:border-black text-black"
|
||||||
|
dangerouslySetInnerHTML={{ __html: titleHtml }}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="mt-6 space-y-3">
|
<div className="mt-6 space-y-3">
|
||||||
{options.map((option, index) => {
|
{options.map((option, index) => {
|
||||||
const isSelected = selectedOptions.includes(index);
|
const isSelected = selectedOptions.includes(index);
|
||||||
const showCorrectness = isSubmitted && isSelected;
|
|
||||||
const isCorrectOption = option.isCorrect;
|
const isCorrectOption = option.isCorrect;
|
||||||
|
|
||||||
const isSelectedAndCorrect =
|
const isSelectedAndCorrect =
|
||||||
@@ -53,6 +66,8 @@ export function AIMCQQuestion(props: AIMCQQuestionProps) {
|
|||||||
const isNotSelectedAndCorrect =
|
const isNotSelectedAndCorrect =
|
||||||
isSubmitted && !isSelected && isCorrectOption;
|
isSubmitted && !isSelected && isCorrectOption;
|
||||||
|
|
||||||
|
const html = markdownToHtml(option.title, false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={option.id}
|
key={option.id}
|
||||||
@@ -93,7 +108,10 @@ export function AIMCQQuestion(props: AIMCQQuestionProps) {
|
|||||||
|
|
||||||
{isNotSelectedAndCorrect && <CheckIcon className="size-4" />}
|
{isNotSelectedAndCorrect && <CheckIcon className="size-4" />}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-left">{option.title}</p>
|
<div
|
||||||
|
className="prose prose-lg prose-p:text-lg prose-p:font-normal prose-p:my-0 prose-pre:my-0 prose-p:prose-code:text-lg! prose-p:prose-code:px-2 prose-p:prose-code:py-0.5 prose-p:prose-code:rounded-lg prose-p:prose-code:border prose-p:prose-code:border-black mt-0.5 text-left text-black"
|
||||||
|
dangerouslySetInnerHTML={{ __html: html }}
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -116,7 +134,7 @@ export function AIMCQQuestion(props: AIMCQQuestionProps) {
|
|||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={!canSubmit}
|
disabled={!canSubmit}
|
||||||
>
|
>
|
||||||
Submit Answer
|
{isSubmitted ? 'Next Question' : 'Submit Answer'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -21,6 +21,10 @@ export function AIQuizContent(props: AIQuizContentProps) {
|
|||||||
const hasMoreQuestions = activeQuestionIndex < questions.length - 1;
|
const hasMoreQuestions = activeQuestionIndex < questions.length - 1;
|
||||||
const hasPreviousQuestions = activeQuestionIndex > 0;
|
const hasPreviousQuestions = activeQuestionIndex > 0;
|
||||||
|
|
||||||
|
console.log('-'.repeat(20));
|
||||||
|
console.log(questions);
|
||||||
|
console.log('-'.repeat(20));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-full max-w-lg py-10">
|
<div className="mx-auto w-full max-w-lg py-10">
|
||||||
<div className="mb-10 flex items-center gap-3">
|
<div className="mb-10 flex items-center gap-3">
|
||||||
@@ -40,7 +44,10 @@ export function AIQuizContent(props: AIQuizContentProps) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{activeQuestion && activeQuestion.type === 'mcq' && (
|
{activeQuestion && activeQuestion.type === 'mcq' && (
|
||||||
<AIMCQQuestion question={activeQuestion} />
|
<AIMCQQuestion
|
||||||
|
question={activeQuestion}
|
||||||
|
onNextQuestion={() => setActiveQuestionIndex(activeQuestionIndex + 1)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -148,7 +148,7 @@ export type QuizQuestion = {
|
|||||||
|
|
||||||
export function generateAiQuizQuestions(questionData: string): QuizQuestion[] {
|
export function generateAiQuizQuestions(questionData: string): QuizQuestion[] {
|
||||||
const questions: QuizQuestion[] = [];
|
const questions: QuizQuestion[] = [];
|
||||||
const lines = questionData.split('\n').map((line) => line.trim());
|
const lines = questionData.split('\n');
|
||||||
|
|
||||||
let currentQuestion: QuizQuestion | null = null;
|
let currentQuestion: QuizQuestion | null = null;
|
||||||
let context: 'question' | 'explanation' | 'option' | null = null;
|
let context: 'question' | 'explanation' | 'option' | null = null;
|
||||||
@@ -214,6 +214,11 @@ export function generateAiQuizQuestions(questionData: string): QuizQuestion[] {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('-'.repeat(20));
|
||||||
|
console.log('CONTEXT:', context);
|
||||||
|
console.log('LINE:', line);
|
||||||
|
console.log('-'.repeat(20));
|
||||||
|
|
||||||
if (context === 'question') {
|
if (context === 'question') {
|
||||||
currentQuestion.title += `\n${line}`;
|
currentQuestion.title += `\n${line}`;
|
||||||
} else if (context === 'explanation') {
|
} else if (context === 'explanation') {
|
||||||
|
Reference in New Issue
Block a user