Add Question Component Made( No Feature)

main
Pedram Keshavarzi 3 years ago
parent c2f9f96935
commit 65defd8de3
  1. 3
      src/assets/img/attach-circle.svg
  2. 18
      src/redux/reducers/exam.js
  3. 103
      src/view/addExam/components/addQuestion.js
  4. 149
      src/view/addExam/views/AddQuestionsFromBank.js

@ -0,0 +1,3 @@
<svg width="50" height="50" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.1999 11.8L10.7899 13.21C10.0099 13.99 10.0099 15.26 10.7899 16.04C11.5699 16.82 12.8399 16.82 13.6199 16.04L15.8399 13.82C17.3999 12.26 17.3999 9.72999 15.8399 8.15999C14.2799 6.59999 11.7499 6.59999 10.1799 8.15999L7.75988 10.58C6.41988 11.92 6.41988 14.09 7.75988 15.43" stroke="#787878" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 472 B

@ -181,9 +181,11 @@ const initialState = {
], ],
questions: [ questions: [
] ],
} }
export const numOfinitQs = initialState.questionBank.length;
export default function addExamReduser(state = initialState, { type, payload }) { export default function addExamReduser(state = initialState, { type, payload }) {
console.log(state.courses) console.log(state.courses)
@ -243,7 +245,7 @@ export default function addExamReduser(state = initialState, { type, payload })
console.log(payload) console.log(payload)
const othercourses = state.courses.filter(itm => itm.id !== payload.courseId) const othercourses = state.courses.filter(itm => itm.id !== payload.courseId)
const selectedC = state.courses.filter(itm => itm.id == payload.courseId) const selectedC = state.courses.filter(itm => itm.id == payload.courseId)
selectedC[0] = { ...selectedC[0], selectedQuestions: [...selectedC[0].selectedQuestions, payload] } selectedC[0] = { ...selectedC[0], selectedQuestions: [ payload, ...selectedC[0].selectedQuestions] }
const newCourses = [...othercourses, ...selectedC] const newCourses = [...othercourses, ...selectedC]
return { return {
@ -275,7 +277,7 @@ export default function addExamReduser(state = initialState, { type, payload })
case 'GET_QUESTION_BACK_TO_BANK': case 'GET_QUESTION_BACK_TO_BANK':
return { return {
...state, ...state,
questionBank: [...state.questionBank, payload] questionBank: [payload, ...state.questionBank,]
} }
case 'CHANGE_QUESTION_ORDER': case 'CHANGE_QUESTION_ORDER':
@ -294,6 +296,16 @@ export default function addExamReduser(state = initialState, { type, payload })
...state, ...state,
courses: payload courses: payload
} }
case 'ADD_CUSTOM_QUESTION':
const otherCourses = state.courses.filter(itm => itm.id !== payload.courseId)
const selectedc = state.courses.filter(itm => itm.id == payload.courseId)
selectedc[0] = { ...selectedc[0], selectedQuestions: [payload, ...selectedc[0].selectedQuestions] }
const newcourses = [ ...selectedc, ...otherCourses]
return{
...state,
courses: newcourses
}
default: default:

@ -1,27 +1,22 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import attachIcon from '../../../assets/img/attach-circle.svg';
const AddQuestionPopUp = ({ titlePass, scorePass, submitOnClick, cancelOnClick, passOptionTitle, setAsAnswer, options }) => {
const AddQuestionPopUp = ({ submitOnClick, nameOnChange, questionQuantityOnChange, coefficientOnChange, closeOnClick }) => {
const [answer, setAnswer] = useState(null); const gozine = [
const [numberOfOptions, setNumberOfOptions] = useState(null); 'الف',
const [options, setOptions] = useState([]) 'ب',
useEffect(() => { 'ج',
const arr = []; 'د',
for (var i = 1; i <= numberOfOptions; i++) { 'ه',
arr.push({ 'ز',
id: i, ]
title: '',
isAnswer: false
})
}
setOptions(arr)
}, [numberOfOptions])
return ( return (
<div className="w-full z-10 fixed h-screen backdrop-blur flex items-center -mt-10 justify-center"> <div className="w-full z-10 fixed bg-black bg-opacity-20 h-screen backdrop-blur flex flex-col items-center top-0 left-0 justify-center">
<div className="w-1/2 bg-white rounded-xl flex flex-col shadow-lg p-6"> <div className="w-1/2 flex flex-col items-center bg-white p-6 rounded-xl shadow-lg">
<div className="w-full"> <div className="w-full">
<div className="w-8 h-8 text-white text-sm rounded-full cursor-pointer flex justify-center items-center bg-red52" onClick={closeOnClick}> <div className="w-8 h-8 text-white text-sm rounded-full cursor-pointer flex justify-center items-center bg-red52" onClick={cancelOnClick}>
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 15.044 15.044"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 15.044 15.044">
<g id="vuesax_linear_card-remove" data-name="vuesax/linear/card-remove" transform="translate(-252.46 -511.461)"> <g id="vuesax_linear_card-remove" data-name="vuesax/linear/card-remove" transform="translate(-252.46 -511.461)">
<g id="card-remove" transform="translate(253.309 512.31)"> <g id="card-remove" transform="translate(253.309 512.31)">
@ -32,47 +27,61 @@ const AddQuestionPopUp = ({ submitOnClick, nameOnChange, questionQuantityOnChang
</svg> </svg>
</div> </div>
</div> </div>
<h1 className="w-full text-right text-lg text-red52 font-bold pt-4"> <div className='w-4/5 flex flex-col text-blue3A mt-4 mb-2 font-bold justify-between items-center'>
افزودن سوال <div className='w-11/12 flex flex-col bg-white rounded-xl border border-gray-300 shadow-md'>
</h1> <textarea className='w-full border-b border-gray-300 rounded-t-xl p-4 text-blue3A overflow-hideen text-right outline-none' placeholder="صورت سوال..." rows={1}
<div className="w-full flex items-center flex-col mt-6 px-2 "> onChange={(e) => titlePass(e.target.value)}
<input type='text' placeholder="صورت سوال..." className="w-full mb-6 p-4 ml-2 rounded border border-red52 h-12 text-red26 outline-none"
onChange={nameOnChange}
/> />
<div className="flex flex-wrap justify-between w-4/5">
{numberOfOptions == null ?
<select onChange={(e) => setNumberOfOptions(e.target.value)}>
<option>تعداد گزینه ها</option>
{
[1,2,3,4,5,6].map(
item => <option>{item}</option>
)
}
</select>
: <div className='w-full p-3 px-4 h-12 flex justify-between items-center'>
options.map((item) => ( <div>
<input type='text' placeholder={`گزینه ${item.id}`} className="my-1 p-4 rounded border border-red52 h-12 text-red26 outline-none" style={{ width: 'calc(50% - 15px)' }} <p className='text-xs'>نمره :
onChange={questionQuantityOnChange} <input type='number' className="w-6 h-6 border border-gray-200 mr-1 rounded"
onChange={(e) => scorePass(e.target.value)}
/> />
</p>
)) </div>
<input type='file' className="hidden" id="Add_Question_Add_Image" />
<label htmlFor="Add_Question_Add_Image" className="flex items-center">
<p className="text-gray-500 ml-1">آپلود</p>
<img src={attachIcon} className="h-full w-10" />
</label>
</div>
</div>
<div className='w-11/12 justify-between mt-4 flex flex-wrap'>
{
options?.map(
(item) => (
<div className='my-2 flex items-center justify-center shadow-md' style={{width: 'calc(50% - 10px)'}} onClick={() => setAsAnswer(item.id) }>
<p className={` h-12 flex items-center justify-center w-16 rounded-lg rounded-l-none ${item.isAnswer ? 'text-white bg-green-400' : 'bg-gray-200 border border-gray-300'}`}>{gozine[item.id - 1]}</p>
<input className={` h-12 outline-none flex items-center justify-center p-2 w-full rounded-lg rounded-r-none ${item.isAnswer ? 'bg-green-200' : 'bg-white border border-gray-300'}`}
onChange={e => passOptionTitle(e.target.value, item.id)}
placeholder={`گزینه ${item.id}`}/>
</div>
)
)
} }
</div> </div>
<div className="flex w-full justify-end pt-4"> <div></div>
<button className="px-6 py-2 rounded-md bg-red52 text-white font-bold" <div className="w-11/12 mt-5 flex justify-between items-center">
onClick={submitOnClick} <button className=" bg-white text-xl text-red-500 border-red-500 w-full h-12 mx-8 rounded-xl border" onClick={cancelOnClick
>
تایید }>
انصراف
</button> </button>
</div>
<button className=" bg-green-500 text-xl text-white border-green-500 w-full mx-8 h-12 rounded-xl border" onClick={
submitOnClick
}>
ثبت سوال
</button>
</div> </div>
</div> </div>
</div> </div>
</div>
) )
} }

@ -10,6 +10,7 @@ import RangeDatePicker from "../../../components/RangeDatePicker";
import SelectedCourse from "../../../components/selectedCourse"; import SelectedCourse from "../../../components/selectedCourse";
import AddQuestionnaireCourse from "../components/addQuestionnaireCourse"; import AddQuestionnaireCourse from "../components/addQuestionnaireCourse";
import Question from "../components/question"; import Question from "../components/question";
import { numOfinitQs } from "../../../redux/reducers/exam";
import AddQuestionPopUp from "../components/addQuestion"; import AddQuestionPopUp from "../components/addQuestion";
const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backStep }) => { const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backStep }) => {
@ -30,14 +31,7 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
title: '', title: '',
selectedQuestions: [], selectedQuestions: [],
}); });
const [answers, setAnswers] = useState(null);
const [newCourse, setNewCourse] = useState({
id: addExamState.questionairesCourses.length + 1,
questionnaireId: selectedCourse.id,
questionsQuantity: 20,
name: '',
coefficient: 4
})
// console.log(choosedQuestionaries) // console.log(choosedQuestionaries)
@ -53,21 +47,15 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
const [fakeState, setFakeState] = useState(2); const [fakeState, setFakeState] = useState(2);
useEffect(() => {
// questoinaresLists.map(item => showCoursesInList.push(false));
if (answers !== null && answers !== []) {
answers.map(item => dispatch({ type: 'ADD_ANSWERS', payload: item }))
}
}, [answers])
const payload = { name: name, description: description, type: type }; const payload = { name: name, description: description, type: type };
const handleOnDragEnd = (result) => { const handleOnDragEnd = (result) => {
const { source, destination } = result; const { source, destination } = result;
if (source.droppableId !== destination.droppableId) { if (source.droppableId !== destination?.droppableId) {
if (destination.droppableId == 'Choosed_Questions_Form_Bank') { if (destination?.droppableId == 'Choosed_Questions_Form_Bank') {
dispatch({ type: 'ADD_EXAM_QUESTIONS', payload: choosedQuestion }) dispatch({ type: 'ADD_EXAM_QUESTIONS', payload: choosedQuestion })
dispatch({ type: 'REMOVE_QUESTION_FROM_BANK', payload: choosedQuestion }) dispatch({ type: 'REMOVE_QUESTION_FROM_BANK', payload: choosedQuestion })
@ -99,6 +87,38 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
} }
} }
const [numberOfOptions, setNumberOfOptions] = useState(null);
const [options, setOptions] = useState([])
const [question, setQuestion] = useState({
title: '',
options: [],
})
useEffect(() => {
const arr = [];
for (var i = 1; i <= numberOfOptions; i++) {
arr.push({
id: i,
title: '',
isAnswer: false
})
}
setOptions(arr)
setQuestion({
...question,
options: arr,
courseId: selectedCourse.id,
questionId:numOfinitQs + addExamState.questionBank.length + fakeState,
})
}, [numberOfOptions])
console.log(question)
console.log(addExamState.courses.filter(itm => itm.id == selectedCourse.id)[0]?.selectedQuestions) console.log(addExamState.courses.filter(itm => itm.id == selectedCourse.id)[0]?.selectedQuestions)
return ( return (
<> <>
@ -166,10 +186,23 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
</div> </div>
} }
{ {
addQuestionPopup && addQuestionPopup === 'component' &&
<AddQuestionPopUp // <AddQuestionPopUp
closeOnClick={() => setAddQuestionPopuo(false)} // closeOnClick={() => setAddQuestionPopuo(false)}
/> // submitOnClick={data => {
// dispatch({type: 'ADD_CUSTOM_QUESTION', payload: {
// ...data,
// questionId:addExamState.questionBank.length + 1 ,
// courseId: selectedCourse.id,
// }})
// console.log({
// ...data,
// questionId: addExamState.questionBank.length + 1,
// courseId: selectedCourse.id,
// })
// }}
// />
<></>
} }
@ -210,7 +243,7 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
{(provided) => ( {(provided) => (
<div className="flex"> <div className="flex">
{provided.placeholder} {provided.placeholder}
<div className=" flex" {...provided.droppableProps} ref={provided.innerRef}> <div className=" flex " {...provided.droppableProps} ref={provided.innerRef}>
{addExamState.courses.length > 0 && {addExamState.courses.length > 0 &&
addExamState.courses.map( addExamState.courses.map(
(item, index) => ( (item, index) => (
@ -267,7 +300,7 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
seChoosedQuestion(addExamState.questionBank.find(itm => itm.questionId == result.source.index)) seChoosedQuestion(addExamState.questionBank.find(itm => itm.questionId == result.source.index))
} }
}}> }}>
<div className="w-full flex px-10"> <div className="w-full flex px-10 pl-0">
<Droppable droppableId="Choosed_Questions_Form_Bank"> <Droppable droppableId="Choosed_Questions_Form_Bank">
{(provided) => ( {(provided) => (
@ -278,8 +311,50 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
<h1 className="text-blue3A w-full font-bold text-lg text-right"> <h1 className="text-blue3A w-full font-bold text-lg text-right">
{selectedCourse.title} {selectedCourse.title}
</h1> </h1>
<div className="flex flex-col items-center "> <div className="flex flex-col items-center overflow-x-hidden overflow-scroll" style={{height: '550px'}}>
<div className="w-4/5 "> <div className="w-4/5 ">
{
addQuestionPopup === 'component' &&
<AddQuestionPopUp
titlePass={title => setQuestion({
...question,
title: title
})}
options={question.options}
setAsAnswer={e => {
let thisOption = question.options.find(itm => itm.id == e)
thisOption.isAnswer = !thisOption.isAnswer
setQuestion({
...question,
options : [...options]
})
}}
scorePass={score => setQuestion(
{
...question,
score: parseInt(score)
}
)}
passOptionTitle={(optionTitle, id) => {
let thisOption = question.options.find(itm => itm.id == id)
thisOption.title = optionTitle
setQuestion({
...question,
options : [...options]
})
}}
submitOnClick={() =>
{setAddQuestionPopuo(false)
dispatch({type: 'ADD_CUSTOM_QUESTION', payload: question});
setNumberOfOptions(null)
} }
cancelOnClick ={() => setAddQuestionPopuo(false)}
/>
}
{ {
addExamState.courses?.filter(itm => itm.id == selectedCourse.id)[0]?.selectedQuestions?.map( addExamState.courses?.filter(itm => itm.id == selectedCourse.id)[0]?.selectedQuestions?.map(
@ -303,20 +378,42 @@ const AddQuestionsFromBank = ({ grades, addExamState, dispatch, stepClick, backS
} }
{selectedCourse.id !== null && {selectedCourse.id !== null &&
<div className="w-full flex justify-center mt-10"> <div className="w-full flex justify-center mt-10">
<button className=" bg-gray-300 text-xl text-gray-500 border-gray-500 w-1/3 h-12 rounded-xl border" onClick={() => setAddQuestionPopuo(true)}> {addQuestionPopup == false ?
<button className=" bg-gray-300 text-xl text-gray-500 border-gray-500 w-1/3 h-12 rounded-xl border" onClick={() => setAddQuestionPopuo('select')}>
افزودن سوال افزودن سوال
</button> </button>
:
addQuestionPopup === 'select' &&
<select onChange={(e) => { setFakeState(fakeState + 5); setNumberOfOptions(e.target.value); setAddQuestionPopuo('component')}}>
<option>تعداد گزینه ها</option>
{
[1,2,3,4,5,6].map(
item => <option>{item}</option>
)
}
</select>
}
</div>} </div>}
</div> </div>
)} )}
</Droppable> </Droppable>
<div className="w-1/2 flex justify-center"> <div className="w-1/2 flex flex-col items-center justify-start">
<div className="w-full h-16 mb-1 bg-green-400 border-b border-gray-200">
</div>
<Droppable droppableId="QUESTIONS_IN_BANK"> <Droppable droppableId="QUESTIONS_IN_BANK">
{(provided) => ( {(provided) => (
<div className="w-full py-8 flex flex-col items-center "> <div className="w-full py-1 flex flex-col items-center overflow-x-hidden overflow-scroll" >
{selectedCourse.id !== null && <> {selectedCourse.id !== null && <>

Loading…
Cancel
Save