add new page "QuestionBank"

This commit is contained in:
karimaldeen 2024-09-14 16:21:57 +03:00
parent 693c1cdb06
commit 0b827ba990
19 changed files with 332 additions and 5 deletions

View File

@ -13,6 +13,7 @@
"Popconfirm", "Popconfirm",
"queryqlent", "queryqlent",
"registraion", "registraion",
"Sellcast",
"SENDNOTIFICATION", "SENDNOTIFICATION",
"setdateparams", "setdateparams",
"szhsin", "szhsin",

View File

@ -25,6 +25,7 @@ const TextField = ({
) => { ) => {
formik.setFieldValue(name, e.target.value); formik.setFieldValue(name, e.target.value);
}; };
return ( return (
<div className={`ValidationField w-100 ${className ?? ""} `}> <div className={`ValidationField w-100 ${className ?? ""} `}>
<ValidationFieldLabel <ValidationFieldLabel
@ -45,8 +46,8 @@ const TextField = ({
size="large" size="large"
showCount showCount
maxLength={1000} maxLength={1000}
autoSize={{ minRows: 4, maxRows: 10 }}
onChange={onChange || TextFilehandleChange} onChange={onChange || TextFilehandleChange}
style={{ height: 120 }}
id={name} id={name}
{...props} {...props}
/> />

View File

@ -0,0 +1,33 @@
import React from "react";
import { getInitialValues, getValidationSchema } from "./formUtil";
import { ModalEnum } from "../../../../enums/Model";
import LayoutModel from "../../../../Layout/Dashboard/LayoutModel";
import { QueryStatusEnum } from "../../../../enums/QueryStatus";
import ModelForm from "./ModelForm";
import { useAddGrade } from "../../../../api/grade";
const AddModel: React.FC = () => {
const { mutate, status } = useAddGrade();
const handleSubmit = (values: any) => {
mutate({
...values,
});
};
return (
<>
<LayoutModel
status={status as QueryStatusEnum}
ModelEnum={ModalEnum.GRADE_ADD}
modelTitle="grade"
handleSubmit={handleSubmit}
getInitialValues={getInitialValues({})}
getValidationSchema={getValidationSchema}
>
<ModelForm />
</LayoutModel>
</>
);
};
export default AddModel;

View File

@ -0,0 +1,38 @@
import React from "react";
import { getInitialValues, getValidationSchema } from "./formUtil";
import { ModalEnum } from "../../../../enums/Model";
import LayoutModel from "../../../../Layout/Dashboard/LayoutModel";
import ModelForm from "./ModelForm";
import { QueryStatusEnum } from "../../../../enums/QueryStatus";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { useUpdateQuestion } from "../../../../api/Question";
import { handelImageState } from "../../../../utils/DataToSendImageState";
const EditModel: React.FC = () => {
const { mutate, status } = useUpdateQuestion();
const { objectToEdit } = useObjectToEdit((state) => state);
const handleSubmit = (values: any) => {
const Data_to_send = { ...values };
const handelImage = handelImageState(Data_to_send, "icon");
mutate(handelImage);
};
return (
<>
<LayoutModel
status={status as QueryStatusEnum}
ModelEnum={ModalEnum.QUESTION_BANK_EDIT}
modelTitle="QuestionBank"
handleSubmit={handleSubmit}
getInitialValues={getInitialValues(objectToEdit)}
getValidationSchema={getValidationSchema}
isAddModal={false}
>
<ModelForm />
</LayoutModel>
</>
);
};
export default EditModel;

View File

@ -0,0 +1,20 @@
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
import { useFormikContext } from "formik";
const FilterForm = () => {
const formik = useFormikContext();
return (
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
);
};
export default FilterForm;

View File

@ -0,0 +1,17 @@
import { Col, Row } from "reactstrap";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
const Form = () => {
return (
<Row className="w-100">
<Col>
<ValidationField name="name" placeholder="name" label="name" />
</Col>
<Col>
<ValidationField name="icon" type="File" />
</Col>
</Row>
);
};
export default Form;

View File

@ -0,0 +1,19 @@
import * as Yup from "yup";
import { Grade, GradeInitialValues } from "../../../../types/Grade";
export const getInitialValues = (
objectToEdit: Partial<Grade>,
): GradeInitialValues => {
return {
id: objectToEdit?.id,
name: objectToEdit?.name ?? "",
icon: objectToEdit?.icon ?? "",
};
};
export const getValidationSchema = () => {
// validate input
return Yup.object().shape({
name: Yup.string().required("validation.required"),
});
};

View File

@ -0,0 +1,46 @@
import { useTranslation } from "react-i18next";
import { lazy, Suspense } from "react";
import { Spin } from "antd";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { ModalEnum } from "../../../enums/Model";
import { useDeleteQuestion } from "../../../api/Question";
import PageHeader from "../../../Layout/Dashboard/PageHeader";
import FilterLayout from "../../../Layout/Dashboard/FilterLayout";
import FilterForm from "./Model/FilterForm";
import { canAddQuestionBank } from "../../../utils/hasAbilityFn";
const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(
() => import("../../../Layout/Dashboard/DeleteModels"),
);
const TableHeader = () => {
const [t] = useTranslation();
const deleteMutation = useDeleteQuestion();
useSetPageTitle(t(`page_header.QuestionBank`));
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="QuestionBank"
ModelAbility={ModalEnum?.QUESTION_BANK_ADD}
canAdd={canAddQuestionBank}
/>
<FilterLayout sub_children={<FilterForm />} filterTitle="table.QuestionBank" />
<Table />
<AddModalForm />
<EditModalForm />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.QUESTION_BANK_DELETE}
/>
</Suspense>
</div>
);
};
export default TableHeader;

View File

@ -0,0 +1,18 @@
import { useColumns } from "./useTableColumns";
import React from "react";
import DataTable from "../../../Layout/Dashboard/Table/DataTable";
import { useGetAllQuestion } from "../../../api/Question";
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
const App: React.FC = () => {
const { filterState } = useFilterState();
const response = useGetAllQuestion({
pagination: true,
...filterState,
});
return <DataTable response={response} useColumns={useColumns} />;
};
export default App;

View File

@ -0,0 +1,83 @@
import { TableColumnsType } from "antd";
import { Question } from "../../../types/Item";
import { FaPlus } from "react-icons/fa";
import { ModalEnum } from "../../../enums/Model";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../../enums/abilities";
import { useNavigate } from "react-router-dom";
import { useModalState } from "../../../zustand/Modal";
import {
canAddQuestion,
canDeleteQuestion,
canEditQuestion,
} from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons";
export const useColumns = () => {
const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate();
const { setIsOpen } = useModalState((state) => state);
const handelAdd = () => {
setObjectToEdit({});
navigate(`${ABILITIES_ENUM?.QUESTION}/add`);
};
const handelDelete = (data: any) => {
setObjectToEdit(data);
setIsOpen(ModalEnum?.QUESTION_DELETE);
};
const handleEdit = (record: any) => {
setObjectToEdit(record);
navigate(`${ABILITIES_ENUM?.QUESTION}/${record?.id}`);
};
const [t] = useTranslation();
const columns: TableColumnsType<Question> = [
{
title: t("columns.id"),
dataIndex: "id",
key: "id",
align: "center",
render: (text, record) => record?.id,
},
{
title: `${t("columns.content")}`,
dataIndex: "name",
key: "name",
align: "center",
render: (text, record) => record?.content,
ellipsis: true,
},
{
title: t("columns.isBase"),
dataIndex: "isBase",
key: "isBase",
align: "center",
render: (text, record) =>
record?.isBase ? t("practical.yes") : t("practical.no"),
},
{
title: "#",
key: "actions",
align: "center",
render: (_text, record, index) => {
return (
<ActionButtons
canDelete={canDeleteQuestion}
canEdit={canEditQuestion}
index={index}
onDelete={() => handelDelete(record)}
onEdit={() => handleEdit(record)}
/>
);
},
},
];
return columns;
};

View File

@ -70,6 +70,7 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
type="TextArea" type="TextArea"
style={{ width: "100%" , height: 60,resize:"none" }} style={{ width: "100%" , height: 60,resize:"none" }}
showCount={false} showCount={false}
autoSize={{ minRows: 2, maxRows: 10 }}
/> />
</div> </div>
</> </>

View File

@ -89,6 +89,7 @@ const ChoiceFields = ({
type="TextArea" type="TextArea"
style={{ width: "100%" , height: 60,resize:"none" }} style={{ width: "100%" , height: 60,resize:"none" }}
showCount={false} showCount={false}
autoSize={{ minRows: 2, maxRows: 10 }}
/> />
</div> </div>
</> </>

View File

@ -142,6 +142,7 @@ const Form = () => {
label="hint_question" label="hint_question"
type="TextArea" type="TextArea"
style={{ width: "100%" , height: 60,resize:"none" }} style={{ width: "100%" , height: 60,resize:"none" }}
autoSize={{ minRows: 2, maxRows: 10 }}
showCount={false} showCount={false}
/> />
<MaltySelectTag parent_index={parent_index} /> <MaltySelectTag parent_index={parent_index} />

View File

@ -77,6 +77,7 @@ const Form = () => {
type="TextArea" type="TextArea"
style={{ width: "100%" , height: 60,resize:"none" }} style={{ width: "100%" , height: 60,resize:"none" }}
showCount={false} showCount={false}
autoSize={{ minRows: 2, maxRows: 10 }}
/> />
<SelectTag /> <SelectTag />

View File

@ -32,6 +32,7 @@ const EditReSeller = React.lazy(
const User = React.lazy(() => import("./Pages/Admin/User/Page")); const User = React.lazy(() => import("./Pages/Admin/User/Page"));
const Param = React.lazy(() => import("./Pages/Admin/Param/Page")); const Param = React.lazy(() => import("./Pages/Admin/Param/Page"));
const QuestionBank = React.lazy(() => import("./Pages/Admin/QuestionBank/Page"));
/// RESELLER /// /// RESELLER ///
const Student_Package = React.lazy( const Student_Package = React.lazy(
@ -129,6 +130,18 @@ export const menuItems: TMenuItem[] = [
prevPath: 0, prevPath: 0,
}, },
{
header: "page_header.questionBank",
element: <QuestionBank />,
icon: <FaSellcast />,
text: "sidebar.questionBank",
path: `/${ABILITIES_ENUM?.QUESTION}`,
abilities: ABILITIES_ENUM?.QUESTION,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
},
/// RESELLER ///// /// RESELLER /////
{ {

View File

@ -186,4 +186,11 @@ export enum ModalEnum {
Student_Package_EDIT = "Student_Package.edit", Student_Package_EDIT = "Student_Package.edit",
Student_Package_ADD = "Student_Package.add", Student_Package_ADD = "Student_Package.add",
Student_Package_DELETE = "Student_Package.delete", Student_Package_DELETE = "Student_Package.delete",
///QuestionBank
QUESTION_BANK_ADD = "QuestionBank.add",
QUESTION_BANK_EDIT = "QuestionBank.edit",
QUESTION_BANK_DELETE = "QuestionBank.delete",
} }

View File

@ -47,6 +47,7 @@ export enum ABILITIES_ENUM {
User = "user", User = "user",
RE_SELLER = "reseller", RE_SELLER = "reseller",
Student_Package = "student_package", Student_Package = "student_package",
QUESTION_BANK = "QuestionBank"
//// ////
} }

View File

@ -753,7 +753,8 @@
"reseller": "البائعين", "reseller": "البائعين",
"param": "معامل", "param": "معامل",
"student_package": "حزمة الطالب", "student_package": "حزمة الطالب",
"quiz":"الاختبارات" "quiz":"الاختبارات",
"QuestionBank":"بنك الأسئلة"
}, },
"message": { "message": {
"some_thing_went_wrong": "حدث خطأ ما", "some_thing_went_wrong": "حدث خطأ ما",
@ -788,7 +789,8 @@
"grade": "الصفوف", "grade": "الصفوف",
"report": "تقرير", "report": "تقرير",
"tags": "كلمات مفتاحية", "tags": "كلمات مفتاحية",
"reseller":"البائعين" "reseller":"البائعين",
"QuestionBank":"بنك الأسئلة"
}, },
"page_header": { "page_header": {
"dashboard": "لوحة القيادة / الصفحة الرئيسية", "dashboard": "لوحة القيادة / الصفحة الرئيسية",
@ -825,13 +827,15 @@
"reseller": " لوحة القيادة / البائعين", "reseller": " لوحة القيادة / البائعين",
"add_reseller": " لوحة القيادة / البائعين / إضافة بائع ", "add_reseller": " لوحة القيادة / البائعين / إضافة بائع ",
"param": "معامل", "param": "معامل",
"student_package": "حزمة الطالب" "student_package": "حزمة الطالب",
"QuestionBank":"لوحة القيادة / بنك الأسئلة"
}, },
"table": { "table": {
"student": "قائمة الطلاب", "student": "قائمة الطلاب",
"reseller": "البائعين", "reseller": "البائعين",
"grade": "قائمة الصفوف", "grade": "قائمة الصفوف",
"subjects": "مواد الصف" "subjects": "مواد الصف",
"QuestionBank":"بنك الأسئلة"
}, },
"alphabet": { "alphabet": {
"A": "A", "A": "A",

View File

@ -677,3 +677,25 @@ export const canDeleteStudent_Package = hasAbility(
); );
/// QuestionBank
export const canAddQuestionBank = hasAbility(
ABILITIES_ENUM.QUESTION_BANK,
ABILITIES_VALUES_ENUM.STORE,
);
export const canEditQuestionBank = hasAbility(
ABILITIES_ENUM.QUESTION_BANK,
ABILITIES_VALUES_ENUM.UPDATE,
);
export const canDeleteQuestionBank = hasAbility(
ABILITIES_ENUM.QUESTION_BANK,
ABILITIES_VALUES_ENUM.DELETE,
);
export const canShowQuestionBank = hasAbility(
ABILITIES_ENUM.QUESTION_BANK,
ABILITIES_VALUES_ENUM.SHOW,
);