Compare commits
No commits in common. "a05bb8b46d5d4eeb4846da90ed3d7e3883b11221" and "e470e902e58d9d922f404014ea9e559b6184a07c" have entirely different histories.
a05bb8b46d
...
e470e902e5
|
|
@ -1,33 +1,43 @@
|
|||
import {
|
||||
DownloadOutlined,
|
||||
RotateLeftOutlined,
|
||||
RotateRightOutlined,
|
||||
SwapOutlined,
|
||||
ZoomInOutlined,
|
||||
ZoomOutOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import { Image, Space } from "antd";
|
||||
import { CiImageOff } from "react-icons/ci"; // Assuming you're using this icon from react-icons
|
||||
import useImageError from "../../Hooks/useImageError";
|
||||
import { ErrorImage } from "../../Layout/app/Const";
|
||||
|
||||
const ColumnsImage = ({ src }: any) => {
|
||||
const [hasError, setHasError] = useState(false); // Track if the image has an error
|
||||
const imageUrl = src || ErrorImage;
|
||||
|
||||
const imageUrl = src;
|
||||
const handleError = useImageError;
|
||||
// or you can download flipped and rotated image
|
||||
// https://codesandbox.io/s/zi-ding-yi-gong-ju-lan-antd-5-7-0-forked-c9jvmp
|
||||
const onDownload = () => {
|
||||
fetch(src)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const url = URL.createObjectURL(new Blob([blob]));
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = "image.png";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
link.remove();
|
||||
});
|
||||
};
|
||||
|
||||
if (hasError) {
|
||||
// If there is an error, display the fallback icon
|
||||
return <CiImageOff />;
|
||||
}
|
||||
if(!imageUrl){
|
||||
return <CiImageOff />;
|
||||
}
|
||||
return (
|
||||
<Image
|
||||
width={45}
|
||||
height={45}
|
||||
src={imageUrl}
|
||||
className="p-1 mb-1 columnImage"
|
||||
onError={() => setHasError(true)} // Triggered when image fails to load
|
||||
className="p-1 mb-1 columnImage "
|
||||
preview={{
|
||||
toolbarRender: (
|
||||
_,
|
||||
|
|
@ -44,6 +54,7 @@ const ColumnsImage = ({ src }: any) => {
|
|||
},
|
||||
) => (
|
||||
<Space size={12} className="toolbar-wrapper">
|
||||
{/* <DownloadOutlined onClick={onDownload} /> */}
|
||||
<SwapOutlined rotate={90} onClick={onFlipY} />
|
||||
<SwapOutlined onClick={onFlipX} />
|
||||
<RotateLeftOutlined onClick={onRotateLeft} />
|
||||
|
|
@ -53,8 +64,19 @@ const ColumnsImage = ({ src }: any) => {
|
|||
</Space>
|
||||
),
|
||||
}}
|
||||
onError={handleError}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ColumnsImage;
|
||||
|
||||
// {
|
||||
// name: t("image"),
|
||||
// center: "true",
|
||||
// cell: (row: any) => {
|
||||
// return (
|
||||
// <ColumnsImage src={row?.image} />
|
||||
// )
|
||||
// }
|
||||
// },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IoSearch } from "react-icons/io5";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useFilterStateState } from "../../zustand/Filter";
|
||||
import { useDebounce } from "../../utils/useDebounce";
|
||||
|
||||
|
|
@ -13,16 +15,15 @@ const SearchField: React.FC<Props> = ({ placeholder, searchBy }) => {
|
|||
const [searchQuery, setSearchQuery] = useState<string>("");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const { setFilter,Filter } = useFilterStateState();
|
||||
const { setFilter } = useFilterStateState();
|
||||
|
||||
const handleInputChange = (value: string) => {
|
||||
setSearchQuery(value);
|
||||
};
|
||||
console.log(searchBy,"searchBy");
|
||||
|
||||
|
||||
const handleInputChangeWithDebounce = useDebounce((value: string) => {
|
||||
setFilter({
|
||||
[searchBy]: value,
|
||||
name: value,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
min-height: 80px;
|
||||
// padding-inline: 20px;
|
||||
padding-inline: 20px;
|
||||
> * {
|
||||
width: 100% !important;
|
||||
min-width: 150px;
|
||||
|
|
|
|||
|
|
@ -14,15 +14,9 @@ import useFilter from "../../Components/Utils/Filter/useFilter";
|
|||
const FilterLayout = ({
|
||||
filterTitle,
|
||||
sub_children,
|
||||
search_by = "name",
|
||||
width = "500px",
|
||||
haveFilter=true
|
||||
}: {
|
||||
filterTitle: string;
|
||||
sub_children: any;
|
||||
search_by?:string
|
||||
width?:string
|
||||
haveFilter?:boolean
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const translateArray = translateOptions(search_array, t);
|
||||
|
|
@ -43,23 +37,17 @@ const FilterLayout = ({
|
|||
ModelClassName="filter_model_direction"
|
||||
isOpen={isOpen}
|
||||
setIsOpen={setIsOpen}
|
||||
width={width}
|
||||
>
|
||||
<div className="model_sub_children">{sub_children}</div>
|
||||
<FilterSubmit />
|
||||
</FilterBody>
|
||||
{haveFilter &&
|
||||
|
||||
<div className="filter_button" onClick={() => setIsOpen(true)}>
|
||||
<div className="filter_button" onClick={() => setIsOpen(true)}>
|
||||
<span>
|
||||
<BiFilterAlt className="addition_select_icon" />
|
||||
{t("header.filter")}
|
||||
</span>
|
||||
<MdKeyboardArrowDown />
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
|
|
@ -78,7 +66,7 @@ const FilterLayout = ({
|
|||
</span>
|
||||
|
||||
<div className="header_search">
|
||||
<SearchField searchBy={search_by} placeholder={t("practical.search_here")} />
|
||||
<SearchField searchBy="" placeholder={t("practical.search_here")} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ const FormikFormModel: React.FC<FormikFormProps> = ({
|
|||
useEffect(() => {
|
||||
if (isOpen === "") {
|
||||
formik.setErrors({});
|
||||
}
|
||||
if (isOpen === "isSuccess") {
|
||||
formik.setErrors({});
|
||||
formik.resetForm();
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ const PageHeader = ({
|
|||
const { t } = useTranslation();
|
||||
|
||||
const PrevPath = getPrevPathRoute(location.pathname);
|
||||
const handelNavigate = () => {
|
||||
if (PrevPath === 0) {
|
||||
return;
|
||||
}
|
||||
navigate(deletePathSegments(location.pathname, PrevPath));
|
||||
};
|
||||
const handleNavigateToPage = (location: string) => {
|
||||
navigate(location);
|
||||
};
|
||||
|
|
@ -35,7 +41,7 @@ const PageHeader = ({
|
|||
return (
|
||||
<div className="page_header">
|
||||
<header className="d-flex justify-content-between">
|
||||
<span className="page_header_links" >
|
||||
<span className="page_header_links" onClick={handelNavigate}>
|
||||
<h1 className="page_title">{t(`PageTitle.${pageTitle}`)}</h1>
|
||||
<span className="page_links">
|
||||
<PageTitleComponent/>
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ import {
|
|||
import ActionButtons from "../../../Components/Table/ActionButtons";
|
||||
import ColumnsImage from "../../../Components/Columns/ColumnsImage";
|
||||
import { Grade } from "../../../types/Grade";
|
||||
import { CiImageOff } from "react-icons/ci";
|
||||
import { isValidImage } from "../../../utils/isValidImage";
|
||||
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
|
@ -61,11 +59,20 @@ export const useColumns = () => {
|
|||
align: "center",
|
||||
render: (_text: any, record: Grade) => {
|
||||
let str = record?.icon;
|
||||
|
||||
return <ColumnsImage src={str}/> ;
|
||||
return <ColumnsImage src={str} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
// canAddGrade ? (
|
||||
// <button
|
||||
// onClick={() => handel_open_model(ModalEnum?.GRADE_ADD)}
|
||||
// className="add_button"
|
||||
// >
|
||||
// {t("practical.add")} {t("models.grade")} <FaPlus />
|
||||
// </button>
|
||||
// ) : (
|
||||
// ""
|
||||
// ),
|
||||
|
||||
title: t("columns.procedure"),
|
||||
key: "actions",
|
||||
|
|
|
|||
33
src/Pages/Admin/QuestionBank/Model/AddModel.tsx
Normal file
33
src/Pages/Admin/QuestionBank/Model/AddModel.tsx
Normal 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;
|
||||
38
src/Pages/Admin/QuestionBank/Model/EditModel.tsx
Normal file
38
src/Pages/Admin/QuestionBank/Model/EditModel.tsx
Normal 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;
|
||||
|
|
@ -2,141 +2,15 @@ import React from "react";
|
|||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||
import { Col, Row } from "reactstrap";
|
||||
import { useFormikContext } from "formik";
|
||||
import { useGetAllGrade } from "../../../../api/grade";
|
||||
import { useValidationValidationParamState } from "../../../../Components/ValidationField/state/ValidationValidationParamState";
|
||||
import { useGetAllUnit } from "../../../../api/unit";
|
||||
import { useGetAllSubject } from "../../../../api/subject";
|
||||
import { useGetAllLesson } from "../../../../api/lesson";
|
||||
|
||||
const FilterForm = () => {
|
||||
|
||||
const { ValidationParamState } = useValidationValidationParamState();
|
||||
const {
|
||||
GradeName, GradeCurrentPage,
|
||||
SubjectName, SubjectCurrentPage,
|
||||
UnitName, UnitCurrentPage,
|
||||
LessonName, LessonCurrentPage
|
||||
|
||||
|
||||
} = ValidationParamState;
|
||||
|
||||
|
||||
|
||||
const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({
|
||||
name: GradeName,
|
||||
page: GradeCurrentPage
|
||||
});
|
||||
const GradeOption = Grade?.data ?? []
|
||||
const canChangeGradePage = !!Grade?.links?.next;
|
||||
const GradePage = Grade?.meta?.currentPage;
|
||||
|
||||
|
||||
/// subject_id
|
||||
const { data: Subject, isLoading: isLoadingSubject } = useGetAllSubject({
|
||||
name: SubjectName,
|
||||
page: SubjectCurrentPage
|
||||
});
|
||||
const SubjectOption = Subject?.data ?? []
|
||||
const canChangeSubjectPage = !!Subject?.links?.next;
|
||||
const SubjectPage = Subject?.meta?.currentPage;
|
||||
|
||||
/// unit_id
|
||||
const { data: Unit, isLoading: isLoadingUnit } = useGetAllUnit({
|
||||
name: UnitName,
|
||||
page: UnitCurrentPage
|
||||
});
|
||||
const UnitOption = Unit?.data ?? []
|
||||
const canChangeUnitPage = !!Unit?.links?.next;
|
||||
const UnitPage = Unit?.meta?.currentPage;
|
||||
|
||||
/// lessonsIds
|
||||
const { data: Lesson, isLoading: isLoadingLesson } = useGetAllLesson({
|
||||
name: LessonName,
|
||||
page: LessonCurrentPage
|
||||
});
|
||||
const LessonOption = Lesson?.data ?? []
|
||||
const canChangeLessonPage = !!Lesson?.links?.next;
|
||||
const LessonPage = Lesson?.meta?.currentPage;
|
||||
const formik = useFormikContext();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<Col>
|
||||
{/*
|
||||
grade_id
|
||||
*/}
|
||||
<ValidationField
|
||||
searchBy="GradeName"
|
||||
name="grade_id"
|
||||
label="grade"
|
||||
type="Search"
|
||||
option={GradeOption}
|
||||
isLoading={isLoadingGrade}
|
||||
canChangePage={canChangeGradePage}
|
||||
PageName={"GradeCurrentPage"}
|
||||
page={GradePage}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
{/*
|
||||
subject_id
|
||||
*/}
|
||||
|
||||
<ValidationField
|
||||
searchBy="SubjectName"
|
||||
name="subject_id"
|
||||
label="subject"
|
||||
type="Search"
|
||||
option={SubjectOption}
|
||||
isLoading={isLoadingSubject}
|
||||
canChangePage={canChangeSubjectPage}
|
||||
PageName={"SubjectCurrentPage"}
|
||||
page={SubjectPage}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
{/*
|
||||
unit_id
|
||||
*/}
|
||||
|
||||
<ValidationField
|
||||
searchBy="UnitName"
|
||||
name="unit_id"
|
||||
label="unit"
|
||||
type="Search"
|
||||
option={UnitOption}
|
||||
isLoading={isLoadingUnit}
|
||||
canChangePage={canChangeUnitPage}
|
||||
PageName={"UnitCurrentPage"}
|
||||
page={UnitPage}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
{/*
|
||||
lessonsIds
|
||||
*/}
|
||||
|
||||
<ValidationField
|
||||
searchBy="LessonName"
|
||||
name="lessonsIds"
|
||||
label="lesson"
|
||||
type="Search"
|
||||
option={LessonOption}
|
||||
isMulti
|
||||
isLoading={isLoadingLesson}
|
||||
canChangePage={canChangeLessonPage}
|
||||
PageName={"LessonCurrentPage"}
|
||||
page={LessonPage}
|
||||
|
||||
/>
|
||||
<ValidationField placeholder="name" label="name" name="name" />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
|
|
|||
19
src/Pages/Admin/QuestionBank/Model/formUtil.ts
Normal file
19
src/Pages/Admin/QuestionBank/Model/formUtil.ts
Normal 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"),
|
||||
});
|
||||
};
|
||||
|
|
@ -10,6 +10,8 @@ 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"),
|
||||
);
|
||||
|
|
@ -31,8 +33,10 @@ const TableHeader = () => {
|
|||
ModelAbility={ModalEnum?.QUESTION_BANK_ADD}
|
||||
canAdd={canAddQuestionBank}
|
||||
/>
|
||||
<FilterLayout width="700px" search_by="content" sub_children={<FilterForm />} filterTitle="table.QuestionBank" />
|
||||
<FilterLayout sub_children={<FilterForm />} filterTitle="table.QuestionBank" />
|
||||
<Table />
|
||||
<AddModalForm />
|
||||
<EditModalForm />
|
||||
<DeleteModalForm
|
||||
deleteMutation={deleteMutation}
|
||||
ModelEnum={ModalEnum?.QUESTION_BANK_DELETE}
|
||||
|
|
|
|||
|
|
@ -3,20 +3,13 @@ import React from "react";
|
|||
import DataTable from "../../../Layout/Dashboard/Table/DataTable";
|
||||
import { useGetAllQuestion } from "../../../api/Question";
|
||||
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
import { useFilterStateState } from "../../../zustand/Filter";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { filterState } = useFilterState();
|
||||
const { setFilter,Filter } = useFilterStateState();
|
||||
|
||||
console.log(filterState,"filterState");
|
||||
|
||||
const response = useGetAllQuestion({
|
||||
pagination: true,
|
||||
...filterState,
|
||||
content:Filter?.content
|
||||
|
||||
});
|
||||
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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";
|
||||
|
|
@ -7,6 +8,7 @@ import { ABILITIES_ENUM } from "../../../enums/abilities";
|
|||
import { useNavigate } from "react-router-dom";
|
||||
import { useModalState } from "../../../zustand/Modal";
|
||||
import {
|
||||
canAddQuestion,
|
||||
canDeleteQuestion,
|
||||
canEditQuestion,
|
||||
} from "../../../utils/hasAbilityFn";
|
||||
|
|
@ -17,18 +19,19 @@ export const useColumns = () => {
|
|||
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) => {
|
||||
console.log(record,"record");
|
||||
const lesson = record?.lessons?.[0] ;
|
||||
const unit = lesson?.unit;
|
||||
const subject = unit?.subject;
|
||||
const grade = subject?.grade;
|
||||
navigate(`/${ABILITIES_ENUM?.GRADE}/${grade?.id}/${ABILITIES_ENUM?.SUBJECT}/${subject?.id}/${ABILITIES_ENUM?.UNIT}/${unit?.id}/${ABILITIES_ENUM?.LESSON}/${lesson?.id}/${ABILITIES_ENUM?.QUESTION}/${record?.id}`);
|
||||
setObjectToEdit(record);
|
||||
navigate(`${ABILITIES_ENUM?.QUESTION}/${record?.id}`);
|
||||
};
|
||||
const [t] = useTranslation();
|
||||
|
||||
|
|
@ -48,24 +51,6 @@ export const useColumns = () => {
|
|||
render: (text, record) => record?.content,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: `${t("columns.course")}`,
|
||||
dataIndex: "lessons",
|
||||
key: "lessons",
|
||||
align: "center",
|
||||
render: (text, record) => {
|
||||
const lesson = record?.lessons?.[0] ;
|
||||
const unit = lesson?.unit;
|
||||
const subject = unit?.subject;
|
||||
const grade = subject?.grade;
|
||||
|
||||
return (
|
||||
<> {grade?.name} </>
|
||||
)
|
||||
},
|
||||
ellipsis: true,
|
||||
},
|
||||
|
||||
{
|
||||
title: `${t("columns.hint")}`,
|
||||
dataIndex: "hint",
|
||||
|
|
|
|||
|
|
@ -1,143 +1,27 @@
|
|||
import React from "react";
|
||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||
import { Col, Row } from "reactstrap";
|
||||
import { useFormikContext } from "formik";
|
||||
import { useGetAllGrade } from "../../../api/grade";
|
||||
import { useValidationValidationParamState } from "../../../Components/ValidationField/state/ValidationValidationParamState";
|
||||
import { useGetAllUnit } from "../../../api/unit";
|
||||
import { useGetAllSubject } from "../../../api/subject";
|
||||
import { useGetAllLesson } from "../../../api/lesson";
|
||||
import useFormatDataToSelect from "../../../utils/useFormatDataToSelect";
|
||||
|
||||
const FilterForm = () => {
|
||||
|
||||
const { ValidationParamState } = useValidationValidationParamState();
|
||||
const {
|
||||
GradeName, GradeCurrentPage,
|
||||
SubjectName, SubjectCurrentPage,
|
||||
UnitName, UnitCurrentPage,
|
||||
LessonName, LessonCurrentPage
|
||||
|
||||
|
||||
} = ValidationParamState;
|
||||
|
||||
|
||||
|
||||
const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({
|
||||
name: GradeName,
|
||||
page: GradeCurrentPage
|
||||
});
|
||||
const GradeOption = Grade?.data ?? []
|
||||
const canChangeGradePage = !!Grade?.links?.next;
|
||||
const GradePage = Grade?.meta?.currentPage;
|
||||
|
||||
|
||||
/// subject_id
|
||||
const { data: Subject, isLoading: isLoadingSubject } = useGetAllSubject({
|
||||
name: SubjectName,
|
||||
page: SubjectCurrentPage
|
||||
});
|
||||
const SubjectOption = Subject?.data ?? []
|
||||
const canChangeSubjectPage = !!Subject?.links?.next;
|
||||
const SubjectPage = Subject?.meta?.currentPage;
|
||||
|
||||
/// unit_id
|
||||
const { data: Unit, isLoading: isLoadingUnit } = useGetAllUnit({
|
||||
name: UnitName,
|
||||
page: UnitCurrentPage
|
||||
});
|
||||
const UnitOption = Unit?.data ?? []
|
||||
const canChangeUnitPage = !!Unit?.links?.next;
|
||||
const UnitPage = Unit?.meta?.currentPage;
|
||||
|
||||
/// lessonsIds
|
||||
const { data: Lesson, isLoading: isLoadingLesson } = useGetAllLesson({
|
||||
name: LessonName,
|
||||
page: LessonCurrentPage
|
||||
});
|
||||
const LessonOption = Lesson?.data ?? []
|
||||
const canChangeLessonPage = !!Lesson?.links?.next;
|
||||
const LessonPage = Lesson?.meta?.currentPage;
|
||||
|
||||
const yesNoArray = [
|
||||
{ id: "لا", name: "لا" },
|
||||
{ id: "نعم", name: "نعم" },
|
||||
];
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<Col>
|
||||
{/*
|
||||
grade_id
|
||||
*/}
|
||||
<ValidationField
|
||||
searchBy="GradeName"
|
||||
name="grade_id"
|
||||
label="grade"
|
||||
type="Search"
|
||||
option={GradeOption}
|
||||
isLoading={isLoadingGrade}
|
||||
canChangePage={canChangeGradePage}
|
||||
PageName={"GradeCurrentPage"}
|
||||
page={GradePage}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
{/*
|
||||
subject_id
|
||||
*/}
|
||||
|
||||
<ValidationField
|
||||
searchBy="SubjectName"
|
||||
name="subject_id"
|
||||
label="subject"
|
||||
type="Search"
|
||||
option={SubjectOption}
|
||||
isLoading={isLoadingSubject}
|
||||
canChangePage={canChangeSubjectPage}
|
||||
PageName={"SubjectCurrentPage"}
|
||||
page={SubjectPage}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
{/*
|
||||
unit_id
|
||||
*/}
|
||||
|
||||
<ValidationField
|
||||
searchBy="UnitName"
|
||||
name="unit_id"
|
||||
label="unit"
|
||||
type="Search"
|
||||
option={UnitOption}
|
||||
isLoading={isLoadingUnit}
|
||||
canChangePage={canChangeUnitPage}
|
||||
PageName={"UnitCurrentPage"}
|
||||
page={UnitPage}
|
||||
|
||||
/>
|
||||
|
||||
|
||||
{/*
|
||||
lessonsIds
|
||||
*/}
|
||||
|
||||
<ValidationField
|
||||
searchBy="LessonName"
|
||||
name="lessonsIds"
|
||||
label="lesson"
|
||||
type="Search"
|
||||
option={LessonOption}
|
||||
isMulti
|
||||
isLoading={isLoadingLesson}
|
||||
canChangePage={canChangeLessonPage}
|
||||
PageName={"LessonCurrentPage"}
|
||||
page={LessonPage}
|
||||
|
||||
/>
|
||||
<ValidationField
|
||||
placeholder="content"
|
||||
label="content"
|
||||
name="content"
|
||||
/>
|
||||
{/* <ValidationField type="Select" option={yesNoArray} placeholder="isBase" label="isBase" name="isBase" /> */}
|
||||
</Col>
|
||||
{/* <Col>
|
||||
<ValidationField type="Select" option={yesNoArray} placeholder="canAnswersBeShuffled" label="canAnswersBeShuffled" name="canAnswersBeShuffled" />
|
||||
</Col> */}
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -65,8 +65,6 @@ const TableHeader = () => {
|
|||
<FilterLayout
|
||||
sub_children={<FilterForm />}
|
||||
filterTitle={` ${unitName} (${LessonName}) `}
|
||||
search_by="content"
|
||||
haveFilter={false}
|
||||
/>
|
||||
<Table />
|
||||
</Suspense>
|
||||
|
|
|
|||
|
|
@ -5,18 +5,15 @@ import { useGetAllQuestion } from "../../../api/Question";
|
|||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../../enums/params";
|
||||
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
|
||||
import { useFilterStateState } from "../../../zustand/Filter";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const { lesson_id } = useParams<ParamsEnum>();
|
||||
const { filterState } = useFilterState();
|
||||
const { setFilter,Filter } = useFilterStateState();
|
||||
|
||||
const response = useGetAllQuestion({
|
||||
lessonsIds: [lesson_id],
|
||||
pagination: true,
|
||||
...filterState,
|
||||
content:Filter?.content
|
||||
});
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import {
|
|||
} from "../../../../utils/hasAbilityFn";
|
||||
import { ABILITIES_ENUM } from "../../../../enums/abilities";
|
||||
import { Subject } from "../../../../types/Subject";
|
||||
import { CiImageOff } from "react-icons/ci";
|
||||
|
||||
export const useColumns = () => {
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -55,7 +54,7 @@ export const useColumns = () => {
|
|||
align: "center",
|
||||
render: (row: Subject, record) => {
|
||||
let str = record.icon;
|
||||
return <ColumnsImage src={str}/> ;
|
||||
return <ColumnsImage src={str} />;
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -61,9 +61,6 @@
|
|||
border-radius: var(--border-radius);
|
||||
transition: 1s ease-in-out;
|
||||
animation: fadeInRight 1s ease-in-out;
|
||||
max-height: 90vh;
|
||||
overflow-y: scroll;
|
||||
@include Scrollbar;
|
||||
|
||||
> header {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -85,8 +85,3 @@
|
|||
font-size: 8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.model_sub_children{
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
|
@ -209,12 +209,12 @@
|
|||
}
|
||||
|
||||
.SelectTag {
|
||||
// padding-inline: 20px;
|
||||
padding-inline: 20px;
|
||||
}
|
||||
|
||||
.exercise_add {
|
||||
.add_new_button {
|
||||
// padding-inline: 20px !important;
|
||||
padding-inline: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,12 +229,12 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// >{
|
||||
// flex: 1;
|
||||
// min-height: auto;
|
||||
// min-width: 30px;
|
||||
>{
|
||||
flex: 1;
|
||||
min-height: auto;
|
||||
min-width: 30px;
|
||||
|
||||
// }
|
||||
}
|
||||
.ant-btn{
|
||||
min-height: 30px !important;
|
||||
max-height: 30px !important;
|
||||
|
|
|
|||
|
|
@ -193,7 +193,6 @@
|
|||
"normal_question": " تمرين عادي",
|
||||
"hint":"شرح ",
|
||||
"tags":"كلمات مفتاحية",
|
||||
"course":" الصفوف",
|
||||
"student_full_name":"اسم الطالب الثلاثي",
|
||||
"amount_paid":"المبلغ المدفوع",
|
||||
"sale_date":"تاريخ البيع",
|
||||
|
|
@ -445,10 +444,6 @@
|
|||
"city": "المحافظة",
|
||||
"personal_image": "صورة شخصية",
|
||||
"id_image": "صورة الهوية",
|
||||
"grade":"الصفوف",
|
||||
"subject":"المادة",
|
||||
"unit":"الوحدة",
|
||||
"lesson":"الدرس",
|
||||
"date_of_receipt":"تاريخ الاستلام",
|
||||
"amount_value":"قيمة المبلغ"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -315,8 +315,7 @@ export interface Question {
|
|||
question_options_count?: any;
|
||||
answers: QuestionOption[];
|
||||
hint?: string;
|
||||
tags: tags[];
|
||||
lessons:any
|
||||
tags: tags[]; // Assuming tags are strings, adjust as per actual data type
|
||||
}
|
||||
|
||||
export type report = {
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
export const isValidImage = (url: string): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
const img = new Image();
|
||||
img.src = url;
|
||||
|
||||
img.onload = () => resolve(true); // Image loaded successfully
|
||||
img.onerror = () => resolve(false); // Error loading image
|
||||
});
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user