From 5e0e0afd013bbc87186a03ea1c7975c9c60e768c Mon Sep 17 00:00:00 2001 From: karimaldeen Date: Sun, 18 Aug 2024 15:25:56 +0300 Subject: [PATCH] end package --- .../ValidationField/Ui/KarimSpinner.tsx | 24 -- .../ValidationField/Ui/SearchBar.scss | 37 --- .../ValidationField/Ui/SearchBar.tsx | 45 ---- .../ValidationField/ValidationField.tsx | 8 +- .../ValidationField/View/CheckboxField.tsx | 18 +- .../ValidationField/View/DataRange.tsx | 35 +-- src/Components/ValidationField/View/Date.tsx | 41 ++- .../ValidationField/View/Default.tsx | 51 ++-- .../ValidationField/View/DropFile.tsx.tsx | 6 +- src/Components/ValidationField/View/File.tsx | 21 +- .../ValidationField/View/LocalSearch.tsx | 55 ++-- .../ValidationField/View/MaltyFile.tsx | 54 ++-- .../ValidationField/View/NumberField.tsx | 70 ------ .../ValidationField/View/NumberFormate.tsx | 46 ++-- .../ValidationField/View/SearchField.tsx | 160 ++++++++---- .../ValidationField/View/SelectField.tsx | 59 ++--- .../ValidationField/View/TextAreaField.tsx | 15 +- .../ValidationField/View/TextField.tsx | 36 +-- src/Components/ValidationField/View/Time.tsx | 36 ++- .../components/ValidationFieldContainer.tsx | 24 ++ .../components/ValidationFieldLabel.tsx | 39 +++ src/Components/ValidationField/index.tsx | 2 - .../state/ValidationValidationParamState.ts | 36 +++ .../utils/ValidationField.scss | 31 +-- .../ValidationField/utils/getNestedValue.ts | 7 - .../utils/translatedOptions.ts | 5 +- src/Components/ValidationField/utils/types.ts | 236 +++++------------- src/Hooks/useDebounce.ts | 25 ++ .../Package/Field/ConfigurationField.tsx | 9 + src/Pages/Package/Field/FieldGroup.tsx | 96 +++++++ src/Pages/Package/Model/AddModel.tsx | 72 +++--- src/Pages/Package/Model/EditModel.tsx | 73 ++++-- src/Pages/Package/Model/ModelForm.tsx | 225 ++++++++++++++++- src/Pages/Package/Model/formUtil.ts | 20 +- src/Pages/Package/Page.tsx | 2 - src/Pages/Package/useTableColumns.tsx | 5 +- src/Routes.tsx | 12 +- src/enums/params.ts | 1 + src/translate/ar.json | 23 +- src/types/Package.ts | 30 +++ src/utils/arrayToObject.ts | 15 ++ src/utils/objectToArray.ts | 14 ++ 42 files changed, 1019 insertions(+), 800 deletions(-) delete mode 100644 src/Components/ValidationField/Ui/KarimSpinner.tsx delete mode 100644 src/Components/ValidationField/Ui/SearchBar.scss delete mode 100644 src/Components/ValidationField/Ui/SearchBar.tsx delete mode 100644 src/Components/ValidationField/View/NumberField.tsx create mode 100644 src/Components/ValidationField/components/ValidationFieldContainer.tsx create mode 100644 src/Components/ValidationField/components/ValidationFieldLabel.tsx create mode 100644 src/Components/ValidationField/state/ValidationValidationParamState.ts delete mode 100644 src/Components/ValidationField/utils/getNestedValue.ts create mode 100644 src/Hooks/useDebounce.ts create mode 100644 src/Pages/Package/Field/ConfigurationField.tsx create mode 100644 src/Pages/Package/Field/FieldGroup.tsx create mode 100644 src/types/Package.ts create mode 100644 src/utils/arrayToObject.ts create mode 100644 src/utils/objectToArray.ts diff --git a/src/Components/ValidationField/Ui/KarimSpinner.tsx b/src/Components/ValidationField/Ui/KarimSpinner.tsx deleted file mode 100644 index 53a29d4..0000000 --- a/src/Components/ValidationField/Ui/KarimSpinner.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; -import { Spin } from "antd"; - -interface Props { - loading: boolean; - children: React.ReactNode; - className?: string; -} - -const KarimSpinner: React.FC = ({ loading, className, children }) => { - return ( -
- {loading ? ( -
- -
- ) : ( - children - )} -
- ); -}; - -export default KarimSpinner; diff --git a/src/Components/ValidationField/Ui/SearchBar.scss b/src/Components/ValidationField/Ui/SearchBar.scss deleted file mode 100644 index 9dc4900..0000000 --- a/src/Components/ValidationField/Ui/SearchBar.scss +++ /dev/null @@ -1,37 +0,0 @@ -.SearchBar { - // margin-top: 20px; - .group { - display: flex; - align-items: center; - position: relative; - max-width: 350px; - width: 350px; - } - - .input { - width: 100%; - height: 40px; - padding: 0 1rem; - padding-left: 2.5rem; - border-radius: 8px; - outline: none; - font-weight: 500; - background: var(--bg); - color: var(--text); - border: none; - box-shadow: 2px 2px 7px 0 var(--bg); - } - - .input::placeholder { - color: var(--subtext); - opacity: 0.4; - } - - .icon { - position: absolute; - left: 1rem; - fill: var(--subtext); - width: 1rem; - height: 1rem; - } -} diff --git a/src/Components/ValidationField/Ui/SearchBar.tsx b/src/Components/ValidationField/Ui/SearchBar.tsx deleted file mode 100644 index 46d2566..0000000 --- a/src/Components/ValidationField/Ui/SearchBar.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useState } from "react"; -import "./SearchBar.scss"; -import { useNavigate, useSearchParams } from "react-router-dom"; -const SearchBar = () => { - const [searchQuery, setSearchQuery] = useState(""); - const [searchParams] = useSearchParams(); - const navigate = useNavigate(); - - const handleChange = (event: any) => { - const { value } = event.target; - setSearchQuery(value); - updateUrlParams(value); - }; - - const updateUrlParams = (value: any) => { - navigate(`?search=${value}`, { replace: true }); - }; - - return ( -
-
- - -
-
- ); -}; - -export default SearchBar; diff --git a/src/Components/ValidationField/ValidationField.tsx b/src/Components/ValidationField/ValidationField.tsx index c02aa07..3b2f503 100644 --- a/src/Components/ValidationField/ValidationField.tsx +++ b/src/Components/ValidationField/ValidationField.tsx @@ -6,17 +6,16 @@ import { File, DataRange, SelectField, - Default, CheckboxField, MaltyFile, SearchField, TextField, DropFile, + Default, } from "./View"; import { ValidationFieldProps, ValidationFieldType } from "./utils/types"; import LocalSearchField from "./View/LocalSearch"; import NumberFormate from "./View/NumberFormate"; -import NumberField from "./View/NumberField"; const components: { [key: string]: React.FC } = { Select: SelectField, @@ -31,12 +30,11 @@ const components: { [key: string]: React.FC } = { MaltyFile: MaltyFile, Checkbox: CheckboxField, NumberFormate: NumberFormate, - Number: NumberField, }; const ValidationField: React.FC = React.memo( - ({ type, ...otherProps }: any) => { - const Component = components[type as ValidationFieldType]; + ({ type = "text", ...otherProps }) => { + const Component = components[type ?? ("text" as ValidationFieldType)]; if (!Component) { return ; diff --git a/src/Components/ValidationField/View/CheckboxField.tsx b/src/Components/ValidationField/View/CheckboxField.tsx index c54e880..c29116f 100644 --- a/src/Components/ValidationField/View/CheckboxField.tsx +++ b/src/Components/ValidationField/View/CheckboxField.tsx @@ -1,7 +1,7 @@ import React from "react"; import useFormField from "../../../Hooks/useFormField"; -import { Checkbox, Form } from "antd"; -import { getNestedValue } from "../utils/getNestedValue"; +import { Checkbox } from "antd"; +import { ValidationFieldContainer } from "../components/ValidationFieldContainer"; const CheckboxField = ({ name, label, @@ -13,25 +13,21 @@ const CheckboxField = ({ }: any) => { const { t, formik, isError, errorMsg } = useFormField(name, props); const CheckboxhandleChange = (value: any) => { - formik.setFieldValue(name, value?.target?.checked ? 1 : 0); + formik.setFieldValue(name, value?.target?.checked); }; return ( -
- +
+ {t(`input.${label ? label : name}`)} - +
); }; diff --git a/src/Components/ValidationField/View/DataRange.tsx b/src/Components/ValidationField/View/DataRange.tsx index 85dd3a3..ce8b585 100644 --- a/src/Components/ValidationField/View/DataRange.tsx +++ b/src/Components/ValidationField/View/DataRange.tsx @@ -3,6 +3,8 @@ import { Form, DatePicker } from "antd"; import React from "react"; import useFormField from "../../../Hooks/useFormField"; import { MdOutlineEdit } from "react-icons/md"; +import { ValidationFieldLabel } from "../components/ValidationFieldLabel"; +import { ValidationFieldContainer } from "../components/ValidationFieldContainer"; const { RangePicker } = DatePicker; @@ -24,28 +26,16 @@ const DataRange = ({ }; return (
- {no_label ? ( - - ) : label_icon ? ( -
- - -
- ) : ( - - )} + - + - +
); }; diff --git a/src/Components/ValidationField/View/Date.tsx b/src/Components/ValidationField/View/Date.tsx index a14663d..036fb71 100644 --- a/src/Components/ValidationField/View/Date.tsx +++ b/src/Components/ValidationField/View/Date.tsx @@ -3,6 +3,9 @@ import React from "react"; import useFormField from "../../../Hooks/useFormField"; import { MdOutlineEdit } from "react-icons/md"; import dayjs from "dayjs"; +import { DateEnum } from "../../../enums/Date"; +import { ValidationFieldLabel } from "../components/ValidationFieldLabel"; +import { ValidationFieldContainer } from "../components/ValidationFieldContainer"; const Date = ({ name, @@ -21,34 +24,21 @@ const Date = ({ const FormikValue = formik.values[name]; const onCalendarChange = (value: any) => { formik.setFieldValue(name, value); - // console.log(value,"value "); }; - const Formater = "YYYY/MM/DD"; + const Formatter = [DateEnum?.FORMATE, DateEnum?.FORMATE2]; return (
- {no_label ? ( - - ) : label_icon ? ( -
- - -
- ) : ( - - )} + - + {/* */} - +
); }; diff --git a/src/Components/ValidationField/View/Default.tsx b/src/Components/ValidationField/View/Default.tsx index 1893127..5a0db12 100644 --- a/src/Components/ValidationField/View/Default.tsx +++ b/src/Components/ValidationField/View/Default.tsx @@ -1,9 +1,10 @@ -import { Form, Input } from "antd"; +import { Input } from "antd"; import React from "react"; import useFormField from "../../../Hooks/useFormField"; -import { MdOutlineEdit } from "react-icons/md"; import { Field } from "formik"; -import { ValidationFieldPropsInput } from "../utils/types"; +import { ValidationFieldLabel } from "../components/ValidationFieldLabel"; +import { ValidationFieldContainer } from "../components/ValidationFieldContainer"; +import { FieldProps } from "../utils/types"; const Default = ({ name, @@ -14,52 +15,34 @@ const Default = ({ type, no_label, label_icon, - label2, ...props -}: ValidationFieldPropsInput) => { +}: any) => { const { errorMsg, isError, t } = useFormField(name, props); return (
- {label2 ? ( - - ) : no_label ? ( - - ) : label_icon ? ( -
- - -
- ) : ( - - )} + - + - +
); }; diff --git a/src/Components/ValidationField/View/DropFile.tsx.tsx b/src/Components/ValidationField/View/DropFile.tsx.tsx index 2f45684..b9e870f 100644 --- a/src/Components/ValidationField/View/DropFile.tsx.tsx +++ b/src/Components/ValidationField/View/DropFile.tsx.tsx @@ -3,7 +3,6 @@ import { LoadingOutlined, PlusOutlined } from "@ant-design/icons"; import { message, Upload } from "antd"; import type { GetProp, UploadProps } from "antd"; import useFormField from "../../../Hooks/useFormField"; -import { ImageBaseURL } from "../../../api/config"; type FileType = Parameters>[0]; @@ -12,7 +11,7 @@ const DropFile = ({ label, onChange, isDisabled, - placholder, + placeholder, className, props, no_label, @@ -23,7 +22,7 @@ const DropFile = ({ const FormikValue = typeof FormikName === "string" - ? ImageBaseURL + FormikName + ? FormikName : FormikName instanceof File ? URL.createObjectURL(FormikName) : ""; @@ -71,6 +70,7 @@ const DropFile = ({ showUploadList={false} customRequest={customRequest} onChange={onChange || handleChange} + id={name} > {imageUrl ? ( { @@ -16,29 +16,29 @@ const File = ({ let imageUrl = formik?.values?.[name] ?? null; const fileList: UploadFile[] = useMemo(() => { - if (!imageUrl) return []; + if (!imageUrl) { + return []; + } return [ typeof imageUrl === "string" ? { uid: "-1", - name: "uploaded-image", + name: "", status: "done", url: imageUrl, thumbUrl: imageUrl, } : { uid: imageUrl.uid || "-1", - name: imageUrl.name || "uploaded-image", + name: imageUrl.name || "", status: "done", originFileObj: imageUrl, }, ]; }, [imageUrl]); - // console.log(1); const FilehandleChange = (value: any) => { - // console.log(value,"filevalue"); if (value.fileList.length === 0) { formik.setFieldValue(name, null); } else { @@ -62,12 +62,15 @@ const File = ({ onChange={onChange || FilehandleChange} customRequest={customRequest} className={` w-100`} + id={name} >
{isError ? "required" : ""}
{errorMsg} @@ -76,4 +79,4 @@ const File = ({ ); }; -export default File; +export default React.memo(File); diff --git a/src/Components/ValidationField/View/LocalSearch.tsx b/src/Components/ValidationField/View/LocalSearch.tsx index 03b3efc..04c40cd 100644 --- a/src/Components/ValidationField/View/LocalSearch.tsx +++ b/src/Components/ValidationField/View/LocalSearch.tsx @@ -1,8 +1,9 @@ -import { Form, Select } from "antd"; +import { Select } from "antd"; import React, { useState } from "react"; import useFormField from "../../../Hooks/useFormField"; -import { MdOutlineEdit } from "react-icons/md"; import { translateOptions } from "../utils/translatedOptions"; +import { ValidationFieldLabel } from "../components/ValidationFieldLabel"; +import { ValidationFieldContainer } from "../components/ValidationFieldContainer"; const LocalSelectField = ({ name, @@ -13,9 +14,9 @@ const LocalSelectField = ({ isMulti, onChange, className, - props, no_label, label_icon, + ...props }: any) => { const { errorMsg, isError, t, formik } = useFormField(name, props); @@ -29,13 +30,6 @@ const LocalSelectField = ({ option?.label?.toString().toLowerCase().includes(input.toLowerCase()) || option?.value?.toString().toLowerCase().includes(input.toLowerCase()); - const SelectableChange = (value: { - value: string; - label: React.ReactNode; - }) => { - formik.setFieldValue(name, value); - }; - const handleSelectChange = (value: any) => { formik.setFieldValue(name, value); if (onChange) onChange(value); @@ -47,35 +41,21 @@ const LocalSelectField = ({ return (
- {no_label ? ( - - ) : label_icon ? ( -
- - -
- ) : ( - - )} - + + : "لا يوجد"} - onSearch={SearchHandleChange} + optionFilterProp="name" + notFoundContent={isLoading ? : t("validation.undefined")} + onSearch={handleChange} + onBlur={handleBlur} + id={name} + onPopupScroll={handleScroll} + fieldNames={{ label: "name", value: "id" }} + {...props} /> - +
); }; diff --git a/src/Components/ValidationField/View/SelectField.tsx b/src/Components/ValidationField/View/SelectField.tsx index 1470bca..6ece99f 100644 --- a/src/Components/ValidationField/View/SelectField.tsx +++ b/src/Components/ValidationField/View/SelectField.tsx @@ -1,8 +1,10 @@ -import { Form, Select, Spin } from "antd"; +import { Select } from "antd"; import React from "react"; import useFormField from "../../../Hooks/useFormField"; -import { MdOutlineEdit } from "react-icons/md"; import { translateOptions } from "../utils/translatedOptions"; +import { ValidationFieldLabel } from "../components/ValidationFieldLabel"; +import { ValidationFieldContainer } from "../components/ValidationFieldContainer"; +import { SelectFieldProps } from "../utils/types"; const SelectField = ({ name, @@ -13,10 +15,11 @@ const SelectField = ({ isMulti, onChange, className, - props, no_label, label_icon, -}: any) => { + isLoading, + ...props +}: SelectFieldProps) => { const { errorMsg, isError, t, formik } = useFormField(name, props); const SelectableChange = (value: { value: string; @@ -24,47 +27,35 @@ const SelectField = ({ }) => { formik.setFieldValue(name, value); }; - // console.log(name,"Select"); - + const options = translateOptions(option, t); return (
- {no_label ? ( - - ) : label_icon ? ( -
- - -
- ) : ( - - )} + - + handleChangeKey(e, index)} + value={group.key} + size="large" + style={{ width: "100%" }} + allowClear + disabled={only_value} + /> + handleChangeValue(e, index)} + value={group.value} + size="large" + style={{ width: "100%" }} + allowClear + + /> +
+ ))} + {!isStatic && +
+ + +
+ } + + + ); +}; + +export default FieldGroup; diff --git a/src/Pages/Package/Model/AddModel.tsx b/src/Pages/Package/Model/AddModel.tsx index ce944d8..8c347ee 100644 --- a/src/Pages/Package/Model/AddModel.tsx +++ b/src/Pages/Package/Model/AddModel.tsx @@ -6,52 +6,60 @@ import { QueryStatusEnum } from "../../../enums/QueryStatus"; import ModelForm from "./ModelForm"; import { useAddPackage } from "../../../api/package"; import FormikForm from "../../../Layout/Dashboard/FormikForm"; +import { Spin } from "antd"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import useSetPageTitle from "../../../Hooks/useSetPageTitle"; +import { PackageInitialValues } from "../../../types/Package"; +import { arrayToObject } from "../../../utils/arrayToObject"; const AddModel: React.FC = () => { - const { mutate, status } = useAddPackage(); + const { mutate, status ,isLoading} = useAddPackage(); + const [t] = useTranslation(); + const navigate = useNavigate() + const handleSubmit = (values: PackageInitialValues) => { + const DataToSend = JSON.parse(JSON.stringify(values) ); + console.log(DataToSend,"DataToSend"); + console.log(values?.configuration); + + const configuration = JSON.stringify(arrayToObject(values?.configuration )) ; + console.log(configuration); - const handleSubmit = (values: any) => { mutate({ ...values, }); }; + + useSetPageTitle(t(`page_header.package`)); + return ( - <> - {/* - - moaz - */} - casascaas +
+ > + +
+ {t("header.add_new_package")} +
+
- + +
+ */} -
-
+ {isLoading && ( + + + + )} + +
+ - +
); }; diff --git a/src/Pages/Package/Model/EditModel.tsx b/src/Pages/Package/Model/EditModel.tsx index 7288f2b..7bb6ca1 100644 --- a/src/Pages/Package/Model/EditModel.tsx +++ b/src/Pages/Package/Model/EditModel.tsx @@ -1,35 +1,72 @@ 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 FormikForm from "../../../Layout/Dashboard/FormikForm"; +import { Spin } from "antd"; +import { useTranslation } from "react-i18next"; +import { useNavigate, useParams } from "react-router-dom"; +import useSetPageTitle from "../../../Hooks/useSetPageTitle"; +import { PackageInitialValues } from "../../../types/Package"; +import { arrayToObject } from "../../../utils/arrayToObject"; +import { useGetAllPackage, useUpdatePackage } from "../../../api/package"; +import { ParamsEnum } from "../../../enums/params"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; -import { useUpdatePackage } from "../../../api/package"; +import SpinContainer from "../../../Components/Layout/SpinContainer"; const EditModel: React.FC = () => { - const { mutate, status } = useUpdatePackage(); - const { objectToEdit } = useObjectToEdit((state) => state); + const { mutate, status ,isLoading} = useUpdatePackage(); + const [t] = useTranslation(); + const {package_id} = useParams(); + const {objectToEdit} = useObjectToEdit(); + + const {data,isLoading:isLoadingData} = useGetAllPackage({show:package_id}) + console.log(data?.data,"data"); + + const handleSubmit = (values: PackageInitialValues) => { + const DataToSend = JSON.parse(JSON.stringify(values) ); + console.log(DataToSend,"DataToSend"); + console.log(values?.configuration); + + const configuration = JSON.stringify(arrayToObject(values?.configuration )) ; + console.log(configuration); - const handleSubmit = (values: any) => { mutate({ ...values, }); }; + + useSetPageTitle(t(`page_header.package`)); + if(isLoadingData){ + return + } return ( - <> - + + initialValues={getInitialValues(data?.data)} + validationSchema={getValidationSchema} + > + +
+ {t("header.edit_package")} +
+ +
- - +
+ +
+
+
+ ); }; diff --git a/src/Pages/Package/Model/ModelForm.tsx b/src/Pages/Package/Model/ModelForm.tsx index ab45c44..861020c 100644 --- a/src/Pages/Package/Model/ModelForm.tsx +++ b/src/Pages/Package/Model/ModelForm.tsx @@ -1,15 +1,236 @@ import { Col, Row } from "reactstrap"; import ValidationField from "../../../Components/ValidationField/ValidationField"; +import { useGetAllGrade } from "../../../api/grade"; +import { useGetAllSubject } from "../../../api/subject"; +import { useGetAllUnit } from "../../../api/unit"; +import { useGetAllCurriculum } from "../../../api/curriculum"; +import { useGetAllLesson } from "../../../api/lesson"; +import { useFormikContext } from "formik"; +import { PackageInitialValues } from "../../../types/Package"; +import { useValidationValidationParamState } from "../../../Components/ValidationField/state/ValidationValidationParamState"; +import { useEffect } from "react"; +import ConfigurationField from "../Field/ConfigurationField"; +import FieldGroup from "../Field/FieldGroup"; const Form = () => { + const { values, setFieldValue } = useFormikContext(); + + const { ValidationParamState } = useValidationValidationParamState(); + const { + GradeName, GradeCurrentPage, + SubjectName, SubjectCurrentPage, + UnitName, UnitCurrentPage, + CurriculumName, CurriculumCurrentPage, + LessonName, LessonCurrentPage + + + } = ValidationParamState; + + const { curriculums_ids, grade_id, subjects_ids, units_ids, lessons_ids } = values; + + + + + /// grade_id + const GradeDisabled = !!grade_id; + const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({ + name: GradeName, + page: GradeCurrentPage + }); + const GradeOption = Grade?.data ?? [] + const canChangeGradePage = !!Grade?.links?.next; + const GradePage = Grade?.meta?.currentPage; + + + /// subjects_ids + const SubjectDisabled = !!subjects_ids && subjects_ids?.length > 0; + const { data: Subject, isLoading: isLoadingSubject } = useGetAllSubject({ + grade_id: grade_id, + name: SubjectName, + page: SubjectCurrentPage + }, { enabled: GradeDisabled }); + const SubjectOption = Subject?.data ?? [] + const canChangeSubjectPage = !!Subject?.links?.next; + const SubjectPage = Subject?.meta?.currentPage; + + /// units_ids + const UnitDisabled = !!units_ids && units_ids?.length > 0; + const { data: Unit, isLoading: isLoadingUnit } = useGetAllUnit({ + subjects_ids: subjects_ids, + name: UnitName, + page: UnitCurrentPage + }, { enabled: SubjectDisabled }); + const UnitOption = Unit?.data ?? [] + const canChangeUnitPage = !!Unit?.links?.next; + const UnitPage = Unit?.meta?.currentPage; + + /// curriculums_ids + const CurriculumDisabled = !!curriculums_ids && curriculums_ids?.length > 0; + const { data: Curriculum, isLoading: isLoadingCurriculum } = useGetAllCurriculum({ + units_ids: units_ids, + name: CurriculumName, + page: CurriculumCurrentPage + }, { enabled: UnitDisabled }); + const CurriculumOption = Curriculum?.data ?? [] + const canChangeCurriculumPage = !!Curriculum?.links?.next; + const CurriculumPage = Curriculum?.meta?.currentPage; + + /// lessons_ids + const { data: Lesson, isLoading: isLoadingLesson } = useGetAllLesson({ + curriculums_ids: curriculums_ids, + name: LessonName, + page: LessonCurrentPage + }, { enabled: CurriculumDisabled }); + const LessonOption = Lesson?.data ?? [] + const canChangeLessonPage = !!Lesson?.links?.next; + const LessonPage = Lesson?.meta?.currentPage; + + + + useEffect(() => { + const GradeChildren = (subjects_ids && subjects_ids?.length > 0 || units_ids && units_ids?.length > 0 || curriculums_ids && curriculums_ids?.length > 0 || lessons_ids && lessons_ids?.length > 0); + + if (!grade_id && GradeChildren) { + setFieldValue("subjects_ids", []); + setFieldValue("units_ids", []); + setFieldValue("curriculums_ids", []); + setFieldValue("lessons_ids", []); + return; + } + console.log(1); + + const SubjectChildren = (units_ids && units_ids?.length > 0 || curriculums_ids && curriculums_ids?.length > 0 || lessons_ids && lessons_ids?.length > 0) + console.log( subjects_ids && subjects_ids?.length < 1 && SubjectChildren); + + if (subjects_ids && subjects_ids?.length < 1 && SubjectChildren) { + console.log(1); + + setFieldValue("units_ids", []); + setFieldValue("curriculums_ids", []); + setFieldValue("lessons_ids", []); + return; + } + const UnitChildren = (curriculums_ids && curriculums_ids?.length > 0 || lessons_ids && lessons_ids?.length > 0) + if (units_ids && units_ids?.length < 1 && UnitChildren) { + setFieldValue("curriculums_ids", []); + setFieldValue("lessons_ids", []); + return; + } + const CurriculumChildren = (lessons_ids && lessons_ids?.length > 0) + if (curriculums_ids && curriculums_ids?.length < 1 && CurriculumChildren) { + setFieldValue("lessons_ids", []); + return; + } + }, [grade_id, subjects_ids, units_ids, curriculums_ids]) + + return ( - - + + + + + + {/* + grade_id + */} + + + {/* + subjects_ids + */} + + + + + {/* + units_ids + */} + + + + + {/* + curriculums_ids + */} + + + + + + {/* + lessons_ids + */} + + + ); }; diff --git a/src/Pages/Package/Model/formUtil.ts b/src/Pages/Package/Model/formUtil.ts index 7210eb8..253e265 100644 --- a/src/Pages/Package/Model/formUtil.ts +++ b/src/Pages/Package/Model/formUtil.ts @@ -1,16 +1,32 @@ import * as Yup from "yup"; -export const getInitialValues = (objectToEdit: any): any => { +import { Package, PackageInitialValues } from "../../../types/Package"; +import { arrayToObject } from "../../../utils/arrayToObject"; +import { objectToArray } from "../../../utils/objectToArray"; +export const getInitialValues = (objectToEdit: Partial): PackageInitialValues => { + console.log(objectToEdit,"objectToEdit"); + + const configuration = Array.isArray(objectToEdit?.configuration) ? objectToEdit?.configuration : objectToArray(objectToEdit?.configuration) return { id: objectToEdit?.id ?? null, name: objectToEdit?.name ?? null, price: objectToEdit?.price ?? null, grade_id: objectToEdit?.grade_id ?? null, - + curriculums_ids: objectToEdit?.curriculums_ids ?? [], + lessons_ids: objectToEdit?.lessons_ids ?? [], + subjects_ids: objectToEdit?.subjects_ids ?? [], + units_ids: objectToEdit?.units_ids ?? [], + configuration: configuration ?? [{key:"",value:""}], }; }; export const getValidationSchema = () => { return Yup.object().shape({ name: Yup.string().required("validation.required"), + price: Yup.number().required("validation.required").typeError("validation.Must_be_a_number"), + grade_id: Yup.string().required("validation.required"), + curriculums_ids: Yup.array().of(Yup.number().required()).min(1,"validation.must_have_on_item").required("validation.required"), + lessons_ids: Yup.array().of(Yup.number().required()).min(1,"validation.must_have_on_item").required("validation.required"), + subjects_ids: Yup.array().of(Yup.number().required()).min(1,"validation.must_have_on_item").required("validation.required"), + units_ids: Yup.array().of(Yup.number().required()).min(1,"validation.must_have_on_item").required("validation.required"), }); }; diff --git a/src/Pages/Package/Page.tsx b/src/Pages/Package/Page.tsx index 0636e83..3fcf647 100644 --- a/src/Pages/Package/Page.tsx +++ b/src/Pages/Package/Page.tsx @@ -52,8 +52,6 @@ const TableHeader = () => { deleteMutation={deleteMutation} ModelEnum={ModalEnum?.Package_DELETE} /> - {/* */} - ); diff --git a/src/Pages/Package/useTableColumns.tsx b/src/Pages/Package/useTableColumns.tsx index 8141e48..bfda9f2 100644 --- a/src/Pages/Package/useTableColumns.tsx +++ b/src/Pages/Package/useTableColumns.tsx @@ -5,12 +5,13 @@ import { useModalState } from "../../zustand/Modal"; import { useTranslation } from "react-i18next"; import { canDeletePackage,canEditPackage } from "../../utils/hasAbilityFn"; import ActionButtons from "../../Components/Table/ActionButtons"; +import { useNavigate } from "react-router-dom"; export const useColumns = () => { const [t] = useTranslation(); const { setIsOpen } = useModalState((state) => state); - + const navigate = useNavigate() const { setObjectToEdit } = useObjectToEdit((state) => state); const handelDelete = (record: any) => { setObjectToEdit(record); @@ -19,6 +20,8 @@ export const useColumns = () => { const handleEdit = (record: any) => { setObjectToEdit(record); setIsOpen(ModalEnum?.Package_EDIT); + navigate(`${record?.id}`) + }; const columns: TableColumnsType = [ diff --git a/src/Routes.tsx b/src/Routes.tsx index 558e10a..89c40bc 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -1,5 +1,5 @@ import { TCrudRoute, TMenuItem } from "./types/App"; -import { FaHome, FaMoneyBill } from "react-icons/fa"; +import { FaHome, FaKey, FaMoneyBill, FaUserGraduate } from "react-icons/fa"; import { LuPackage } from "react-icons/lu"; import React from "react"; const Dummy = React.lazy(() => import("./Pages/Home/Dummy")); @@ -38,7 +38,7 @@ export const menuItems: TMenuItem[] = [ { header: "page_header.grade", element: , - icon: , + icon: , text: "sidebar.grade", path: `/${ABILITIES_ENUM?.GRADE}`, abilities: ABILITIES_ENUM?.GRADE, @@ -68,7 +68,7 @@ export const menuItems: TMenuItem[] = [ { header: "page_header.tags", element: , - icon: , + icon: , text: "sidebar.tags", path: `/${ABILITIES_ENUM?.TAG}`, abilities: ABILITIES_ENUM?.TAG, @@ -143,15 +143,15 @@ export const CrudRoute: TCrudRoute[] = [ path: `/${ABILITIES_ENUM?.Package}/add`, abilities: ABILITIES_ENUM?.Package, abilities_value: ABILITIES_VALUES_ENUM.INDEX, - prevPath: 0, + prevPath: 1, }, { header: "page_header.edit_package", element: , - path: `/${ABILITIES_ENUM?.Package}/add`, + path: `/${ABILITIES_ENUM?.Package}/:${ParamsEnum?.PACKAGE_ID}`, abilities: ABILITIES_ENUM?.Package, abilities_value: ABILITIES_VALUES_ENUM.INDEX, - prevPath: 0, + prevPath: 1, }, ]; diff --git a/src/enums/params.ts b/src/enums/params.ts index 0214cda..3ec3006 100644 --- a/src/enums/params.ts +++ b/src/enums/params.ts @@ -10,5 +10,6 @@ export enum ParamsEnum { UNIT_ID = "unit_id", LESSON_ID = "lesson_id", QUESTION_ID = "question_id", + PACKAGE_ID = "package_id", CHILDREN_QUESTION_ID = "children_question_id", } diff --git a/src/translate/ar.json b/src/translate/ar.json index d400f9c..cede066 100644 --- a/src/translate/ar.json +++ b/src/translate/ar.json @@ -46,7 +46,8 @@ "Due_date_must_be_before_assigning_date": "يجب أن يكون تاريخ الاستحقاق بعد تاريخ التعيين", "grade_to_pass_must_be_less_than_max_grade": "يجب أن تكون درجة النجاح أقل من الحد الأقصى للدرجة", "max_mark_must_be_greater_than_min_mark_to_pass": "يجب ان تكون اكبر من علامة النجاح", - "Sorry, the question must have at least one option": "عذرًا، يجب أن يحتوي السؤال على خيار واحد على الأقل" + "Sorry, the question must have at least one option": "عذرًا، يجب أن يحتوي السؤال على خيار واحد على الأقل", + "must_have_on_item":"يجب ان يحتوي على عنصر واحد على الاقل" }, "header": { "register_students": "تسجيل الطلاب", @@ -107,7 +108,9 @@ "malty_exercise": "تمرين متعدد", "add_new_question": "اضافة سؤال جديد", "exercise": "تمارين", - "icon": "الايقونة" + "icon": "الايقونة", + "add_new_package":"اضافة حزمة جديدة", + "configuration":"إعدادات" }, "columns": { "id": "الرقم التعريفي", @@ -199,7 +202,12 @@ "Are you sure you want to go back and not save any changes?": "هل أنت متأكد أنك تريد العودة وعدم حفظ أي تغييرات؟", "accept_back": "قبول العودة ", "accept": "قبول ", - "to_confirm_deletion_please_re_enter_id": "يرجى اعادة ادخال رقم التعريف" + "to_confirm_deletion_please_re_enter_id": "يرجى اعادة ادخال رقم التعريف", + "add_new":"اضافة عنصر", + "delete_last":"حذف عنصر", + "key":"الاسم", + "value":"القيمة", + "delete_this_item":"حذف هذا العنصر" }, "Table": { "header": "", @@ -365,7 +373,12 @@ "question": "السؤال", "id": "الرقم التعريفي", "canAnswersBeShuffled": "يمكن خلط الإجابات", - "hint": "تَلمِيح" + "hint": "تَلمِيح", + "grade":"الدرجات", + "subject":"المادة", + "curriculum":"مقرر", + "lesson":"الدرس", + "unit":"الوحدة" }, "select": { @@ -725,6 +738,6 @@ "edit_Question": "لوحة القيادة /تعديل اسئلة ", "grade": "لوحة القيادة /الدرجات ", "curriculum": "لوحة القيادة / تعديل مقرر ", - "package":"حزمة" + "package":"لوحة القيادة / الحزم " } } diff --git a/src/types/Package.ts b/src/types/Package.ts new file mode 100644 index 0000000..df887f7 --- /dev/null +++ b/src/types/Package.ts @@ -0,0 +1,30 @@ +import { Nullable } from "./App"; + +// Define the Teacher interface + +export interface Package { + id: number; + name: string; + price: string; + grade_id: number; + subjects_ids: any[]; + units_ids: any[]; + curriculums_ids: any[]; + lessons_ids: any[]; + configuration:{} + +} + +export interface InitialValues { + id: number; + name: string; + price: string; + grade_id: number; + subjects_ids: any[]; + units_ids: any[]; + curriculums_ids: any[]; + lessons_ids: any[]; + configuration:{key:string,value:string}[] +} + +export type PackageInitialValues = Partial>; diff --git a/src/utils/arrayToObject.ts b/src/utils/arrayToObject.ts new file mode 100644 index 0000000..83e46bd --- /dev/null +++ b/src/utils/arrayToObject.ts @@ -0,0 +1,15 @@ + interface KeyValue { + key: string; + value: string; +} + +// Function to convert an array of key-value objects to an object +export function arrayToObject(arr: KeyValue[] | null | undefined ): Record { + if(!arr){ + return {} + } + return arr.reduce((obj, item) => { + obj[item.key] = item.value; + return obj; + }, {} as Record); +} diff --git a/src/utils/objectToArray.ts b/src/utils/objectToArray.ts new file mode 100644 index 0000000..74e43e8 --- /dev/null +++ b/src/utils/objectToArray.ts @@ -0,0 +1,14 @@ + +interface KeyValue { + key: string; + value: string; +} +export function objectToArray(obj: Record | null | undefined): KeyValue[] { + if(!obj){ + return [{key:"",value:""}] + } + return Object.entries(obj).map(([key, value]) => ({ + key, + value + })); +} \ No newline at end of file