Compare commits

..

No commits in common. '0fe9b16efd4f808d2cc497ba30984ff2f5091a85' and '98b14196a49310febc51face0abf69edf32a0d55' have entirely different histories.

  1. 13
      src/App.js
  2. 68
      src/components/AdminNav.js
  3. 1
      src/components/Table/Layouts/Main/components/Table.js
  4. 2
      src/components/Table/Layouts/Toolbar/index.js
  5. 14
      src/components/Table/components/Columns/index.js
  6. 4
      src/redux/actions/book.js
  7. 8
      src/redux/actions/exam.js
  8. 10
      src/redux/reducers/book.js
  9. 8
      src/redux/reducers/exam2.js
  10. 120
      src/view/Exam2/Exam.js
  11. 30
      src/view/Exam2/Header.js
  12. 55
      src/view/Exam2/Questions.js
  13. 2
      src/view/addExam/components/addQuestion.js
  14. 2
      src/view/addExam/index.js
  15. 1
      src/view/addExam/views/AddDescription.js
  16. 106
      src/view/school management/index.js
  17. 202
      src/view/school management/layouts/Editor.js

@ -45,8 +45,6 @@ import MyServices from "./view/my-services/MyServices";
import MobileMyServices from "./view/my-services/mobile/MyServices"; import MobileMyServices from "./view/my-services/mobile/MyServices";
import Exam from "./view/Exam2/Exam"; import Exam from "./view/Exam2/Exam";
import UserManagement from "./view/user-management"; import UserManagement from "./view/user-management";
import AdminNav from "./components/AdminNav";
import SchoolManagement from "./view/school management";
let data = [ let data = [
{ {
@ -684,17 +682,13 @@ function App() {
console.log("hhhhhhhh--------------------"); console.log("hhhhhhhh--------------------");
console.log(location.split("/")); console.log(location.split("/"));
return ( return (
<Provider store={store}> <Provider store={store}>
<div> <div>
<Router> <Router>
<div className="App"> <div className="App">
{LOGIN && !dontShowNav && <Header logOut={logOut} />} {LOGIN && !dontShowNav && <Header logOut={logOut} />}
{LOGIN && !dontShowNav && !location.includes("adminpanel") && ( {LOGIN && !dontShowNav && <Nav />}
<Nav />
)}
{location.includes("adminpanel") && <AdminNav />}
<Routes> <Routes>
<Route <Route
path="/" path="/"
@ -751,10 +745,7 @@ function App() {
path="/adminpanel/user-management" path="/adminpanel/user-management"
element={<UserManagement />} element={<UserManagement />}
/> />
<Route
path="/adminpanel/schools"
element={<SchoolManagement/>}
/>
<Route <Route
path="/register" path="/register"
element={<Register activeLogin={activeLogin} />} element={<Register activeLogin={activeLogin} />}

@ -1,68 +0,0 @@
import React from "react";
import { useState } from "react";
import { Link } from "react-router-dom";
let data = [
{
name: "داشبورد",
link: "/",
},
{
name: "مدارس",
link: "schools",
},
{
name: "محصولات",
link: "products",
},
{
name: "کد تخفیف",
link: "discount_codes",
},
{
name: "اضافه کردن آزمون",
link: "add-exam",
},
{
name: "خروج",
link: "#",
},
];
let location = window.location.pathname;
let intial = 0;
if (location.includes("schools")) {
intial = 1;
} else if (location.includes("products")) {
intial = 2;
} else if (location.includes("discount_codes")) {
intial = 3;
} else if (location.includes("add-exam")) {
intial = 4;
}
const AdminNav = () => {
const [activeNav, setActiveNav] = useState(intial);
const changeNav = (index) => {
setActiveNav(index);
};
return (
<div className="w-[120px] h-screen fixed flex flex-col top-0 right-0 bg-white z-[10] border-l border-[#e5e5e5]">
{data?.map((item, index) => (
<Link
to={`/adminpanel/${item.link}`}
className="w-full flex-1 flex items-center justify-center text-sm cursor-pointer"
style={
index === activeNav
? { backgroundColor: "#df1452", color: "#fff" }
: null
}
onClick={() => changeNav(index)}
>
{item?.name}
</Link>
))}
</div>
);
};
export default AdminNav;

@ -126,7 +126,6 @@ const Table = ({
// className={isEven(idx) ? "bg-gray-600" : "bg-white"} // className={isEven(idx) ? "bg-gray-600" : "bg-white"}
> >
{row.cells.map((cell, index) => { {row.cells.map((cell, index) => {
// {console.log(cell)}
return ( return (
<td <td
key={index} key={index}

@ -39,7 +39,7 @@ export const Toolbar = ({
activeOtherTab={activeOtherTab} activeOtherTab={activeOtherTab}
setActiveOtherTab={setActiveOtherTab} setActiveOtherTab={setActiveOtherTab}
/> />
<div className="flex py-2 bg-[#df145277] items-center gap-2 px-2"> <div className="flex py-2 bg-[#df145277] items-center gap-2 px-2 bg-sky-200">
<TableSearch <TableSearch
globalFilter={globalFilter} globalFilter={globalFilter}
setGlobalFilter={setGlobalFilter} setGlobalFilter={setGlobalFilter}

@ -14,7 +14,9 @@ const Components = {
date: ({ value }) => { date: ({ value }) => {
// return format(new Date(value), "dd/MM/yyyy"); // return format(new Date(value), "dd/MM/yyyy");
// return moment(value).locale("fa").format("YYYY-MM-DD") // return moment(value).locale("fa").format("YYYY-MM-DD")
return moment(value, "YYYY/MM/DD").locale("fa").format("YYYY/MM/DD"); return moment(value, "YYYY/MM/DD")
.locale("fa")
.format("YYYY/MM/DD")
}, },
OrderStatus, OrderStatus,
OrderLevel, OrderLevel,
@ -26,7 +28,7 @@ const Components = {
const Filters = { const Filters = {
SliderColumnFilter: SliderColumnFilter, SliderColumnFilter: SliderColumnFilter,
SelectFilter: SelectFilter, SelectFilter: SelectFilter,
ColumnSrarch: ColumnSearch, ColumnSrarch:ColumnSearch
}; };
export const COLUMNS = ({ export const COLUMNS = ({
@ -42,10 +44,10 @@ export const COLUMNS = ({
activeOtherTab, activeOtherTab,
}) => [ }) => [
...schema.map((e) => ({ ...schema.map((e) => ({
accessor: e?.name || e?.foreignKey || "id", accessor: e?.name,
Header: e?.description, Header: e?.description,
// Cell: e.renderer ? Components[e.renderer] : Components["text"], // Cell: e.renderer ? Components[e.renderer] : Components["text"],
Cell: e?.type ? Components[e.Component || e.type] : Components["text"], Cell: e?.type ? Components[e.type] : Components["text"],
Filter: e?.filter ? Filters[e.filter] : Filters["ColumnSrarch"], Filter: e?.filter ? Filters[e.filter] : Filters["ColumnSrarch"],
disableSortBy: e?.sort == false, disableSortBy: e?.sort == false,
Footer: "ستون " + e.description, Footer: "ستون " + e.description,
@ -78,6 +80,8 @@ export const COLUMNS = ({
}, },
]; ];
// Cell: ({ row }) => // Cell: ({ row }) =>
// Buttons({ // Buttons({
// row, // row,
@ -88,4 +92,4 @@ export const COLUMNS = ({
// setFake, // setFake,
// setActiveOtherTab, // setActiveOtherTab,
// activeOtherTab, // activeOtherTab,
// }), // }),

@ -8,10 +8,6 @@ const book = {
(data = {}) => (data = {}) =>
async (dispatch) => async (dispatch) =>
await proxy.get("product/schoolUsers", data, { dispatch }), await proxy.get("product/schoolUsers", data, { dispatch }),
schoolList:
(data = {}) =>
async (dispatch) =>
await proxy.get("product/schoolList", data, { dispatch }),
info: info:
(data = {}) => (data = {}) =>
async (dispatch) => async (dispatch) =>

@ -25,14 +25,6 @@ const exam = {
(data = {}) => (data = {}) =>
async (dispatch) => async (dispatch) =>
await proxy.get("exam/start", data, { dispatch }), await proxy.get("exam/start", data, { dispatch }),
end:
(data = {}) =>
async (dispatch) =>
await proxy.post("exam/end", data, { dispatch }),
setAnswer:
(data = {}) =>
async (dispatch) =>
await proxy.post("exam/set/answer", data, { dispatch }),
emptySubexamList: (data = {}) => { emptySubexamList: (data = {}) => {
return (dispatch) => { return (dispatch) => {
dispatch({ dispatch({

@ -4,7 +4,7 @@ const initialState = {
loading: false, loading: false,
error: null, error: null,
list: [], list: [],
schoolUserList: [], schoolUserList :[],
info: null, info: null,
searchResult: [], searchResult: [],
filterResult: [], filterResult: [],
@ -16,8 +16,6 @@ const initialState = {
sortFilterCourse: null, sortFilterCourse: null,
selectedGrade: null, selectedGrade: null,
selectedSort: "پربازدید ترین ها", selectedSort: "پربازدید ترین ها",
schoolList: [],
schema: [],
}; };
const grades = [ const grades = [
@ -64,11 +62,9 @@ export default function book(state = initialState, action) {
}; };
case "product/info": case "product/info":
return { ...state, loading: false, info: data, error: null }; return { ...state, loading: false, info: data, error: null };
case "product/schoolList":
return { ...state, loading: false, schoolList: data,schema: schema, error: null };
case "product/schoolUsers": case "product/schoolUsers":
console.log("{{{{{{-..-}}}}}}}"); console.log("{{{{{{-..-}}}}}}}")
console.log(action); console.log(action)
return { return {
...state, ...state,
loading: false, loading: false,

@ -11,9 +11,7 @@ const initialState = {
subExamList: [], subExamList: [],
lastSubExamAdd:null, lastSubExamAdd:null,
list:null, list:null,
confirm:null, confirm:null
lastAnswer:null,
end:null
}; };
export default function exam2(state = initialState, action) { export default function exam2(state = initialState, action) {
let { type, data } = action; let { type, data } = action;
@ -22,8 +20,6 @@ export default function exam2(state = initialState, action) {
return { ...state, loading: false, info: data, error: null }; return { ...state, loading: false, info: data, error: null };
case "exam/preview": case "exam/preview":
return { ...state, loading: false, preview: data, error: null }; return { ...state, loading: false, preview: data, error: null };
case "exam/set/answer":
return { ...state, loading: false, lastAnswer: data, error: null };
case "exam/confirm": case "exam/confirm":
toast.success("درخواست با موفقیت انجام شد"); toast.success("درخواست با موفقیت انجام شد");
return { ...state, loading: false, confirm: data, error: null }; return { ...state, loading: false, confirm: data, error: null };
@ -32,8 +28,6 @@ export default function exam2(state = initialState, action) {
return { ...state, loading: false, error: null, lastExamAdd: data.id }; return { ...state, loading: false, error: null, lastExamAdd: data.id };
case "exam/start": case "exam/start":
return { ...state, loading: false, list: data, error: null }; return { ...state, loading: false, list: data, error: null };
case "exam/end":
return { ...state, loading: false, end: data, error: null };
case "exam/subexamAdd": case "exam/subexamAdd":
toast.success("درخواست با موفقیت انجام شد"); toast.success("درخواست با موفقیت انجام شد");
return { return {

@ -2,131 +2,29 @@ import Header from "./Header";
import Questions from "./Questions"; import Questions from "./Questions";
import "./index.css"; import "./index.css";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { exam } from "../../redux/actions";
import { Link, useParams } from "react-router-dom";
import { useEffect } from "react";
import { useState } from "react";
let loadingCondition = false;
const Exam = ({
examData, const Exam = ({ examData }) => {
setAnswer,
endExam,
startExam,
examLoading,
end,
}) => {
const { id } = useParams();
console.log("Exam render=========================");
console.log("||||||||||||||||||||||||||||"); console.log("||||||||||||||||||||||||||||");
console.log(examData); console.log(examData);
const [endBox, setEndBox] = useState(false);
//getData after refresh-------------------------------------------
useEffect(() => {
console.log(examData);
if (!examData) {
// alert("hooo");
startExam({
examId: id,
});
}
}, []);
//active endBox================================
useEffect(() => {
if(end){
setEndBox(true);
}
}, [end]);
return ( return (
<div <div
className="Exam w-[100vw] min-h-screen px-28 pt-16 pb-8 relative z-[200] bg-[#fff]" className="Exam w-[100vw] px-28 pt-16 pb-8 relative"
style={{ width: "calc(100vw - 5px)" }} style={{ width: "calc(100vw - 5px)" }}
> >
{examData && <Header info={examData?.exam} examData={examData} />} <Header />
{examData && examData ( <Questions questions={examData?.questions} />
<Questions
questions={examData?.questions}
setAnswer={setAnswer}
endExam={endExam}
info={examData?.exam}
/>
)}
{examLoading && !examData && (
<div className="w-full text-center text-xl rtl mt-8">
در حال گرفتن اطلاعات..
</div>
)}
{endBox && (
<div className="w-screen h-screen flex items-center justify-center fixed top-0 left-0 backdrop-blur-xl bg-[#ffffff20] z-[300] p-3 overflow-hidden">
<div className="w-3/4 h-2/3 rounded-lg bg-white border border-[#c9c9c9]">
<div className="w-full h-1/5 flex items-center justify-center text-center text-xl rtl bg-green-600 text-white rounded-t">
جواب های شما با موفقیت ثبت شد.
</div>
<div className="w-full h-1/5 flex items-center justify-center text-center text-xl rtl">
نتیجه اولیه:
</div>
<div className="w-full h-2/5 px-6">
<div className="w-full h-1/3 flex rtl bg-red52 rounded-t">
<div className="flex-1 h-full flex items-center justify-center px-1 text-xs text-white">
تعداد گزینه صحیح
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 text-xs text-white">
تعداد گزینه غلط
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 text-xs text-white">
تعداد گزینه بدون جواب
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 text-xs text-white">
درصد
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 text-xs text-white">
نمره ({end?.totalPoint})
</div>
</div>
<div className="w-full h-1/3 flex rtl border border-red52 rounded-b bg-white">
<div className="flex-1 h-full flex items-center justify-center px-1 text-sm">
{end?.correct}
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 rtl text-sm">
{end?.incorrect}
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 rtl text-sm">
{end?.notAnswerd}
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 ltr text-sm">
{end?.percent}
</div>
<div className="flex-1 h-full flex items-center justify-center px-1 ltr text-sm">
{end?.point}
</div>
</div>
</div>
<div className="w-full h-1/5 flex items-center justify-center">
<Link
to="/services"
className="p-4 text-base text-white bg-red52 rounded cursor-pointer"
>
خروج از آزمون
</Link>
</div>
</div>
</div>
)}
</div> </div>
); );
}; };
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
examData: state.exam2.list, examData : state.exam2.list
examLoading: state.exam2.loading,
end: state.exam2.end,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
setAnswer: exam.setAnswer,
endExam: exam.end,
startExam: exam.start,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Exam); export default connect(mapStateToProps, mapDispatchToProps)(Exam);

@ -1,18 +1,9 @@
import { useEffect, useState } from "react"; import { useState } from "react";
import { RiTimerLine } from "react-icons/ri"; import { RiTimerLine } from "react-icons/ri";
import './index.css'; import './index.css';
const Header = ({ info, examData }) => { const Header=()=>{
console.log("header render===================");
const [timer, setTimer] = useState(null);
useEffect(() => {
if (info?.duration === info?.remainingTime) {
setTimer(info?.duration);
} else {
setTimer(info?.remainingTime +1);
}
}, [info]);
return ( return (
<div className="Header w-full h-14 fixed top-2 left-0 px-28 bg-white"> <div className="Header w-full h-14 fixed top-2 left-0 px-28 bg-white">
<div className="w-full h-full flex flex-row-reverse items-center justify-between rounded-lg border border-[#ECECEC] px-6"> <div className="w-full h-full flex flex-row-reverse items-center justify-between rounded-lg border border-[#ECECEC] px-6">
@ -20,28 +11,25 @@ const Header = ({ info, examData }) => {
className="text-right text-sm text-right" className="text-right text-sm text-right"
style={{ width: "calc(100% - 220px)" }} style={{ width: "calc(100% - 220px)" }}
> >
{info?.name} آزمون تیزهوشان درس تاریخ باستان
</div> </div>
<div className="w-52 flex items-center gap-x-2"> <div className="w-52 flex items-center gap-x-2">
<div className="w-[30%]"> <div className="w-[30%]">
{timer && <Timer timer={timer} />} <Timer/>
</div>
<div className="text-sm" style={{ direction: "rtl" }}>
زمان باقیمانده :
</div> </div>
<div className="text-sm" style={{direction:'rtl'}}>زمان باقیمانده :</div>
<RiTimerLine className="text-xl text-[#DF1452]" /> <RiTimerLine className="text-xl text-[#DF1452]" />
</div> </div>
</div> </div>
</div> </div>
); );
}; }
export default Header; export default Header;
const Timer = ({ timer }) => { const Timer = ({ cellphone }) => {
console.log(timer); const [min, setMin] = useState(10);
const [min, setMin] = useState(timer); const [sec, setSec] = useState(30);
const [sec, setSec] = useState(0);
const [showBtn, setShowbtn] = useState(false); const [showBtn, setShowbtn] = useState(false);
setTimeout(() => { setTimeout(() => {

@ -1,6 +1,6 @@
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { RiErrorWarningLine } from "react-icons/ri"; import { RiErrorWarningLine } from "react-icons/ri";
import "./index.css"; import './index.css';
import img1 from "../../assets/img/4bea9a991c6b23d3dcaf231513ee94bd.jpg"; import img1 from "../../assets/img/4bea9a991c6b23d3dcaf231513ee94bd.jpg";
// let data = [ // let data = [
@ -76,17 +76,17 @@ import img1 from "../../assets/img/4bea9a991c6b23d3dcaf231513ee94bd.jpg";
// ]; // ];
//badgeList------------- //badgeList-------------
let badgeList = ["الف", "ب", "ج", "د", "هـ", "ز"]; let badgeList = ["الف", "ب", "ج", "د","هـ","ز"];
const Questions = ({ questions, setAnswer, endExam ,info}) => { const Questions = ({questions}) => {
const [Data, setData] = useState(null); const [Data, setData] = useState(null);
console.log("Questions render-----------------"); console.log("exam render-----------------")
console.log(Data); console.log(Data);
const [fake, setFake] = useState(0); const [fake, setFake] = useState(0);
const [layoutTrigger, setLayoutTrigger] = useState(0); const [layoutTrigger,setLayoutTrigger]=useState(0);
const [answerList, setAnswerList] = useState([]); const [answerList, setAnswerList] = useState([]);
//create local data from api data ------------------------------------- //create local data from api data -------------------------------------
const createChoices = (item) => { const createChoices=(item)=>{
let list = []; let list = [];
let options = [ let options = [
item["question.option1"], item["question.option1"],
@ -98,14 +98,14 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
for (let i = 0; i < item["question.type"]; i++) { for (let i = 0; i < item["question.type"]; i++) {
list.push(options[i]); list.push(options[i]);
} }
return list; return(list)
}; }
useEffect(() => { useEffect(() => {
let newList = []; let newList =[];
console.log("create data useEffect------------------------"); console.log("create data useEffect------------------------");
for (let i = 0; i < questions?.length; i++) { for (let i = 0; i < questions?.length; i++) {
newList.push({ newList.push({
id: questions[i].id, id: questions[i]["question.id"],
text: questions[i]["question.text"], text: questions[i]["question.text"],
fileId: questions[i]["question.fileId"], fileId: questions[i]["question.fileId"],
choices: createChoices(questions[i]), choices: createChoices(questions[i]),
@ -114,12 +114,10 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
choiceHeight: null, choiceHeight: null,
}); });
} }
setData(newList);
console.log("created data-----------------------"); console.log("created data-----------------------");
console.log(newList); console.log(newList);
if(newList.length>0){ setFake(Math.random()*10000);
setData(newList);
}
setFake(Math.random() * 10000);
setLayoutTrigger(Math.random() * 10000); setLayoutTrigger(Math.random() * 10000);
}, [questions]); }, [questions]);
//-------------------------------------------------- //--------------------------------------------------
@ -130,7 +128,6 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
); );
console.log(Data); console.log(Data);
if (Data) { if (Data) {
console.log("layout setting start----------");
let newData = Data; let newData = Data;
let data = Data; let data = Data;
let defaultAnswers = []; let defaultAnswers = [];
@ -182,12 +179,9 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
newData[i].choiceWidth = "full"; newData[i].choiceWidth = "full";
} }
} }
console.log(newData);
setData(newData); setData(newData);
setAnswerList(defaultAnswers); setAnswerList(defaultAnswers);
setFake(fake + 1); setFake(fake + 1);
}else{
// setLayoutTrigger(Math.random() * 10000);
} }
}, [questions, layoutTrigger]); }, [questions, layoutTrigger]);
@ -208,21 +202,6 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
setFake(fake + 1); setFake(fake + 1);
}; };
//submit answer ===================================
const submitAnswer = (id, answer) => {
setAnswer({
userAnswerId: id,
answer: answer,
});
};
//end exam ============================
const endExamHandler =()=>{
endExam({
userExamId: info.id,
});
}
return ( return (
<div className="Questions w-full mt-10"> <div className="Questions w-full mt-10">
{Data?.map((item, index) => ( {Data?.map((item, index) => (
@ -269,10 +248,7 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
? { width: `${item.choiceWidth}%` } ? { width: `${item.choiceWidth}%` }
: null : null
} }
onClick={() => { onClick={() => chooseHandler(index, INDEX)}
chooseHandler(index, INDEX);
submitAnswer(item.id, choice);
}}
> >
<div <div
className="w-14 py-4 flex items-center justify-center text-sm rounded-r-md bg-[#D5DEEA]" className="w-14 py-4 flex items-center justify-center text-sm rounded-r-md bg-[#D5DEEA]"
@ -332,10 +308,7 @@ const Questions = ({ questions, setAnswer, endExam ,info}) => {
کلیک کنید کلیک کنید
</div> </div>
</div> </div>
<div <div className="w-full h-12 rounded-md flex items-center justify-center bg-[#DF1452] text-white cursor-pointer mt-6">
className="w-full h-12 rounded-md flex items-center justify-center bg-[#DF1452] text-white cursor-pointer mt-6"
onClick={endExamHandler}
>
ثبت پاسخها و اتمام آزمون ثبت پاسخها و اتمام آزمون
</div> </div>
</div> </div>

@ -128,7 +128,7 @@ const AddQuestionPopUp = ({
</button> </button>
<button <button
className=" bg-green-500 text-xs text-white border-green-500 w-full ml-0 mx-3 h-12 rounded-md border " className=" bg-green-500 text-xl text-white border-green-500 w-full ml-0 mx-3 h-12 rounded-md border"
onClick={submitOnClick} onClick={submitOnClick}
> >
ثبت سوال ثبت سوال

@ -64,7 +64,7 @@ const AddExam = () => {
] ]
return( return(
<div className='flex flex-col overflow-scroll overflow-x-hidden py-[4%] bg-grayFD rtl' style={{height: '100vh',width:"calc(100vw - 120px)"}}> <div className='flex flex-col w-[96%] overflow-scroll overflow-x-hidden py-[4%] bg-grayFD rtl' style={{height: '100vh'}}>
<div className='flex w-full items-center py-2 pb-5 px-10 border-b border-gray-300'> <div className='flex w-full items-center py-2 pb-5 px-10 border-b border-gray-300'>
<h1 className="text-blue3A text-lg font-bold w-1/5 text-right px-4 border-r-4 border-blue65"> <h1 className="text-blue3A text-lg font-bold w-1/5 text-right px-4 border-r-4 border-blue65">
ساخت آزمون جدید ساخت آزمون جدید

@ -106,7 +106,6 @@ const AddExamDescription = ({
parentAdd({ parentAdd({
name: name, name: name,
description: description, description: description,
gradeId: addExamState.grade,
// startDate: moment( // startDate: moment(
// `${addExamState.startDate?.year}/${addExamState.startDate?.month}/${addExamState.startDate?.day} ${addExamState.startDate?.hour}:${addExamState.startDate?.minute}` // `${addExamState.startDate?.year}/${addExamState.startDate?.month}/${addExamState.startDate?.day} ${addExamState.startDate?.hour}:${addExamState.startDate?.minute}`
// ) // )

@ -1,106 +0,0 @@
import React, { useMemo, useState } from "react";
import { useEffect } from "react";
import { connect } from "react-redux";
import Table from "../../components/Table";
import * as actions from "../../redux/actions";
import Editor from "./layouts/Editor";
const source = "book";
const title = " مدیریت کاربران";
const SchoolMangement = ({
info,
getData,
tabs,
setTabs,
add,
update,
getSchoolList,
schoolList,
schoolUserList,
schema,
}) => {
useMemo(() => {
// getData({ num: 1000 });
getSchoolList();
}, []);
// console.log(info);
console.log("SchoolManagement render---------------------------------");
console.log(schoolList);
console.log(schema);
console.log(info);
// console.log("==============^tabs^==============");
// console.log(tabs);
useEffect(() => {
setTabs([
{
id: 0,
name: title,
isActive: true,
element: "table",
},
]);
}, []);
// console.log(tabs);
// const [tabs, setTabs] = useState([
// {
// id: 0,
// name: title,
// isActive: true,
// },
// ]);
const [activeOtherTab, setActiveOtherTab] = useState(false);
const [fake, setFake] = useState(0);
const [schoolId, setSchoolId] = useState(null);
const [setp, setStep] = useState(1);
const submitHandler = () => {
getData({ id: schoolId });
setStep(2);
};
return (
<div
className="UserManagement w-[95.5%] h-screen max-h-screen bg-[#F8F8F8] overflow-y-auto rtl relative"
// style={{ width: "calc(100% - 4.5%)" }}
>
<div className="flex flex-1 w-full pt-12 pb-4">
<Table
// data={schoolList || []}
data={[]}
schema={schema || []}
Editor={Editor}
add={add}
update={update}
getData={getData}
title={title}
tabs={tabs}
setTabs={setTabs}
fake={fake}
setFake={setFake}
activeOtherTab={activeOtherTab}
setActiveOtherTab={setActiveOtherTab}
/>
</div>
</div>
);
};
const mapStateToProps = (state) => ({
info: state[source],
tabs: state.table.tabs,
schoolList: state.book.schoolList,
schoolUserList: state.book.schoolUserList,
schema:state.book.schema
});
const mapDispatchToProps = {
// getData: actions[source].list,
getData: actions[source].schoolUser,
setTabs: actions.table.setTab,
update: actions[source].update,
add: actions[source].add,
getSchoolList: actions.book.schoolList,
};
export default connect(mapStateToProps, mapDispatchToProps)(SchoolMangement);

@ -1,202 +0,0 @@
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { file } from "../../../redux/actions";
import loadingGiff from "../../../assets/img/Rolling-1s-200px.gif";
import SimpleDatePicker from "../../../components/SimpleDatePicker";
import moment from "jalali-moment";
const baseUrl = "https://light.barnamenegar.com/api/v1";
const components = (props) => ({
text: (
<input
type="text"
className="table-edit-input w-full py-3 px-2 rounded-md border border-[#D5DEEA]"
{...props}
/>
),
string: (
<textarea
type="text"
className="table-edit-input w-full py-3 px-2 rounded-md border border-[#D5DEEA]"
{...props}
/>
),
number: (
<input
type="number"
className="table-edit-input w-full py-3 px-2 rounded-md border border-[#D5DEEA]"
{...props}
/>
),
select: (
<select
type="text"
className="table-edit-input w-full py-3 px-2 rounded-md border border-[#D5DEEA]"
{...props}
>
{Object.entries(props?.options || {}).map(([v, k]) => (
<option value={v} key={v}>
{k}
</option>
))}
</select>
),
file: (
<div className="table-edit-input w-full py-3 px-2 rounded-md border border-[#D5DEEA] flex justify-between bg-[#fff]">
<div className="w-full flex items-center">
<div
className="w-fit w-24 text-center py-1 rounded bg-[#111] text-white text-sm cursor-pointer"
onClick={props.chooseFile}
>
انتخاب فایل
</div>
{/* <div className="text-xs mt-2 text-right">{props.fileNmae}</div> */}
{props.fileNmae && !props.loading && (
<div
className="w-fit w-24 py-1 rounded bg-[#65A9FF] text-white text-sm mr-2 cursor-pointer"
onClick={props.uploadHandler}
>
آپلود
</div>
)}
{props.loading && (
<img src={loadingGiff} alt="loadingGiff" className="h-10 mr-2" />
)}
<input
className="edit-file-input w-0 h-0 hidden"
id="edit-file-input"
type={"file"}
// onChange={(e) => {
// props.setFileName(e.target.value);
// }}
onChange={(e) => props.fileInputHandler(e)}
/>
</div>
{props.defaultValue && !props?.fileNmae ? (
<img
src={baseUrl + "/file/" + props.defaultValue}
className="edit-file-img-placeholder h-10"
/>
) : null}
{props?.fileNmae && (
<img src={props?.fileNmae} className="edit-file-img-placeholder h-10" />
)}
</div>
),
date: (
<div className="w-full">
<SimpleDatePicker returnValue={props.setDateInfo} mode={props.mode} />
</div>
),
});
const Filed = (props) => {
return components(props)[props.type] || <div>{props.type}</div>;
};
const Editor = ({ data, schema, update, add, loading,lastUpload,uploadFile }) => {
const [info, setInfo] = useState(data ? { id: data?.original?.id } : {});
const changeInputHandler = (e, key) => {
setInfo({ ...info, [key]: e.target.value });
};
useEffect(() => {
if (lastUpload) {
setInfo({ ...info, fileId: String(lastUpload) });
}
}, [lastUpload]);
const submitHandler = () => {
if (data) update(info);
else add(info);
console.log(info);
};
const [fileNmae, setFileName] = useState(null);
const chooseFile = () => {
document.querySelector(".edit-file-input").click();
};
const fileInputHandler = (e) => {
console.log(e.target.value);
if (e.target.files && e.target.files[0]) {
var reader = new FileReader();
reader.onload = function (event) {
setFileName(event.target.result);
};
reader.readAsDataURL(e.target.files[0]);
}
};
const uploadHandler=()=>{
uploadFile({
file: document.querySelector("#edit-file-input").files[0],
});
}
const [dateInfo,setDateInfo]=useState(null);
const datehandler=(value,mode)=>{
setDateInfo({ ...value,mode});
}
useEffect(() => {
console.log("::::::::::::::::::::::::::::::::::::::::::::-")
console.log(dateInfo);
if(dateInfo?.day){
setInfo({
...info,
[dateInfo.mode]: moment(
`${dateInfo?.year}/${dateInfo?.month}/${dateInfo?.day}`
)
.locale("en")
.format("YYYY-MM-DD"),
});
}
}, [dateInfo]);
return (
<div className="w-full py-3" key={data?.id || 0}>
{console.log({ data })}
<div className="w-full flex rtl flex-wrap items-center justify-between gap-y-6">
{schema?.map((item, index) => (
<div key={index} className="w-1/2 shrink-0 flex items-center ">
<div className="w-1/6 text-sm ml-2">{item?.description}:</div>
<Filed
type={
item?.options
? "select"
: item.name == "fileId"
? "file"
: item?.type
}
options={item?.options}
defaultValue={data?.original[item?.name]}
onChange={(e) => changeInputHandler(e, item?.name)}
fileNmae={fileNmae}
setFileName={setFileName}
chooseFile={chooseFile}
fileInputHandler={fileInputHandler}
uploadHandler={uploadHandler}
loading={loading}
setDateInfo={datehandler}
mode={item?.name}
/>
</div>
))}
</div>
<div
className="px-6 py-4 w-fit rounded-md bg-[#df1452] text-[#fff] text-base cursor-pointer mx-auto mt-6"
onClick={submitHandler}
>
{data ? "ثبت تغییرات" : "ثبت ردیف"}
</div>
</div>
);
};
const mapStateToProps = (state) => ({
loading: state.file.loading,
lastUpload: state.file.lastUpload,
});
const mapDispatchToProps = {
uploadFile : file.upload
};
export default connect(mapStateToProps, mapDispatchToProps)(Editor);
Loading…
Cancel
Save