mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: Improve QuizBlockComponent UI and interaction with responsive design and enhanced user experience
This commit is contained in:
parent
5dd9d5d749
commit
2175534e8f
1 changed files with 63 additions and 33 deletions
|
|
@ -50,6 +50,7 @@ function QuizBlockComponent(props: any) {
|
||||||
const refreshUserSubmission = () => {
|
const refreshUserSubmission = () => {
|
||||||
setUserAnswers([])
|
setUserAnswers([])
|
||||||
setSubmitted(false)
|
setSubmitted(false)
|
||||||
|
setSubmissionMessage('')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUserSubmission = () => {
|
const handleUserSubmission = () => {
|
||||||
|
|
@ -124,7 +125,7 @@ function QuizBlockComponent(props: any) {
|
||||||
correct: false,
|
correct: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there is already more thqn 5 answers
|
// check if there is already more than 5 answers
|
||||||
const question: any = questions.find(
|
const question: any = questions.find(
|
||||||
(question: Question) => question.question_id === question_id
|
(question: Question) => question.question_id === question_id
|
||||||
)
|
)
|
||||||
|
|
@ -206,11 +207,11 @@ function QuizBlockComponent(props: any) {
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className="block-quiz">
|
<NodeViewWrapper className="block-quiz">
|
||||||
<div
|
<div
|
||||||
//style={{ background: "radial-gradient(152.15% 150.08% at 56.45% -6.67%, rgba(180, 255, 250, 0.10) 5.53%, rgba(202, 201, 255, 0.10) 66.76%)" }}
|
className="rounded-xl px-3 sm:px-5 py-2 bg-slate-100 transition-all ease-linear"
|
||||||
className="rounded-xl px-5 py-2 bg-slate-100 transition-all ease-linear"
|
|
||||||
>
|
>
|
||||||
<div className="flex space-x-2 pt-1 items-center text-sm overflow-hidden">
|
{/* Header section */}
|
||||||
{submitted && submissionMessage == 'All answers are correct!' && (
|
<div className="flex flex-wrap gap-2 pt-1 items-center text-sm">
|
||||||
|
{submitted && submissionMessage === 'All answers are correct!' && (
|
||||||
<ReactConfetti
|
<ReactConfetti
|
||||||
numberOfPieces={submitted ? 1400 : 0}
|
numberOfPieces={submitted ? 1400 : 0}
|
||||||
recycle={false}
|
recycle={false}
|
||||||
|
|
@ -223,7 +224,21 @@ function QuizBlockComponent(props: any) {
|
||||||
Quiz
|
Quiz
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="grow flex items-center justify-center"></div>
|
|
||||||
|
{/* Submission message */}
|
||||||
|
{submitted && (
|
||||||
|
<div className={`text-xs font-medium px-2 py-1 rounded-md ${
|
||||||
|
submissionMessage === 'All answers are correct!'
|
||||||
|
? 'bg-lime-100 text-lime-700'
|
||||||
|
: 'bg-red-100 text-red-700'
|
||||||
|
}`}>
|
||||||
|
{submissionMessage}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="grow"></div>
|
||||||
|
|
||||||
|
{/* Action buttons */}
|
||||||
{isEditable ? (
|
{isEditable ? (
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
|
@ -237,10 +252,11 @@ function QuizBlockComponent(props: any) {
|
||||||
<div className="flex space-x-1 items-center">
|
<div className="flex space-x-1 items-center">
|
||||||
<div
|
<div
|
||||||
onClick={() => refreshUserSubmission()}
|
onClick={() => refreshUserSubmission()}
|
||||||
className="cursor-pointer px-2"
|
className="cursor-pointer p-1.5 rounded-md hover:bg-slate-200"
|
||||||
|
title="Reset answers"
|
||||||
>
|
>
|
||||||
<RefreshCcw
|
<RefreshCcw
|
||||||
className="text-slate-400 cursor-pointer"
|
className="text-slate-500"
|
||||||
size={15}
|
size={15}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -254,8 +270,9 @@ function QuizBlockComponent(props: any) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Questions section */}
|
||||||
{questions.map((question: Question) => (
|
{questions.map((question: Question) => (
|
||||||
<div key={question.question_id} className="pt-1 space-y-2">
|
<div key={question.question_id} className="pt-3 space-y-2">
|
||||||
<div className="question">
|
<div className="question">
|
||||||
<div className="flex space-x-2 items-center">
|
<div className="flex space-x-2 items-center">
|
||||||
<div className="flex-grow">
|
<div className="flex-grow">
|
||||||
|
|
@ -269,10 +286,10 @@ function QuizBlockComponent(props: any) {
|
||||||
e.target.value
|
e.target.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="text-slate-800 bg-[#00008b00] border-2 border-gray-200 rounded-md border-dotted text-md font-bold w-full"
|
className="text-slate-800 bg-[#00008b00] border-2 border-gray-200 rounded-md border-dotted text-md font-bold w-full p-2"
|
||||||
></input>
|
></input>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-slate-800 bg-[#00008b00] rounded-md text-md font-bold w-full">
|
<p className="text-slate-800 bg-[#00008b00] rounded-md text-md font-bold w-full p-2 break-words">
|
||||||
{question.question}
|
{question.question}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
@ -280,25 +297,27 @@ function QuizBlockComponent(props: any) {
|
||||||
{isEditable && (
|
{isEditable && (
|
||||||
<div
|
<div
|
||||||
onClick={() => deleteQuestion(question.question_id)}
|
onClick={() => deleteQuestion(question.question_id)}
|
||||||
className="w-[20px] flex-none flex items-center h-[20px] rounded-lg bg-slate-200 hover:bg-slate-300 text-sm transition-all ease-linear cursor-pointer"
|
className="w-[24px] flex-none flex items-center h-[24px] rounded-lg bg-slate-200 hover:bg-slate-300 text-sm transition-all ease-linear cursor-pointer"
|
||||||
>
|
>
|
||||||
<Minus className="mx-auto text-slate-400" size={12} />
|
<Minus className="mx-auto text-slate-500" size={14} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="answers flex py-2 space-x-3">
|
|
||||||
|
{/* Answers section - changed to vertical layout for better responsiveness */}
|
||||||
|
<div className="answers flex flex-col py-2 space-y-2">
|
||||||
{question.answers.map((answer: Answer) => (
|
{question.answers.map((answer: Answer) => (
|
||||||
<div
|
<div
|
||||||
key={answer.answer_id}
|
key={answer.answer_id}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
'outline outline-3 pr-2 shadow w-full flex items-center space-x-2 h-[30px] bg-opacity-50 hover:bg-opacity-100 hover:shadow-md rounded-s rounded-lg bg-white text-sm duration-150 cursor-pointer ease-linear',
|
'outline outline-2 pr-2 shadow w-full flex items-stretch space-x-2 min-h-[36px] bg-opacity-50 hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white text-sm duration-150 cursor-pointer ease-linear',
|
||||||
answer.correct && isEditable ? 'outline-lime-300' : 'outline-white',
|
answer.correct && isEditable ? 'outline-lime-300' : 'outline-white',
|
||||||
userAnswers.some(
|
userAnswers.some(
|
||||||
(userAnswer: any) =>
|
(userAnswer: any) =>
|
||||||
userAnswer.question_id === question.question_id &&
|
userAnswer.question_id === question.question_id &&
|
||||||
userAnswer.answer_id === answer.answer_id &&
|
userAnswer.answer_id === answer.answer_id &&
|
||||||
!isEditable
|
!isEditable && !submitted
|
||||||
) ? 'outline-slate-300' : '',
|
) ? 'outline-blue-400' : '',
|
||||||
submitted && answer.correct ? 'outline-lime-300 text-lime' : '',
|
submitted && answer.correct ? 'outline-lime-300 text-lime' : '',
|
||||||
submitted &&
|
submitted &&
|
||||||
!answer.correct &&
|
!answer.correct &&
|
||||||
|
|
@ -314,10 +333,16 @@ function QuizBlockComponent(props: any) {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
'bg-white font-bold text-base flex items-center h-full w-[40px] rounded-l-md text-slate-800',
|
'font-bold text-base flex items-center justify-center self-stretch w-[40px] rounded-l-md text-slate-800 bg-white',
|
||||||
answer.correct && isEditable
|
answer.correct && isEditable
|
||||||
? 'bg-lime-300 text-lime-800 outline-none'
|
? 'bg-lime-300 text-lime-800 outline-none'
|
||||||
: 'bg-white',
|
: 'bg-white',
|
||||||
|
userAnswers.some(
|
||||||
|
(userAnswer: any) =>
|
||||||
|
userAnswer.question_id === question.question_id &&
|
||||||
|
userAnswer.answer_id === answer.answer_id &&
|
||||||
|
!isEditable && !submitted
|
||||||
|
) ? 'bg-blue-400 text-white outline-none' : '',
|
||||||
submitted && answer.correct
|
submitted && answer.correct
|
||||||
? 'bg-lime-300 text-lime-800 outline-none'
|
? 'bg-lime-300 text-lime-800 outline-none'
|
||||||
: '',
|
: '',
|
||||||
|
|
@ -332,7 +357,7 @@ function QuizBlockComponent(props: any) {
|
||||||
: ''
|
: ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<p className="mx-auto font-bold text-sm ">
|
<p className="font-bold text-sm">
|
||||||
{getAnswerID(
|
{getAnswerID(
|
||||||
question.answers.indexOf(answer),
|
question.answers.indexOf(answer),
|
||||||
question.question_id
|
question.question_id
|
||||||
|
|
@ -350,33 +375,37 @@ function QuizBlockComponent(props: any) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="Answer"
|
placeholder="Answer"
|
||||||
className="w-full mx-2 px-3 pr-6 text-neutral-600 bg-[#00008b00] border-2 border-gray-200 rounded-md border-dotted text-sm font-bold"
|
className="w-full mx-2 px-3 pr-6 text-neutral-600 bg-[#00008b00] border-2 border-gray-200 rounded-md border-dotted text-sm font-bold py-1.5"
|
||||||
></input>
|
></input>
|
||||||
) : (
|
) : (
|
||||||
<p className="w-full mx-2 px-3 pr-6 text-neutral-600 bg-[#00008b00] rounded-md ext-sm font-bold">
|
<p className="w-full mx-2 px-3 pr-6 text-neutral-600 bg-[#00008b00] rounded-md text-sm font-bold py-1.5 break-words">
|
||||||
{answer.answer}
|
{answer.answer}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{isEditable && (
|
{isEditable && (
|
||||||
<div className="flex space-x-1 items-center">
|
<div className="flex space-x-1 items-center">
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
markAnswerCorrect(
|
markAnswerCorrect(
|
||||||
question.question_id,
|
question.question_id,
|
||||||
answer.answer_id
|
answer.answer_id
|
||||||
)
|
);
|
||||||
}
|
}}
|
||||||
className="w-[20px] flex-none flex items-center h-[20px] rounded-lg bg-lime-300 hover:bg-lime-400 transition-all ease-linear text-sm cursor-pointer "
|
className="w-[24px] flex-none flex items-center h-[24px] rounded-lg bg-lime-300 hover:bg-lime-400 transition-all ease-linear text-sm cursor-pointer"
|
||||||
|
title={answer.correct ? "Mark as incorrect" : "Mark as correct"}
|
||||||
>
|
>
|
||||||
<Check className="mx-auto text-lime-800" size={12} />
|
<Check className="mx-auto text-lime-800" size={14} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={(e) => {
|
||||||
deleteAnswer(question.question_id, answer.answer_id)
|
e.stopPropagation();
|
||||||
}
|
deleteAnswer(question.question_id, answer.answer_id);
|
||||||
className="w-[20px] flex-none flex items-center h-[20px] rounded-lg bg-slate-200 hover:bg-slate-300 text-sm transition-all ease-linear cursor-pointer"
|
}}
|
||||||
|
className="w-[24px] flex-none flex items-center h-[24px] rounded-lg bg-slate-200 hover:bg-slate-300 text-sm transition-all ease-linear cursor-pointer"
|
||||||
|
title="Delete answer"
|
||||||
>
|
>
|
||||||
<Minus className="mx-auto text-slate-400" size={12} />
|
<Minus className="mx-auto text-slate-500" size={14} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -385,9 +414,10 @@ function QuizBlockComponent(props: any) {
|
||||||
{isEditable && (
|
{isEditable && (
|
||||||
<div
|
<div
|
||||||
onClick={() => addAnswer(question.question_id)}
|
onClick={() => addAnswer(question.question_id)}
|
||||||
className="outline outline-3 w-[30px] flex-none flex items-center h-[30px] outline-white hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white text-sm hover:scale-105 active:scale-110 duration-150 cursor-pointer ease-linear"
|
className="outline outline-2 w-full flex-none flex items-center h-[36px] outline-white hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white text-sm hover:scale-[1.01] active:scale-[1.02] duration-150 cursor-pointer ease-linear justify-center"
|
||||||
>
|
>
|
||||||
<Plus className="mx-auto text-slate-800" size={15} />
|
<Plus className="text-slate-800 mr-1" size={15} />
|
||||||
|
<span className="text-slate-800 text-sm">Add Answer</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue