add note , add lesson , add category , add subexam | 350

main
alireza khaji 2 years ago
parent 093924033b
commit d92199f6b0
  1. 51
      src/components/selectedCourse/index.js
  2. 16
      src/redux/actions/exam.js
  3. 1
      src/redux/actions/index.js
  4. 23
      src/redux/actions/note.js
  5. 2
      src/redux/reducers/exam.js
  6. 2
      src/redux/reducers/exam2.js
  7. 1
      src/redux/reducers/file.js
  8. 1
      src/redux/reducers/index.js
  9. 37
      src/redux/reducers/note.js
  10. 5
      src/view/addExam/components/addQuestionnaireCourse.js
  11. 302
      src/view/addExam/views/addQuestionnaireExam.js

@ -1,42 +1,65 @@
import React from "react";
const SelectedCourse = ({ onClick, title, questionQuantity, coefficient, optionsQuantity }) => {
const SelectedCourse = ({
onClick,
title,
questionQuantity,
coefficient,
optionsQuantity,
optionsNumber,
}) => {
return (
<div className="w-full border border-gray-400 rounded-xl bg-white flex items-center justify-between px-6 py-8 mt-8">
<div className="flex flex-col w-full">
<h1 className="w-full text-lg text-right text-blue3A font-bold">
{title}
</h1>
<div className="w-full flex mt-4 justify-between">
<p className="flex items-center w-1/4 text-sm justify-between border-l-2 px-2 border-red52">
<p>تعداد سوالات</p>
<input type='number' className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center text-xs" value={questionQuantity} />
<input
type="number"
className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center text-xs"
value={questionQuantity}
/>
</p>
<p className="flex items-center w-1/4 text-sm justify-between border-l-2 px-2 border-red52">
<p className="w-full text-center"> ضریب</p>
<input type='number' className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center text-xs" value={coefficient} />
<input
type="number"
className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center text-xs"
value={coefficient}
/>
</p>
<p className="flex items-center w-1/4 text-sm justify-between border-l-2 px-2 border-red52">
<p>تعداد گزینه</p>
<input type='number' className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center text-xs" value={4} />
<input
type="number"
className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center text-xs"
value={optionsNumber || 4}
/>
</p>
<p className="flex items-center w-1/4 text-sm justify-between px-2 ">
<p>نمره منفی</p>
<input type='number' className="w-5 h-5 ml-1 border border-red52 outline-none rounded text-center" />
<input
type="checkbox"
className="note-course-negetive-point-input w-5 h-5 ml-1 border border-red52 outline-none rounded text-center"
/>
</p>
</div>
<textarea className="border border-gray-300 mt-8 rounded-xl h-32 p-4 outline-none" placeholder="توضیحات">
</textarea>
<textarea
className="border border-gray-300 mt-8 rounded-xl h-32 p-4 outline-none"
placeholder="توضیحات"
></textarea>
</div>
<h1 className="w-40 text-center text-lg text-blue3A font-bold cursor-pointer" onClick={onClick}>
<h1
className="w-40 text-center text-lg text-blue3A font-bold cursor-pointer"
onClick={onClick}
>
پاسخ برگ
</h1>
</div>
)
}
);
};
export default SelectedCourse;

@ -117,6 +117,22 @@ const exam = {
});
};
},
addExamQuestionaires: (data = {}) => {
return (dispatch) => {
dispatch({
type: "ADD_EXAM_QUESTIONAIRES",
payload: data,
});
};
},
addQuestionnaireCourse: (data = {}) => {
return (dispatch) => {
dispatch({
type: "ADD_QUESTIONNAIRE_COURSES",
payload: data,
});
};
},
};
export default exam;

@ -19,6 +19,7 @@ export { default as lesson } from "./lesson";
export { default as question } from "./question";
export { default as category } from "./category";
export { default as examQuestion } from "./examQuestion";
export { default as note } from "./note";

