frontend_adaptive_learning/src/roles/user/exerciseCombine/views/Exercise.jsx

208 lines
7.6 KiB
React
Raw Normal View History

2024-10-31 02:32:14 +00:00
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useExercise } from '../hooks/useExercises';
import { Container, Row, Col, ListGroup, Button, Modal, Alert, OverlayTrigger, Popover } from 'react-bootstrap';
import MultipleChoiceQuestion from './components/MultipleChoiceQuestion';
import TrueFalseQuestion from './components/TrueFalseQuestion';
import MatchingPairsQuestion from './components/MatchingPairsQuestion';
import Skeleton from 'react-loading-skeleton';
import ilustration from '../../../../assets/images/illustration/submitExercise.png';
const Exercise = () => {
const [showModal, setShowModal] = useState(false);
const [showAlert, setShowAlert] = useState(false);
const { topic, level } = useParams();
const {
questions,
currentQuestion,
currentQuestionIndex,
setCurrentQuestionIndex,
answers,
isLoading,
error,
handleAnswer,
nextQuestion,
prevQuestion,
handleSubmit,
handleConfirmSubmit
} = useExercise(topic, level);
const handleSubmitWrapper = () => {
if (handleSubmit()) {
setShowModal(true);
} else {
setShowAlert(true);
}
};
const handleCloseModal = () => setShowModal(false);
const renderQuestion = () => {
switch (currentQuestion.QUESTION_TYPE) {
case 'MCQ':
return (
<MultipleChoiceQuestion
question={currentQuestion}
onAnswer={handleAnswer}
savedAnswer={answers[currentQuestionIndex]}
index={currentQuestionIndex}
/>
);
case 'TFQ':
return (
<TrueFalseQuestion
question={currentQuestion}
onAnswer={handleAnswer}
savedAnswer={answers[currentQuestionIndex]}
index={currentQuestionIndex}
/>
);
case 'MPQ':
return (
<MatchingPairsQuestion
question={currentQuestion}
onAnswer={handleAnswer}
savedAnswer={answers[currentQuestionIndex]}
index={currentQuestionIndex}
/>
);
default:
return <p>Unknown question type.</p>;
}
};
const popover = (
<Popover id="popover-basic">
<Popover.Header as="h4">Tips</Popover.Header>
<Popover.Body className='p-2'>
<ul className='ps-3 m-0'>
<li>Click the <strong>left arrow</strong> key to go to the previous question</li>
<li>Click the <strong>right arrow</strong> key to go to the next question</li>
</ul>
</Popover.Body>
</Popover>
);
if (isLoading) {
return (
<div className="row">
<div className="col-2">
<Skeleton containerClassName='w-100' className='w-100 mb-1 rounded-3' count={6} style={{height:"4vh"}} />
</div>
<div className="col-10">
<Skeleton containerClassName='w-100' className='w-100 mb-1 rounded-3' style={{height:"5vh"}} />
<Skeleton containerClassName='w-100' className='w-50 mb-1 rounded-3' style={{height:"20vh"}} />
<Skeleton containerClassName='w-100' className='w-100 mb-1 rounded-3' style={{height:"30vh"}} />
</div>
</div>
);
}
if (error) return <p>Error loading questions.</p>;
return (
<Container fluid className='exercise-page'>
<Row>
<Col sm={2}>
<div className='p-3 rounded-4 bg-white'>
<div className="mb-3 d-flex justify-content-between align-items-center">
<h4 className='mb-0 text-gd fw-bold'>Pretest</h4>
<OverlayTrigger trigger="click" placement="right" overlay={popover}>
<i className=" bi bi-info-circle cursor-pointer text-secondary"></i>
</OverlayTrigger>
</div>
<ListGroup variant="flush" className='number-list'>
{questions.map((q, index) => (
<ListGroup.Item
key={q.ID_ADMIN_EXERCISE}
active={index === currentQuestionIndex}
onClick={() => setCurrentQuestionIndex(index)}
className={`border-0 rounded-3 number-label ${answers[index] !== null ? 'answered fw-bold' : ''}`}
style={{ cursor: 'pointer' }}
>
<i className={`me-2 bi bi-circle ${answers[index] !== null ? 'd-none' : 'd-block'}`}></i>
<i className={`me-2 bi bi-check2-circle ${answers[index] !== null ? 'd-block' : 'd-none'}`}></i>
{index+1}
</ListGroup.Item>
))}
</ListGroup>
</div>
</Col>
<Col sm={10}>
<div className='p-4 rounded-4 bg-white'>
<div className="pb-4 d-flex justify-content-between align-items-center">
<Button
variant='outline-blue'
className={`rounded-35 ${currentQuestionIndex === 0 ? 'invisible' : 'visible'}`}
onClick={prevQuestion}
disabled={currentQuestionIndex === 0}
>
<i className="bi bi-arrow-left"></i>
</Button>
<h5 className='m-0'>{`Questions ${currentQuestionIndex + 1} of ${questions.length}`}</h5>
<Button
variant="blue"
className={`rounded-35 ${currentQuestionIndex === questions.length - 1 ? 'd-none' : ''}`}
onClick={nextQuestion}
disabled={currentQuestionIndex === questions.length - 1}
>
Next Questions <i className="bi bi-arrow-right"></i>
</Button>
<Button
variant="blue"
className={`rounded-35 px-4 ${currentQuestionIndex === questions.length - 1 ? 'd-inline-block' : 'd-none'}`}
onClick={handleSubmitWrapper}
>
Submit <i className="bi bi-send"></i>
</Button>
</div>
<div className='p-3 border rounded-3'>
{renderQuestion()}
</div>
</div>
</Col>
</Row>
<Alert show={showAlert} variant="danger" className="custom-alert" onClose={() => setShowAlert(false)} dismissible>
<Alert.Heading>ATTENTION!</Alert.Heading>
<span>Please answer all questions before submitting.</span>
</Alert>
{/* <Modal show={showModal} onHide={handleCloseModal} centered>
<Modal.Header closeButton>
<Modal.Title>Confirmation</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Are you sure you want to submit your answer?</p>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleCloseModal}>
Cancel
</Button>
<Button variant="primary" onClick={handleConfirmSubmit}>
Yes, Submit <i className="bi bi-send"></i>
</Button>
</Modal.Footer>
</Modal> */}
<Modal show={showModal} onHide={handleCloseModal} centered>
<Modal.Body className='p-4 d-flex flex-column items-center'>
<h4 className='mb-4 fw-bold text-dark'>Proceed with <span className='text-blue'>Submission</span>?</h4>
<img src={ilustration} alt="" />
<p className='my-3 text-muted fw-light'>Confirm submission? There's no going back.</p>
<div className="mt-4 w-100 d-flex justify-content-center">
<Button variant="outline-blue" className="w-50 py-2 px-5 mx-1 rounded-35" onClick={handleCloseModal}>Check Again</Button>
<Button variant="gd" className="w-50 py-2 px-5 mx-1 rounded-35" onClick={handleConfirmSubmit}>Confirm</Button>
</div>
</Modal.Body>
</Modal>
</Container>
);
};
export default Exercise;