@ -0,0 +1,23 @@
import proxy from "../proxy";
const note = {
info:
(data = {}) =>
async (dispatch) =>
await proxy.get("note/info", data, { dispatch }),
list:
(data = {}) =>
async (dispatch) =>
await proxy.get("note/list", data, { dispatch }),
add:
(data = {}) =>
async (dispatch) =>
await proxy.post("note/add", data, { dispatch }),
delete:
(data = {}) =>
async (dispatch) =>
await proxy.delete("note/delete", data, { dispatch }),
};
export default note;

@ -225,7 +225,7 @@ export default function addExamReduser(
);
thisQ = {
...thisQ,
courses: [...thisQ.courses, payload],
courses: thisQ?.courses?.length ? [...thisQ?.courses, payload] :[payload],
};
console.log(thisQ);
return {

@ -9,6 +9,7 @@ const initialState = {
lastExamAdd: null,
preview: null,
subExamList: [],
lastSubExamAdd:null,
confirm:null
};
export default function exam2(state = initialState, action) {
@ -30,6 +31,7 @@ export default function exam2(state = initialState, action) {
...state,
loading: false,
error: null,
lastSubExamAdd:data.id,
subExamList: [...state.subExamList, data.id],
};
case "empty_subexam_list":

@ -11,6 +11,7 @@ export default function file(state = initialState, action) {
let { type, data, params } = action;
switch (type) {
case "file/upload":
toast.success("آپلود با موفقیت انجام شد")
return {
...state,
loading: false,

@ -19,5 +19,6 @@ export { default as lesson } from "./lesson";
export { default as question } from "./question";
export { default as category } from "./category";
export { default as examQuestion } from "./examQuestion";
export { default as note } from "./note";

@ -0,0 +1,37 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
info: null,
list: null,
lastAdd: null,
myNotes:[]
};
export default function note(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "note/info":
return { ...state, loading: false, info: data, error: null };
case "note/add":
toast.success("درخواست با موفقیت انجام شد");
return {
...state,
loading: false,
error: null,
lastAdd: data.id,
myNotes:[...state.myNotes,data.id]
};
case "note/list":
return { ...state, loading: false, error: null, list: data };
case "note/loading":
return { ...state, loading: true };
case "note/error":
toast.error(data.message);
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -7,6 +7,7 @@ const AddQuestionnaireCourse = ({
questionEnd,
coefficientOnChange,
closeOnClick,
optionsNumber,
}) => {
return (
<div className="w-full z-10 fixed h-screen backdrop-blur flex items-center -mt-10 justify-center">
@ -77,13 +78,13 @@ const AddQuestionnaireCourse = ({
type="number"
placeholder="ضریب ..."
className="w-4/5 p-4 ml-2 rounded border border-red52 h-12 text-red26 outline-none"
onChange={coefficientOnChange}
onChange={(e) => coefficientOnChange(e)}
/>
<input
type="number"
placeholder="تعداد گزینه"
className="w-4/5 p-4 ml-2 rounded border border-red52 h-12 text-red26 outline-none"
// onChange={}
onChange={(e) => optionsNumber(e)}
/>
</div>
<div className="flex w-full justify-end pt-4">

@ -11,13 +11,34 @@ import { DragDropContext } from "react-beautiful-dnd";
import { Droppable } from "react-beautiful-dnd";
import { Draggable } from "react-beautiful-dnd";
import { toMap } from "draft-js/lib/DefaultDraftBlockRenderMap";
import { category, exam, file, lesson, note } from "../../../redux/actions";
import loadingGiff from "../../../assets/img/Rolling-2s-223px.gif";
let lastCourseIndex;
const AddQuestionnaireExam = ({
grades,
addExamState,
dispatch,
stepClick,
backStep,
uploadNote,
lastUpload,
uploadLoading,
addExamQuestionaires,
addNoteLoading,
myNoteList,
addNote,
examId,
addLesson,
lastlessonAdd,
addCategory,
lastCategoryAdd,
addQuestionnaireCourse,
subexamList,
subexamAdd,
lastSubExamAdd,
}) => {
const [questionarePopUp, setQuestionairePopUp] = useState(false);
const [addCoursePopup, setAddCoursePopup] = useState(false);
@ -33,28 +54,31 @@ const AddQuestionnaireExam = ({
courses: [],
});
const [answers, setAnswers] = useState(null);
const [newCourse, setNewCourse] = useState({
id: selectedQuestionare.courses.length + selectedQuestionare.id + 1,
questionnaireId: selectedQuestionare.id,
questionsQuantity: 20,
name: "",
coefficient: 4,
});
const [selectedCourse, setSelectedCourse] = useState({
sortId: 1,
title: "ادبیات فارسی",
coefficient: 3,
questionStart: 1,
questionEnd: 0,
});
const [newCourse, setNewCourse] = useState(null);
// id: selectedQuestionare?.courses?.length + selectedQuestionare?.id + 1,
// questionnaireId: selectedQuestionare?.id,
// questionsQuantity: 20,
// name: "",
// coefficient: 4,
const [selectedCourse, setSelectedCourse] = useState(null);
const [subexamArray,setSubexamArray]=useState([]);
// {
// sortId: 1,
// title: "ادبیات فارسی",
// coefficient: 3,
// questionStart: 1,
// questionEnd: 0,
// }
// console.log(choosedQuestionaries)
// console.log(newQuestionaire)
// console.log(addExamState.questionnaires)
console.log(newCourse);
console.log(selectedQuestionare);
console.log(selectedCourse.id);
console.log(answers);
// console.log(newCourse);
// console.log(selectedQuestionare);
// console.log(selectedCourse?.id);
// console.log(answers);
const [noteSelectedId, setNoteSelectedId] = useState(null);
const [NoteList, setNoteList] = useState([]);
// const [noteAndCategory]
const [fakeState, setFakeState] = useState(2);
useEffect(() => {
setSelectedCourse(selectedCourse);
@ -68,13 +92,148 @@ const AddQuestionnaireExam = ({
}
}, [answers]);
//add note process =================================================================
console.log("=======myNoteList===================");
console.log(myNoteList);
const [noteFile, setNoteFile] = useState(null);
const noteChooseFile = () => {
let input = document.querySelector("#add-note-input-file");
input.click();
setNoteFile(input);
setFakeState(fakeState + 15);
// setNoteFile(input);
// setFakeState(Math.random()*1000);
};
const noteChangeFile = (e) => {
console.log("{{{}}}");
console.log(e.target.value);
setNoteFile(e.target.value);
};
const uploadNoteHandler = () => {
let input = document.querySelector("#add-note-input-file");
uploadNote({
file: input.files[0],
});
};
const submitNoteHandler = () => {
// dispatch({
// type: "",
// payload: newQuestionaire,
// });
addExamQuestionaires(newQuestionaire);
setQuestionairePopUp(false);
addNote({
name: newQuestionaire.name,
fileId: lastUpload,
examId: examId,
});
};
// useEffect(() => {
// setNewQuestionaire({
// ...newQuestionaire,
// id: lastNoteadd,
// });
// }, [lastNoteadd]);
//add lesson and category process =================================================================
// console.log("========selectedQuestionare=========");
// console.log(addExamState.questionnaires);
// console.log("========selectedQuestionare=========");
// console.log(addExamState.questionnaires);
console.log("========NoteList=========");
console.log(NoteList);
console.log("========subexamArray=========");
console.log(subexamArray);
const submitLessonhandler = () => {
addQuestionnaireCourse(newCourse);
setAddCoursePopup(false);
setFakeState(fakeState + 356);
addLesson({
name: newCourse.name,
});
};
useEffect(() => {
if (lastlessonAdd) {
addCategory({
title: newCourse.name,
lessonId: lastlessonAdd,
gradeId: addExamState.grade,
});
}
}, [lastlessonAdd]);
useEffect(() => {
if (lastCategoryAdd) {
setNoteList([
...NoteList,
{
noteId: noteSelectedId,
categoryId: lastCategoryAdd,
name: newCourse.name,
},
]);
}
}, [lastCategoryAdd]);
//===========================================================
const submitSubexam = (item, index) => {
lastCourseIndex = index;
setSelectedCourse(item);
console.log("a...............................a");
console.log(selectedCourse);
let negetiveInput = document.querySelectorAll(
".note-course-negetive-point-input"
);
let categoryId;
for (let i = 0; i < NoteList.length; i++) {
if (
noteSelectedId === NoteList[i].noteId &&
item?.name === NoteList[i].name
) {
categoryId = NoteList[i].categoryId;
break;
}
}
console.log({
noteId: noteSelectedId,
name: item?.name,
description: " ",
categoryId,
coefficient: item?.coefficient,
negativePoint: negetiveInput[index].checked,
questionType: item.optionsNumber || 2,
questionCount: Number(item.questionEnd) - Number(item.questionStart) + 1,
});
subexamAdd({
pid: examId,
ord:index+1,
noteId: noteSelectedId,
name: item?.name,
description: " ",
categoryId,
coefficient: item?.coefficient,
negativePoint: negetiveInput[index].checked,
questionType: item.optionsNumber || 2,
questionCount: Number(item.questionEnd) - Number(item.questionStart) + 1,
});
};
useEffect(() => {
if (lastSubExamAdd){
setSubexamArray([
...subexamArray,
{
index: lastCourseIndex,
subexamId: lastSubExamAdd,
noteId: noteSelectedId,
},
]);
}
}, [lastSubExamAdd]);
return (
<>
@ -143,31 +302,43 @@ const AddQuestionnaireExam = ({
انتخاب فایل
</div>
<div className="w-[20%] h-12 rounded border border-red53 flex items-center ltr text-xs px-2 overflow-hidden text-left text-ellipsis whitespace-normal">
{noteFile!==null ? noteFile?.value : "فایلی اضافه نشده"}
{noteFile !== null ? noteFile : "فایلی اضافه نشده"}
</div>
<div className="w-[10%] h-12 flex items-center justify-center text-sm rounded bg-[#111] text-white cursor-pointer">
{!uploadLoading && (
<div
className="w-[10%] h-12 flex items-center justify-center text-sm rounded bg-[#111] text-white cursor-pointer"
onClick={uploadNoteHandler}
>
آپلود
</div>
)}
{uploadLoading && (
<div className="w-[10%] h-12 flex items-center justify-center text-sm rounded bg-[#111] text-white cursor-pointer">
<img src={loadingGiff} alt="loadingGiff" className="h-9" />
</div>
)}
<input
type="file"
placeholder="آپلود فایل دفترچه"
className="bg-white items-center flex h-12 text-red26 outline-none hidden"
id="add-note-input-file"
onChange={(e) => noteChangeFile(e)}
/>
</div>
<div className="flex w-full justify-end pt-2">
{!addNoteLoading && (
<button
className="px-6 py-2 rounded-md bg-red52 text-white font-bold"
onClick={() => {
dispatch({
type: "ADD_EXAM_QUESTIONAIRES",
payload: newQuestionaire,
});
setQuestionairePopUp(false);
}}
onClick={submitNoteHandler}
>
تایید
</button>
)}
{addNoteLoading && (
<div className="w-16 h-10 flex items-center justify-center rounded-md bg-red52 text-white font-bold">
<img src={loadingGiff} alt="loadingGiff" className="h-8" />
</div>
)}
</div>
{/* {
@ -235,9 +406,12 @@ const AddQuestionnaireExam = ({
nameOnChange={(e) =>
setNewCourse({ ...newCourse, name: e.target.value })
}
coefficientOnChange={(e) =>
setNewCourse({ ...newCourse, coefficient: e.target.vlaue })
}
coefficientOnChange={(e) => {
setNewCourse({ ...newCourse, coefficient: e.target.value });
}}
optionsNumber={(e) => {
setNewCourse({ ...newCourse, optionsNumber: e.target.value });
}}
questionEnd={(e) =>
setNewCourse({
...newCourse,
@ -250,14 +424,10 @@ const AddQuestionnaireExam = ({
...newCourse,
questionStart: e.target.value,
questionnaireId: selectedQuestionare.id,
id: selectedQuestionare.id + selectedCourse.id + 1,
id: selectedQuestionare?.id + (selectedCourse?.id || 0) + 1,
})
}
submitOnClick={() => {
dispatch({ type: "ADD_QUESTIONNAIRE_COURSES", payload: newCourse });
setAddCoursePopup(false);
setFakeState(fakeState + 356);
}}
submitOnClick={submitLessonhandler}
/>
)}
{/* ==============================top-part============================= */}
@ -314,13 +484,16 @@ const AddQuestionnaireExam = ({
? "bg-pinkF5 border border-red52 text-red52"
: "bg-white border border-gray-300 text-blue3A"
} items-center justify-center w-36 h-32 mx-2 font-bold rounded-xl cursor-pointer`}
onClick={() =>
onClick={() => {
console.log("note click");
console.log(item);
setNoteSelectedId(myNoteList[index]);
setSelectedQuestionare({
id: item.id,
name: item.name,
courses: item.courses,
})
}
});
}}
>
<p className="text-red52">دفترچه {item.name}</p>
</div>
@ -353,8 +526,9 @@ const AddQuestionnaireExam = ({
</div>
</div>
</div>
{/* ====================================================================== */}
{/* ================================bottom-part====================================== */}
<div className="w-full flex px-10">
{/* ==============================b-right-part============================= */}
<div className="w-1/2 border-l flex flex-col border-gray-300 py-10">
{selectedQuestionare.id !== null && (
<>
@ -368,17 +542,17 @@ const AddQuestionnaireExam = ({
<div className="w-4/5 ">
{addExamState.questionnaires
.find((itm) => itm.id == selectedQuestionare.id)
?.courses.map((item, index) => (
?.courses?.map((item, index) => (
<React.Fragment key={index}>
<SelectedCourse
title={item.name}
coefficient={item.coefficient}
optionsNumber={item.optionsNumber}
questionQuantity={
item.questionEnd - item.questionStart
item.questionEnd - item.questionStart + 1
}
onClick={() => {
setSelectedCourse(item);
console.log(selectedCourse);
submitSubexam(item, index);
}}
/>
</React.Fragment>
@ -398,13 +572,14 @@ const AddQuestionnaireExam = ({
</div>
)}
</div>
{/* ==============================b-left-part============================= */}
<div className="w-1/2 flex justify-center">
<div className="w-4/5 py-8">
<AnswerSheet
selectedCourseId={selectedCourse.id}
selectedQId={selectedQuestionare.id}
questionEnd={selectedCourse.questionEnd}
questionStart={selectedCourse.questionStart}
selectedCourseId={selectedCourse?.id}
selectedQId={selectedQuestionare?.id}
questionEnd={selectedCourse?.questionEnd}
questionStart={selectedCourse?.questionStart}
passAnswers={(data) =>
dispatch({ type: "ADD_ANSWERS", payload: data })
}
@ -436,6 +611,29 @@ const AddQuestionnaireExam = ({
const mapStateToProps = (state) => ({
grades: state.publicApi.grades,
addExamState: state.addExamReduser,
lastUpload: state.file.lastUpload,
uploadLoading: state.file.loading,
addNoteLoading: state.note.loading,
myNoteList: state.note.myNotes,
lastNoteadd: state.note.lastAdd,
examId: state.exam2.lastExamAdd,
lastlessonAdd: state.lesson.lastAdd,
lastCategoryAdd: state.category.lastAdd,
subexamList: state.exam2.subExamList,
lastSubExamAdd: state.exam2.lastSubExamAdd,
});
export default connect(mapStateToProps)(AddQuestionnaireExam);
const mapDispatchToProps = {
uploadNote: file.upload,
addNote: note.add,
addExamQuestionaires: exam.addExamQuestionaires,
addLesson: lesson.add,
addCategory: category.add,
addQuestionnaireCourse: exam.addQuestionnaireCourse,
subexamAdd: exam.subexamAdd,
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(AddQuestionnaireExam);

Loading…
Cancel
Save