fix bug and remove unnesasery
This commit is contained in:
parent
fad0d81565
commit
9530ea30e7
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -20,3 +20,4 @@
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
bundle-analysis.html
|
||||||
File diff suppressed because one or more lines are too long
33
package.json
33
package.json
|
|
@ -4,26 +4,57 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^5.3.7",
|
"@ant-design/icons": "^5.3.7",
|
||||||
|
"@types/draft-js": "^0.11.18",
|
||||||
|
"@types/katex": "^0.16.7",
|
||||||
|
"@types/mathjax": "^0.0.40",
|
||||||
"@types/node": "^20.14.0",
|
"@types/node": "^20.14.0",
|
||||||
|
"@types/react-draft-wysiwyg": "^1.13.8",
|
||||||
"@types/react-helmet": "^6.1.11",
|
"@types/react-helmet": "^6.1.11",
|
||||||
|
"algebra.js": "^0.2.6",
|
||||||
"antd": "^5.17.4",
|
"antd": "^5.17.4",
|
||||||
"apexcharts": "^3.49.1",
|
"apexcharts": "^3.49.1",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
|
"better-react-mathjax": "^2.0.3",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
|
"draft-js": "^0.11.7",
|
||||||
|
"draft-js-latex-plugin": "^0.1.2",
|
||||||
|
"equation-resolver": "^1.0.0",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"html2canvas": "^1.4.1",
|
"html2canvas": "^1.4.1",
|
||||||
"i18next": "^23.11.5",
|
"i18next": "^23.11.5",
|
||||||
"jspdf": "^2.5.1",
|
"jspdf": "^2.5.1",
|
||||||
|
"katex": "^0.16.11",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"mammoth": "^1.8.0",
|
||||||
|
"mathjax": "^3.2.2",
|
||||||
|
"mathjax-react": "^2.0.1",
|
||||||
|
"mathjax3-react": "^1.2.0",
|
||||||
|
"mathquill": "0.10.1-a",
|
||||||
|
"nmath": "^1.0.0",
|
||||||
"path-to-regexp": "^6.2.2",
|
"path-to-regexp": "^6.2.2",
|
||||||
|
"quill-image-resize-module": "^3.0.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-apexcharts": "^1.4.1",
|
"react-apexcharts": "^1.4.1",
|
||||||
|
"react-contenteditable": "^3.3.7",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
|
"react-draft-wysiwyg": "^1.15.0",
|
||||||
|
"react-equation": "^1.0.0",
|
||||||
|
"react-google-docs-viewer": "^1.0.1",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-i18next": "^13.5.0",
|
"react-i18next": "^13.5.0",
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
|
"react-katex": "^3.0.1",
|
||||||
|
"react-latex-next": "^3.0.0",
|
||||||
|
"react-math": "^0.0.1",
|
||||||
|
"react-math-keyboard": "^1.5.17",
|
||||||
|
"react-mathjax": "^1.0.1",
|
||||||
|
"react-mathjax2": "^0.0.2",
|
||||||
|
"react-mathquill": "^1.0.3",
|
||||||
"react-query": "^3.39.3",
|
"react-query": "^3.39.3",
|
||||||
|
"react-quill": "^2.0.0",
|
||||||
"react-router-dom": "^6.23.1",
|
"react-router-dom": "^6.23.1",
|
||||||
|
"react-textarea-autosize": "^8.5.3",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
"reactstrap": "^9.2.2",
|
"reactstrap": "^9.2.2",
|
||||||
"sass": "^1.77.4",
|
"sass": "^1.77.4",
|
||||||
|
|
@ -59,12 +90,10 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/testing-library__jest-dom": "^6.0.0",
|
|
||||||
"@vitejs/plugin-react": "^4.3.0",
|
"@vitejs/plugin-react": "^4.3.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jsdom": "^24.1.0",
|
"jsdom": "^24.1.0",
|
||||||
|
|
|
||||||
3056
pnpm-lock.yaml
3056
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -40,7 +40,7 @@ const App = () => {
|
||||||
routes.map((route: TMenuItem) => {
|
routes.map((route: TMenuItem) => {
|
||||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||||
const tableHeader = t(`${route?.header}`);
|
const tableHeader = t(`${route?.header}`);
|
||||||
useSetPage_title(tableHeader,route?.path);
|
// useSetPage_title(tableHeader,route?.path);
|
||||||
|
|
||||||
if (useAbility) {
|
if (useAbility) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -81,7 +81,7 @@ const App = () => {
|
||||||
{CrudRoute.map((route) => {
|
{CrudRoute.map((route) => {
|
||||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||||
const tableHeader = t(`${route?.header}`);
|
const tableHeader = t(`${route?.header}`);
|
||||||
useSetPage_title(tableHeader,route?.path);
|
// useSetPage_title(tableHeader,route?.path);
|
||||||
|
|
||||||
if (!useAbility) {
|
if (!useAbility) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Binary file not shown.
62
src/Components/testInput/MathInput.tsx
Normal file
62
src/Components/testInput/MathInput.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import katex from 'katex';
|
||||||
|
import 'katex/dist/katex.min.css';
|
||||||
|
|
||||||
|
const MathInput: React.FC = () => {
|
||||||
|
const [latex, setLatex] = useState<string>('f(x) = \\frac{1}{1+e^{-x}}');
|
||||||
|
const displayRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
renderLatex();
|
||||||
|
}, [latex]);
|
||||||
|
//// tow input show and edit
|
||||||
|
const renderLatex = () => {
|
||||||
|
if (displayRef.current) {
|
||||||
|
try {
|
||||||
|
katex.render(latex, displayRef.current, {
|
||||||
|
throwOnError: false,
|
||||||
|
displayMode: true,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('KaTeX rendering error:', error);
|
||||||
|
displayRef.current.textContent = 'Error rendering LaTeX';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setLatex(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '20px' }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={latex}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
fontSize: '16px',
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
marginBottom: '10px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
ref={displayRef}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
fontSize: '16px',
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
borderRadius: '4px',
|
||||||
|
minHeight: '40px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MathInput;
|
||||||
68
src/Components/testInput/MathInputEdatble.tsx
Normal file
68
src/Components/testInput/MathInputEdatble.tsx
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import katex from 'katex';
|
||||||
|
import 'katex/dist/katex.min.css';
|
||||||
|
|
||||||
|
const MathInput: React.FC = () => {
|
||||||
|
const [latex, setLatex] = useState<string>('f(x) = \\frac{1}{1+e^{-x}}');
|
||||||
|
const inputRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [isEditing, setIsEditing] = useState<boolean>(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
renderLatex();
|
||||||
|
}, [latex, isEditing]);
|
||||||
|
|
||||||
|
const renderLatex = () => {
|
||||||
|
if (inputRef.current && !isEditing) {
|
||||||
|
try {
|
||||||
|
katex.render(latex, inputRef.current, {
|
||||||
|
throwOnError: false,
|
||||||
|
displayMode: true,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('KaTeX rendering error:', error);
|
||||||
|
inputRef.current.textContent = 'Error rendering LaTeX';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleInput = () => {
|
||||||
|
if (inputRef.current) {
|
||||||
|
setLatex(inputRef.current.textContent || '');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFocus = () => {
|
||||||
|
setIsEditing(true);
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.textContent = latex;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
setIsEditing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '20px' }}>
|
||||||
|
<div
|
||||||
|
ref={inputRef}
|
||||||
|
contentEditable
|
||||||
|
onInput={handleInput}
|
||||||
|
onFocus={handleFocus}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
fontSize: '16px',
|
||||||
|
border: '1px solid #ccc',
|
||||||
|
borderRadius: '4px',
|
||||||
|
minHeight: '40px',
|
||||||
|
fontFamily: isEditing ? 'monospace' : 'inherit',
|
||||||
|
cursor: 'text',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MathInput;
|
||||||
|
|
@ -1,20 +1,12 @@
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { usePage_titleState } from "../zustand/PageTitleState";
|
import { usePage_titleState } from "../zustand/PageTitleState";
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
import { match } from "path-to-regexp";
|
|
||||||
|
|
||||||
const useSetPage_title = (title: string, path: string) => {
|
const useSetPage_title = (title: any) => {
|
||||||
const { setPage_title } = usePage_titleState((state) => state);
|
const setPage_title = usePage_titleState((state) => state.setPage_title);
|
||||||
const { pathname } = useLocation();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const matchPath = match(path, { decode: decodeURIComponent });
|
setPage_title(title);
|
||||||
const isMatching = matchPath(pathname);
|
}, [title, setPage_title]);
|
||||||
|
|
||||||
if (isMatching) {
|
|
||||||
setPage_title(title);
|
|
||||||
}
|
|
||||||
}, [pathname, path, title, setPage_title]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useSetPage_title;
|
export default useSetPage_title;
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,8 @@ import useModalHandler from "../../utils/useModalHandler";
|
||||||
import { ModalEnum } from "../../enums/Model";
|
import { ModalEnum } from "../../enums/Model";
|
||||||
import ChangePasswordModel from "./model/AddModel";
|
import ChangePasswordModel from "./model/AddModel";
|
||||||
import { getLocalStorage } from "../../utils/LocalStorage";
|
import { getLocalStorage } from "../../utils/LocalStorage";
|
||||||
import NavBarSelect from "../../Components/Layout/NavBarSelect";
|
import { getPrevPathRoute } from "../../utils/getPrevPathRoute";
|
||||||
import usePreviousRoute from "../../Hooks/usePreviousRoute";
|
import { deletePathSegments } from "../../utils/deletePathSegments";
|
||||||
import usePreviousPath from "../../Hooks/usePreviousRoute";
|
|
||||||
import { useLocationsState } from "../../zustand/Location";
|
|
||||||
const NavBar = () => {
|
const NavBar = () => {
|
||||||
const { Page_title } = usePage_titleState((state) => state);
|
const { Page_title } = usePage_titleState((state) => state);
|
||||||
const userData = getLocalStorage(USER_KEY);
|
const userData = getLocalStorage(USER_KEY);
|
||||||
|
|
@ -26,22 +24,14 @@ const NavBar = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const translateArray = translateOptions(search_array, t);
|
const translateArray = translateOptions(search_array, t);
|
||||||
const { course_id } = useParams<ParamsEnum>();
|
|
||||||
console.log(location);
|
|
||||||
const {PreLocation} = useLocationsState()
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const PrevPath = getPrevPathRoute(location.pathname);
|
||||||
|
|
||||||
const handelNavigate = () => {
|
const handelNavigate = () => {
|
||||||
const pattern = /^\/course\/\d+\/eduClass\/\d+$/;
|
if (PrevPath === 0) {
|
||||||
if (pattern.test(location.pathname)) {
|
return 0;
|
||||||
navigate(`/course/${course_id}/eduClass`);
|
|
||||||
return;
|
|
||||||
}else if (PreLocation) {
|
|
||||||
navigate(PreLocation)
|
|
||||||
}else{
|
|
||||||
navigate(-1)
|
|
||||||
}
|
}
|
||||||
|
navigate(deletePathSegments(location.pathname, PrevPath));
|
||||||
};
|
};
|
||||||
|
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { Admin_type } from "../../../types/App";
|
|
||||||
|
|
||||||
import SelectGroup from "../SelectGroups/SelectGroup";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
const { values } = useFormikContext<any>();
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="username"
|
|
||||||
label="username"
|
|
||||||
name="username"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="email"
|
|
||||||
label="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="password"
|
|
||||||
label="password"
|
|
||||||
name="password"
|
|
||||||
/>
|
|
||||||
<ValidationField label="status" name="status" type="Checkbox" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="type"
|
|
||||||
label="type"
|
|
||||||
name="type"
|
|
||||||
type="Select"
|
|
||||||
option={Admin_type}
|
|
||||||
/>
|
|
||||||
{values?.type === "branchAdmin" && (
|
|
||||||
<>
|
|
||||||
{/* <ValidationField
|
|
||||||
placeholder="branch"
|
|
||||||
label="branch"
|
|
||||||
name="branch_id"
|
|
||||||
type="Select"
|
|
||||||
option={Branch}
|
|
||||||
isMulti
|
|
||||||
isDisabled={values?.type !== "branchAdmin"}
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="roles"
|
|
||||||
label="roles"
|
|
||||||
name="roles"
|
|
||||||
type="Select"
|
|
||||||
option={Role}
|
|
||||||
isDisabled={!values?.branch_id}
|
|
||||||
/> */}
|
|
||||||
<SelectGroup />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
|
|
||||||
import { useAddAdmin } from "../../../api/admin";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddAdmin();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.table(values);
|
|
||||||
|
|
||||||
const branches = values?.selects
|
|
||||||
?.map((item: any) => {
|
|
||||||
return {
|
|
||||||
branch_id: item?.branch,
|
|
||||||
role_id: item?.role,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter((item: any) => item.branch_id !== null && item.role_id !== null);
|
|
||||||
|
|
||||||
const dataToSend = { ...values };
|
|
||||||
if (values?.status === true) {
|
|
||||||
dataToSend["status"] = "active";
|
|
||||||
}
|
|
||||||
if (values?.status === false) {
|
|
||||||
dataToSend["status"] = "suspend";
|
|
||||||
}
|
|
||||||
if (branches?.length > 0) {
|
|
||||||
dataToSend["branches"] = branches;
|
|
||||||
}
|
|
||||||
mutate({
|
|
||||||
...dataToSend,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.ADMIN_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.add")} {t("models.admin")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useDeleteAdmin } from "../../../api/admin";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeleteAdmin();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(object_to_edit?.id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.ADMIN_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.delete")} ({object_to_edit?.username}){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("input.name")} {t("models.admin")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.name")} ${t("models.admin")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
object_to_edit?.username !== inputValue ? "disabled_button" : ""
|
|
||||||
}
|
|
||||||
disabled={object_to_edit?.username !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { Admin_type } from "../../../types/App";
|
|
||||||
|
|
||||||
import SelectGroup from "../SelectGroups/SelectGroup";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
|
|
||||||
const { values } = useFormikContext<any>();
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="username"
|
|
||||||
label="username"
|
|
||||||
name="username"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="email"
|
|
||||||
label="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
/>
|
|
||||||
<ValidationField label="status" name="status" type="Checkbox" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="type"
|
|
||||||
label="type"
|
|
||||||
name="type"
|
|
||||||
type="Select"
|
|
||||||
option={Admin_type}
|
|
||||||
/>
|
|
||||||
{values?.type === "branchAdmin" && (
|
|
||||||
<>
|
|
||||||
<SelectGroup />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import {
|
|
||||||
getInitialValues,
|
|
||||||
getEditValidationSchema as getValidationSchema,
|
|
||||||
} from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useGetAllAdmin, useUpdateAdmin } from "../../../api/admin";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
const { mutate, isSuccess, isLoading } = useUpdateAdmin();
|
|
||||||
// console.log(object_to_edit,"object_to_edit");
|
|
||||||
|
|
||||||
const { data } = useGetAllAdmin(
|
|
||||||
{ show: object_to_edit?.id },
|
|
||||||
{ enabled: !!object_to_edit?.id },
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.table(values);
|
|
||||||
set_object_to_edit(values);
|
|
||||||
const branches = values?.selects
|
|
||||||
?.map((item: any) => {
|
|
||||||
return {
|
|
||||||
branch_id: item?.branch,
|
|
||||||
role_id: item?.role,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter((item: any) => item.branch_id !== null && item.role_id !== null);
|
|
||||||
|
|
||||||
const dataToSend = { ...values };
|
|
||||||
if (values?.status === true) {
|
|
||||||
dataToSend["status"] = "active";
|
|
||||||
}
|
|
||||||
if (values?.status === false) {
|
|
||||||
dataToSend["status"] = "suspend";
|
|
||||||
}
|
|
||||||
if (branches?.length > 0) {
|
|
||||||
dataToSend["branches"] = branches;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.table(dataToSend);
|
|
||||||
mutate({
|
|
||||||
...dataToSend,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.ADMIN_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
{object_to_edit && (
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(data)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.edit")} {t("practical.details")} {t("models.admin")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.edit")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { BranchRole, showAdmin } from "../../../types/App";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: showAdmin | any): any => {
|
|
||||||
console.log(objectToEdit, "");
|
|
||||||
|
|
||||||
const selects =
|
|
||||||
objectToEdit?.branches?.map((item: BranchRole, index: number) => {
|
|
||||||
return { branch: item?.branch?.id, role: item?.role?.id };
|
|
||||||
}) ?? [];
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.user?.id ?? null,
|
|
||||||
username: objectToEdit?.user?.username ?? null,
|
|
||||||
email: objectToEdit?.user?.email ?? null,
|
|
||||||
type: objectToEdit?.user?.type ?? null,
|
|
||||||
status: objectToEdit?.user?.status === "active" ? true : false,
|
|
||||||
selects: selects,
|
|
||||||
password: null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
return Yup.object().shape({
|
|
||||||
username: Yup.string().required("validation.required"),
|
|
||||||
password: Yup.string()
|
|
||||||
.required("validation.required")
|
|
||||||
.min(8, "validation.Password_must_be_at_least_8_characters_long"),
|
|
||||||
type: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getEditValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
username: Yup.string().required("validation.required"),
|
|
||||||
type: Yup.string().required("validation.required"),
|
|
||||||
// branch_id: Yup.array().required("validation.required"),
|
|
||||||
// roles: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { Select, Button } from "antd";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useGetAllRole } from "../../../api/role";
|
|
||||||
import useFormatDataToSelect from "../../../utils/useFormatDataToSelect";
|
|
||||||
import { useGetAllBranch } from "../../../api/branch";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const SelectGroup = () => {
|
|
||||||
const { values, setFieldValue } = useFormikContext<any>();
|
|
||||||
|
|
||||||
const { data: RoleData } = useGetAllRole();
|
|
||||||
const Role = useFormatDataToSelect(RoleData?.data);
|
|
||||||
|
|
||||||
const { data: BranchData } =
|
|
||||||
useGetAllBranch();
|
|
||||||
// { whereDoesntHasAdmin:values?.id }
|
|
||||||
const Branch = useFormatDataToSelect(BranchData?.data);
|
|
||||||
|
|
||||||
const addSelectGroup = () => {
|
|
||||||
setFieldValue("selects", [
|
|
||||||
...(values?.selects || []),
|
|
||||||
{ role: null, branch: null },
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRoleChange = (
|
|
||||||
value: { value: string; label: React.ReactNode },
|
|
||||||
index: number,
|
|
||||||
) => {
|
|
||||||
const newSelects = values?.selects ? [...values.selects] : [];
|
|
||||||
|
|
||||||
newSelects[index].role = value;
|
|
||||||
setFieldValue("selects", newSelects);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleBranchChange = (
|
|
||||||
value: { value: string; label: React.ReactNode },
|
|
||||||
index: number,
|
|
||||||
) => {
|
|
||||||
const newSelects = values?.selects ? [...values.selects] : [];
|
|
||||||
newSelects[index].branch = value;
|
|
||||||
setFieldValue("selects", newSelects);
|
|
||||||
if (!value) {
|
|
||||||
newSelects.splice(index, 1);
|
|
||||||
newSelects[index].role = value;
|
|
||||||
setFieldValue("selects", newSelects);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getFilteredBranches = (currentIndex: number) => {
|
|
||||||
const selectedBranches = values?.selects
|
|
||||||
?.map(
|
|
||||||
(select: any, index: number) => index !== currentIndex && select.branch,
|
|
||||||
)
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
return Branch.map((branch: any) => {
|
|
||||||
if (selectedBranches.includes(branch.value)) {
|
|
||||||
return { ...branch, disabled: true };
|
|
||||||
}
|
|
||||||
return branch;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectsArray = values?.selects ?? [];
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{selectsArray.map((group: any, index: number) => {
|
|
||||||
console.log(getFilteredBranches(index));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={index} className="TwoSelectGroup">
|
|
||||||
<Select
|
|
||||||
placeholder={t("input.branch")}
|
|
||||||
options={getFilteredBranches(index)}
|
|
||||||
onChange={(value) => handleBranchChange(value, index)}
|
|
||||||
value={group.branch}
|
|
||||||
size="large"
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
<Select
|
|
||||||
placeholder={t("models.role")}
|
|
||||||
options={Role}
|
|
||||||
onChange={(value) => handleRoleChange(value, index)}
|
|
||||||
value={group.role}
|
|
||||||
size="large"
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
<Button
|
|
||||||
className="TwoSelectGroupbutton"
|
|
||||||
type="dashed"
|
|
||||||
onClick={addSelectGroup}
|
|
||||||
>
|
|
||||||
{t("practical.add_new_role")}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SelectGroup;
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
import SearchField from "../../Components/DataTable/SearchField";
|
|
||||||
|
|
||||||
import useModalHandler from "../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../enums/Model";
|
|
||||||
|
|
||||||
import AddModalForm from "./Model/AddModel";
|
|
||||||
import EditModalForm from "./Model/EditModel";
|
|
||||||
import DeleteModalForm from "./Model/Delete";
|
|
||||||
// import useSetPage_title from "../../Hooks/useSetPageTitle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../utils/hasAbility";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
const [t] = useTranslation();
|
|
||||||
// useSetPage_title(
|
|
||||||
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.ADMIN}`)}`,
|
|
||||||
// );
|
|
||||||
const can_add_Admin = hasAbility(
|
|
||||||
ABILITIES_ENUM.ADMIN,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header className="d-flex justify-content-between">
|
|
||||||
<SearchField searchBy="name" placeholder={t("practical.search_here")} />
|
|
||||||
|
|
||||||
{can_add_Admin && (
|
|
||||||
<div className="Selects">
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.ADMIN_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.admin")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<DeleteModalForm />
|
|
||||||
<AddModalForm />
|
|
||||||
<EditModalForm />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import useSearchQuery from "../../api/utils/useSearchQuery";
|
|
||||||
import { useGetAllAdmin } from "../../api/admin";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const [searchQuery] = useSearchQuery("name");
|
|
||||||
|
|
||||||
const response = useGetAllAdmin({
|
|
||||||
username: searchQuery,
|
|
||||||
pagination: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
import { Space, TableColumnsType, Tooltip } from "antd";
|
|
||||||
|
|
||||||
import { ModalEnum } from "../../enums/Model";
|
|
||||||
import { MdOutlineEdit } from "react-icons/md";
|
|
||||||
import { RiDeleteBin6Fill } from "react-icons/ri";
|
|
||||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
|
||||||
import { useModalState } from "../../zustand/Modal";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../utils/hasAbility";
|
|
||||||
import { Admin } from "../../types/App";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
const { set_object_to_edit } = useObjectToEdit((state) => state);
|
|
||||||
|
|
||||||
const handelDelete = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.ADMIN_DELETE);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const can_edit_Admin = hasAbility(
|
|
||||||
ABILITIES_ENUM.ADMIN,
|
|
||||||
ABILITIES_VALUES_ENUM.UPDATE,
|
|
||||||
);
|
|
||||||
const can_delete_Admin = hasAbility(
|
|
||||||
ABILITIES_ENUM.ADMIN,
|
|
||||||
ABILITIES_VALUES_ENUM.DELETE,
|
|
||||||
);
|
|
||||||
const columns: TableColumnsType<Admin> = [
|
|
||||||
{
|
|
||||||
title: t("columns.id"),
|
|
||||||
dataIndex: "id",
|
|
||||||
key: "id",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.username"),
|
|
||||||
dataIndex: "username",
|
|
||||||
key: "username",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.email"),
|
|
||||||
dataIndex: "email",
|
|
||||||
key: "email",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.type"),
|
|
||||||
dataIndex: "type",
|
|
||||||
key: "type",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.status"),
|
|
||||||
dataIndex: "status",
|
|
||||||
key: "status",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: "",
|
|
||||||
key: "actions",
|
|
||||||
align: "end",
|
|
||||||
width: "14vw",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.ADMIN_EDIT);
|
|
||||||
};
|
|
||||||
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space size="middle" className={className}>
|
|
||||||
{can_edit_Admin && (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("practical.edit")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<span onClick={() => handleEdit(record)}>
|
|
||||||
<MdOutlineEdit
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{can_delete_Admin && (
|
|
||||||
<RiDeleteBin6Fill
|
|
||||||
onClick={() => handelDelete(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#C11313" }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
|
||||||
<ValidationField label="status" name="status" type="Checkbox" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="starting_date"
|
|
||||||
label="starting_date"
|
|
||||||
type="Date"
|
|
||||||
name="starting_date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="ending_date"
|
|
||||||
label="ending_date"
|
|
||||||
type="Date"
|
|
||||||
name="ending_date"
|
|
||||||
/>{" "}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
|
|
||||||
import { useAddCycle } from "../../../../api/cycle";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { ParamsEnum } from "../../../../enums/params";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddCycle();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const { branch_id } = useParams<ParamsEnum>();
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
starting_date: "",
|
|
||||||
ending_date: "",
|
|
||||||
branch_id: branch_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (values?.status === true) {
|
|
||||||
dataToSend["status"] = "active";
|
|
||||||
}
|
|
||||||
if (values?.status === false) {
|
|
||||||
dataToSend["status"] = "inActive";
|
|
||||||
}
|
|
||||||
dataToSend["starting_date"] = values?.starting_date?.format("YYYY-MM-DD");
|
|
||||||
dataToSend["ending_date"] = values?.ending_date?.format("YYYY-MM-DD");
|
|
||||||
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.CYCLE_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.add")} {t("models.cycle")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useDeleteCycle } from "../../../../api/cycle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeleteCycle();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(object_to_edit?.id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.CYCLE_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.delete")} ({object_to_edit?.name}){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("input.name")} {t("models.cycle")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.name")} ${t("models.cycle")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
object_to_edit?.name !== inputValue ? "disabled_button" : ""
|
|
||||||
}
|
|
||||||
disabled={object_to_edit?.name !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
|
||||||
const Form = () => {
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
|
||||||
<ValidationField label="status" name="status" type="Checkbox" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="starting_date"
|
|
||||||
label="starting_date"
|
|
||||||
type="Date"
|
|
||||||
name="starting_date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="ending_date"
|
|
||||||
label="ending_date"
|
|
||||||
type="Date"
|
|
||||||
name="ending_date"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useUpdateCycle } from "../../../../api/cycle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { ParamsEnum } from "../../../../enums/params";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
const { mutate, isSuccess, isLoading } = useUpdateCycle();
|
|
||||||
|
|
||||||
const { branch_id } = useParams<ParamsEnum>();
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
starting_date: "",
|
|
||||||
ending_date: "",
|
|
||||||
branch_id: branch_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (values?.status === true) {
|
|
||||||
dataToSend["status"] = "active";
|
|
||||||
}
|
|
||||||
if (values?.status === false) {
|
|
||||||
dataToSend["status"] = "inActive";
|
|
||||||
}
|
|
||||||
dataToSend["starting_date"] = values?.starting_date?.format("YYYY-MM-DD");
|
|
||||||
dataToSend["ending_date"] = values?.ending_date?.format("YYYY-MM-DD");
|
|
||||||
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.CYCLE_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
{object_to_edit && (
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.edit")} {t("practical.details")} {t("models.cycle")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.edit")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
console.log(objectToEdit, "objectToEdit");
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? null,
|
|
||||||
name: objectToEdit?.name ?? null,
|
|
||||||
starting_date: objectToEdit?.starting_date
|
|
||||||
? dayjs(objectToEdit?.starting_date, "YYYY/MM/DD")
|
|
||||||
: null ?? null,
|
|
||||||
ending_date: objectToEdit?.ending_date
|
|
||||||
? dayjs(objectToEdit?.ending_date, "YYYY/MM/DD")
|
|
||||||
: null ?? null,
|
|
||||||
status: objectToEdit?.status === "active" ? true : false,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
name: Yup.string().required("validation.required"),
|
|
||||||
starting_date: Yup.string().required("validation.required"),
|
|
||||||
ending_date: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
import SearchField from "../../../Components/DataTable/SearchField";
|
|
||||||
|
|
||||||
import useModalHandler from "../../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
|
|
||||||
import AddModalForm from "./Model/AddModel";
|
|
||||||
import EditModalForm from "./Model/EditModel";
|
|
||||||
import DeleteModalForm from "./Model/Delete";
|
|
||||||
// import useSetPage_title from "../../../Hooks/useSetPageTitle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../../utils/hasAbility";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
const [t] = useTranslation();
|
|
||||||
// useSetPage_title(
|
|
||||||
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.BRANCH}`)} / ${t(`models.${ABILITIES_ENUM.CYCLE}`)}`,
|
|
||||||
// );
|
|
||||||
const can_add_Cycle = hasAbility(
|
|
||||||
ABILITIES_ENUM.CYCLE,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header className="d-flex justify-content-between">
|
|
||||||
<SearchField searchBy="name" placeholder={t("practical.search_here")} />
|
|
||||||
|
|
||||||
{can_add_Cycle && (
|
|
||||||
<div className="Selects">
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.CYCLE_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.cycle")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<DeleteModalForm />
|
|
||||||
<AddModalForm />
|
|
||||||
<EditModalForm />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { useLocation, useParams } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import { useGetAllCycle } from "../../../api/cycle";
|
|
||||||
import DataTable from "../../../Layout/Dashboard/Table/DataTable";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import useSearchQuery from "../../../api/utils/useSearchQuery";
|
|
||||||
import { ParamsEnum } from "../../../enums/params";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const [searchQuery] = useSearchQuery("name");
|
|
||||||
const { branch_id } = useParams<ParamsEnum>();
|
|
||||||
const response = useGetAllCycle({
|
|
||||||
name: searchQuery,
|
|
||||||
pagination: true,
|
|
||||||
branch_id: branch_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
||||||
import { Space, TableColumnsType, Tooltip } from "antd";
|
|
||||||
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { MdOutlineEdit } from "react-icons/md";
|
|
||||||
import { RiDeleteBin6Fill } from "react-icons/ri";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../../utils/hasAbility";
|
|
||||||
import { Cycle } from "../../../types/App";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { EyeFilled } from "@ant-design/icons";
|
|
||||||
import { BsEye, BsEyeFill, BsEyeSlash } from "react-icons/bs";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
const { set_object_to_edit } = useObjectToEdit((state) => state);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const handelDelete = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.CYCLE_DELETE);
|
|
||||||
};
|
|
||||||
const handelShow = (record: any) => {
|
|
||||||
navigate(`${record?.id}/${ABILITIES_ENUM?.TERM}`);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const can_edit_Cycle = hasAbility(
|
|
||||||
ABILITIES_ENUM.CYCLE,
|
|
||||||
ABILITIES_VALUES_ENUM.UPDATE,
|
|
||||||
);
|
|
||||||
const can_delete_Cycle = hasAbility(
|
|
||||||
ABILITIES_ENUM.CYCLE,
|
|
||||||
ABILITIES_VALUES_ENUM.DELETE,
|
|
||||||
);
|
|
||||||
const can_show_Cycle = hasAbility(
|
|
||||||
ABILITIES_ENUM.CYCLE,
|
|
||||||
ABILITIES_VALUES_ENUM.SHOW,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns: TableColumnsType<Cycle> = [
|
|
||||||
{
|
|
||||||
title: t("columns.id"),
|
|
||||||
dataIndex: "id",
|
|
||||||
key: "id",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.name"),
|
|
||||||
dataIndex: "name",
|
|
||||||
key: "name",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.starting_date"),
|
|
||||||
dataIndex: "starting_date",
|
|
||||||
key: "starting_date",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.ending_date"),
|
|
||||||
dataIndex: "ending_date",
|
|
||||||
key: "ending_date",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.status"),
|
|
||||||
dataIndex: "status",
|
|
||||||
key: "status",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
if (record?.status === "active") {
|
|
||||||
return <div> نشط </div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div> غير نشط </div>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: "",
|
|
||||||
key: "actions",
|
|
||||||
align: "end",
|
|
||||||
width: "24vw",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.CYCLE_EDIT);
|
|
||||||
};
|
|
||||||
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space size="middle" className={className}>
|
|
||||||
{can_edit_Cycle && (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("practical.edit")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<span onClick={() => handleEdit(record)}>
|
|
||||||
<MdOutlineEdit
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{can_delete_Cycle && (
|
|
||||||
<RiDeleteBin6Fill
|
|
||||||
onClick={() => handelDelete(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#C11313" }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("header.view_term_for_this_cycle")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<BsEyeFill
|
|
||||||
onClick={() => handelShow(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "green" }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="address" label="address" name="address" />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
|
|
||||||
import { useAddBranch } from "../../../api/branch";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddBranch();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.log(values, "values");
|
|
||||||
|
|
||||||
mutate({
|
|
||||||
name: values?.name,
|
|
||||||
address: values?.address,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.BRANCH_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.add")} {t("models.branch")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useDeleteBranch } from "../../../api/branch";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeleteBranch();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(object_to_edit?.id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.BRANCH_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.delete")} ({object_to_edit?.name}){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("input.name")} {t("models.branch")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.name")} ${t("models.branch")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
object_to_edit?.name !== inputValue ? "disabled_button" : ""
|
|
||||||
}
|
|
||||||
disabled={object_to_edit?.name !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
|
||||||
const Form = () => {
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="address" label="address" name="address" />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useUpdateBranch } from "../../../api/branch";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
const { mutate, isSuccess, isLoading } = useUpdateBranch();
|
|
||||||
// console.log(object_to_edit,"object_to_edit");
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
mutate({
|
|
||||||
id: values?.id,
|
|
||||||
name: values?.name,
|
|
||||||
address: values?.address,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.BRANCH_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
{object_to_edit && (
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.edit")} {t("practical.details")} {t("models.branch")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.edit")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
// console.log(objectToEdit?.name,"objectToEdit");
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? null,
|
|
||||||
name: objectToEdit?.name ?? null,
|
|
||||||
address: objectToEdit?.address ?? null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
name: Yup.string().required("validation.required"),
|
|
||||||
address: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
import SearchField from "../../Components/DataTable/SearchField";
|
|
||||||
|
|
||||||
import useModalHandler from "../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../enums/Model";
|
|
||||||
|
|
||||||
import AddModalForm from "./Model/AddModel";
|
|
||||||
import EditModalForm from "./Model/EditModel";
|
|
||||||
import DeleteModalForm from "./Model/Delete";
|
|
||||||
// import useSetPage_title from "../../Hooks/useSetPageTitle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../utils/hasAbility";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
const [t] = useTranslation();
|
|
||||||
// useSetPage_title(
|
|
||||||
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.BRANCH}`)}`,
|
|
||||||
// );
|
|
||||||
const can_add_Branch = hasAbility(
|
|
||||||
ABILITIES_ENUM.BRANCH,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header className="d-flex justify-content-between">
|
|
||||||
<SearchField searchBy="name" placeholder={t("practical.search_here")} />
|
|
||||||
|
|
||||||
{can_add_Branch && (
|
|
||||||
<div className="Selects">
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.BRANCH_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.branch")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<DeleteModalForm />
|
|
||||||
<AddModalForm />
|
|
||||||
<EditModalForm />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import { useGetAllBranch } from "../../api/branch";
|
|
||||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import useSearchQuery from "../../api/utils/useSearchQuery";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const [searchQuery] = useSearchQuery("name");
|
|
||||||
|
|
||||||
const response = useGetAllBranch({
|
|
||||||
name: searchQuery,
|
|
||||||
pagination: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { Term_type } from "../../../../types/App";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="term_type"
|
|
||||||
label="term_type"
|
|
||||||
name="term_type"
|
|
||||||
type="Select"
|
|
||||||
option={Term_type}
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="description"
|
|
||||||
label="description"
|
|
||||||
name="description"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="starting_date"
|
|
||||||
label="starting_date"
|
|
||||||
type="Date"
|
|
||||||
name="starting_date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="ending_date"
|
|
||||||
label="ending_date"
|
|
||||||
type="Date"
|
|
||||||
name="ending_date"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
|
|
||||||
import { useAddTerm } from "../../../../api/term";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { ParamsEnum } from "../../../../enums/params";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddTerm();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const { cycle_id } = useParams<ParamsEnum>();
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.log(values, "values");
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
starting_date: "",
|
|
||||||
ending_date: "",
|
|
||||||
cycle_id: cycle_id,
|
|
||||||
};
|
|
||||||
dataToSend["starting_date"] = values?.starting_date?.format("YYYY-MM-DD");
|
|
||||||
dataToSend["ending_date"] = values?.ending_date?.format("YYYY-MM-DD");
|
|
||||||
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.TERM_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.add")} {t("models.term")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useDeleteTerm } from "../../../../api/term";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeleteTerm();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(object_to_edit?.id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.TERM_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.delete")} ({object_to_edit?.term_type}){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("input.name")} {t("models.term")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.name")} ${t("models.term")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
object_to_edit?.term_type !== inputValue
|
|
||||||
? "disabled_button"
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
disabled={object_to_edit?.term_type !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { Term_type } from "../../../../types/App";
|
|
||||||
const Form = () => {
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="term_type"
|
|
||||||
label="term_type"
|
|
||||||
name="term_type"
|
|
||||||
type="Select"
|
|
||||||
option={Term_type}
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="description"
|
|
||||||
label="description"
|
|
||||||
name="description"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="starting_date"
|
|
||||||
label="starting_date"
|
|
||||||
type="Date"
|
|
||||||
name="starting_date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="ending_date"
|
|
||||||
label="ending_date"
|
|
||||||
type="Date"
|
|
||||||
name="ending_date"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useUpdateTerm } from "../../../../api/term";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { ParamsEnum } from "../../../../enums/params";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
const { mutate, isSuccess, isLoading } = useUpdateTerm();
|
|
||||||
|
|
||||||
const { cycle_id } = useParams<ParamsEnum>();
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.log(values, "values");
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
starting_date: "",
|
|
||||||
ending_date: "",
|
|
||||||
cycle_id: cycle_id,
|
|
||||||
};
|
|
||||||
dataToSend["starting_date"] = values?.starting_date?.format("YYYY-MM-DD");
|
|
||||||
dataToSend["ending_date"] = values?.ending_date?.format("YYYY-MM-DD");
|
|
||||||
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.TERM_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
{object_to_edit && (
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.edit")} {t("practical.details")} {t("models.term")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.edit")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
console.log(objectToEdit, "objectToEdit");
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? null,
|
|
||||||
starting_date: objectToEdit?.starting_date
|
|
||||||
? dayjs(objectToEdit?.starting_date, "YYYY/MM/DD")
|
|
||||||
: null ?? null,
|
|
||||||
ending_date: objectToEdit?.ending_date
|
|
||||||
? dayjs(objectToEdit?.ending_date, "YYYY/MM/DD")
|
|
||||||
: null ?? null,
|
|
||||||
term_type: objectToEdit?.term_type ?? null,
|
|
||||||
description: objectToEdit?.description ?? null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
starting_date: Yup.string().required("validation.required"),
|
|
||||||
ending_date: Yup.string().required("validation.required"),
|
|
||||||
term_type: Yup.string().required("validation.required"),
|
|
||||||
description: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
import SearchField from "../../../Components/DataTable/SearchField";
|
|
||||||
|
|
||||||
import useModalHandler from "../../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
|
|
||||||
import AddModalForm from "./Model/AddModel";
|
|
||||||
import EditModalForm from "./Model/EditModel";
|
|
||||||
import DeleteModalForm from "./Model/Delete";
|
|
||||||
// import useSetPage_title from "../../../Hooks/useSetPageTitle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../../utils/hasAbility";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
const [t] = useTranslation();
|
|
||||||
// useSetPage_title(
|
|
||||||
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.BRANCH}`)} / ${t(`models.${ABILITIES_ENUM.CYCLE}`)} / ${t(`models.${ABILITIES_ENUM.TERM}`)}`,
|
|
||||||
// );
|
|
||||||
const can_add_Term = hasAbility(
|
|
||||||
ABILITIES_ENUM.TERM,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header className="d-flex justify-content-between">
|
|
||||||
<SearchField searchBy="name" placeholder={t("practical.search_here")} />
|
|
||||||
|
|
||||||
{can_add_Term && (
|
|
||||||
<div className="Selects">
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.TERM_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.term")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<DeleteModalForm />
|
|
||||||
<AddModalForm />
|
|
||||||
<EditModalForm />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import { useLocation, useParams } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import { useGetAllTerm } from "../../../api/term";
|
|
||||||
import DataTable from "../../../Layout/Dashboard/Table/DataTable";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import useSearchQuery from "../../../api/utils/useSearchQuery";
|
|
||||||
import { ParamsEnum } from "../../../enums/params";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const [searchQuery] = useSearchQuery("name");
|
|
||||||
const { cycle_id } = useParams<ParamsEnum>();
|
|
||||||
|
|
||||||
const response = useGetAllTerm({
|
|
||||||
name: searchQuery,
|
|
||||||
pagination: true,
|
|
||||||
cycle_id: cycle_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
import { Space, TableColumnsType, Tooltip } from "antd";
|
|
||||||
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { MdOutlineEdit } from "react-icons/md";
|
|
||||||
import { RiDeleteBin6Fill } from "react-icons/ri";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../../utils/hasAbility";
|
|
||||||
import { Term, Term_type } from "../../../types/App";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { EyeFilled } from "@ant-design/icons";
|
|
||||||
import { BsEye, BsEyeFill, BsEyeSlash } from "react-icons/bs";
|
|
||||||
import { findLabelByValue } from "../../../utils/findLabelByValue";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
const { set_object_to_edit } = useObjectToEdit((state) => state);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const handelDelete = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.TERM_DELETE);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const can_edit_Term = hasAbility(
|
|
||||||
ABILITIES_ENUM.TERM,
|
|
||||||
ABILITIES_VALUES_ENUM.UPDATE,
|
|
||||||
);
|
|
||||||
const can_delete_Term = hasAbility(
|
|
||||||
ABILITIES_ENUM.TERM,
|
|
||||||
ABILITIES_VALUES_ENUM.DELETE,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns: TableColumnsType<Term> = [
|
|
||||||
{
|
|
||||||
title: t("columns.id"),
|
|
||||||
dataIndex: "id",
|
|
||||||
key: "id",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: t("columns.starting_date"),
|
|
||||||
dataIndex: "starting_date",
|
|
||||||
key: "starting_date",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.ending_date"),
|
|
||||||
dataIndex: "ending_date",
|
|
||||||
key: "ending_date",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.type"),
|
|
||||||
dataIndex: "term_type",
|
|
||||||
key: "term_type",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => {
|
|
||||||
console.log(record?.term_type);
|
|
||||||
|
|
||||||
const value = findLabelByValue(Term_type, record?.term_type);
|
|
||||||
return <>{t(`${value}`)}</>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: "",
|
|
||||||
key: "actions",
|
|
||||||
align: "end",
|
|
||||||
width: "24vw",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.TERM_EDIT);
|
|
||||||
};
|
|
||||||
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space size="middle" className={className}>
|
|
||||||
{can_edit_Term && (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("practical.edit")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<span onClick={() => handleEdit(record)}>
|
|
||||||
<MdOutlineEdit
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{can_delete_Term && (
|
|
||||||
<RiDeleteBin6Fill
|
|
||||||
onClick={() => handelDelete(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#C11313" }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
import { Space, TableColumnsType, Tooltip } from "antd";
|
|
||||||
|
|
||||||
import { ModalEnum } from "../../enums/Model";
|
|
||||||
import { MdOutlineEdit } from "react-icons/md";
|
|
||||||
import { RiDeleteBin6Fill } from "react-icons/ri";
|
|
||||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
|
||||||
import { useModalState } from "../../zustand/Modal";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../utils/hasAbility";
|
|
||||||
import { Branch } from "../../types/App";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { EyeFilled } from "@ant-design/icons";
|
|
||||||
import { BsEye, BsEyeFill, BsEyeSlash } from "react-icons/bs";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
const { set_object_to_edit } = useObjectToEdit((state) => state);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const handelDelete = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.BRANCH_DELETE);
|
|
||||||
};
|
|
||||||
const handelShow = (record: any) => {
|
|
||||||
navigate(`${record?.id}/${ABILITIES_ENUM?.CYCLE}`);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const can_edit_BRANCH = hasAbility(
|
|
||||||
ABILITIES_ENUM.BRANCH,
|
|
||||||
ABILITIES_VALUES_ENUM.UPDATE,
|
|
||||||
);
|
|
||||||
const can_delete_BRANCH = hasAbility(
|
|
||||||
ABILITIES_ENUM.BRANCH,
|
|
||||||
ABILITIES_VALUES_ENUM.DELETE,
|
|
||||||
);
|
|
||||||
const can_show_BRANCH = hasAbility(
|
|
||||||
ABILITIES_ENUM.BRANCH,
|
|
||||||
ABILITIES_VALUES_ENUM.SHOW,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns: TableColumnsType<Branch> = [
|
|
||||||
{
|
|
||||||
title: t("columns.id"),
|
|
||||||
dataIndex: "id",
|
|
||||||
key: "id",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.name"),
|
|
||||||
dataIndex: "name",
|
|
||||||
key: "name",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.address"),
|
|
||||||
dataIndex: "address",
|
|
||||||
key: "address",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: "",
|
|
||||||
key: "actions",
|
|
||||||
align: "end",
|
|
||||||
width: "24vw",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
setIsOpen(ModalEnum?.BRANCH_EDIT);
|
|
||||||
};
|
|
||||||
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space size="middle" className={className}>
|
|
||||||
{can_edit_BRANCH && (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("practical.edit")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<span onClick={() => handleEdit(record)}>
|
|
||||||
<MdOutlineEdit
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{can_delete_BRANCH && (
|
|
||||||
<RiDeleteBin6Fill
|
|
||||||
onClick={() => handelDelete(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#C11313" }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("header.view_cycle_for_this_branch")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<BsEyeFill
|
|
||||||
onClick={() => handelShow(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "green" }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
|
||||||
import ReactApexChart from "react-apexcharts";
|
|
||||||
|
|
||||||
const AreaChart: React.FC = () => {
|
|
||||||
const chartRef = useRef<any>(null); // Ref for the chart component
|
|
||||||
const [options, setOptions] = useState<any>({
|
|
||||||
chart: {
|
|
||||||
type: "area",
|
|
||||||
toolbar: {
|
|
||||||
show: false, // Disable the toolbar
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dataLabels: {
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
stroke: {
|
|
||||||
curve: "smooth",
|
|
||||||
},
|
|
||||||
xaxis: {
|
|
||||||
type: "text",
|
|
||||||
categories: [
|
|
||||||
"كانون الثاني",
|
|
||||||
"شباط",
|
|
||||||
"آذار",
|
|
||||||
"نيسان",
|
|
||||||
"أيار",
|
|
||||||
"حزيران",
|
|
||||||
"تموز",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
x: {
|
|
||||||
format: "عدد الطلاب في الصفوف",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const [series, setSeries] = useState<any>([
|
|
||||||
{
|
|
||||||
name: "الصف الاول",
|
|
||||||
data: [31, 40, 28, 51, 42, 109, 100],
|
|
||||||
color: "#FCC43E",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "الصف الثاني ",
|
|
||||||
data: [11, 32, 45, 32, 34, 52, 41],
|
|
||||||
color: "#FB7D5B",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "الصف الثالث ",
|
|
||||||
data: [21, 12, 35, 22, 14, 22, 1],
|
|
||||||
color: "#9dfb2b",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="AreaChart">
|
|
||||||
<div id="chart">
|
|
||||||
<ReactApexChart
|
|
||||||
options={options}
|
|
||||||
series={series}
|
|
||||||
type="area"
|
|
||||||
className="ReactApexChartArea"
|
|
||||||
height={400}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div id="html-dist"></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AreaChart;
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { useGetAllExamTypes } from "../../../api/examTypes";
|
|
||||||
import useFormatDataToSelect from "../../../utils/useFormatDataToSelect";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
const { data: ExamTypes } = useGetAllExamTypes({});
|
|
||||||
const ExamTypesSelect = useFormatDataToSelect(ExamTypes?.data);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
|
||||||
<ValidationField
|
|
||||||
placeholder="price"
|
|
||||||
label="price"
|
|
||||||
name="price"
|
|
||||||
type="NumberFormate"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="exam_type"
|
|
||||||
label="exam_type"
|
|
||||||
type="Select"
|
|
||||||
isMulti
|
|
||||||
option={ExamTypesSelect}
|
|
||||||
name="exam_type_ids"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
|
|
||||||
import { useAddTeacher } from "../../../api/teacher";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useAddCourse } from "../../../api/course";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddCourse();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
mutate(values);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.COURSE_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.add")} {t("models.course")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useDeleteCourse, useGetAllCourse } from "../../../api/course";
|
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isSuccess, isLoading } = useDeleteCourse();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const { course_id } = useParams();
|
|
||||||
|
|
||||||
const { data: edu_class } = useGetAllCourse({
|
|
||||||
show: course_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const course_name = edu_class?.data?.name || "";
|
|
||||||
const full_name = " " + course_name;
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
navigate(-1);
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, navigate, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(course_id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.COURSE_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.delete")} ({full_name}){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("models.course")} {t("input.name")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.name")} ${t("models.course")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={course_name !== inputValue ? "disabled_button" : ""}
|
|
||||||
disabled={course_name !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
// console.log(objectToEdit?.name,"objectToEdit");
|
|
||||||
|
|
||||||
return {
|
|
||||||
price: objectToEdit?.contact_information ?? null,
|
|
||||||
name: objectToEdit?.name ?? null,
|
|
||||||
exam_type_ids: objectToEdit?.address ?? null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
price: Yup.number()
|
|
||||||
.required("validation.required")
|
|
||||||
.typeError("validation.Must_be_a_number"),
|
|
||||||
name: Yup.string().required("validation.required"),
|
|
||||||
exam_type_ids: Yup.array().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import React, { Suspense, lazy } from "react";
|
|
||||||
import { Spin } from "antd";
|
|
||||||
import { useGetAllCourse } from "../../api/course";
|
|
||||||
// import { ABILITIES_ENUM } from "../../enums/abilities";
|
|
||||||
// import useSetPage_title from "../../Hooks/useSetPageTitle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const HeaderCardsSection = lazy(() => import("../../Components/Course/CourseHeaderSection"));
|
|
||||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
|
||||||
// const AreaChart = lazy(() => import("./Chart/AreaChart"));
|
|
||||||
|
|
||||||
const Course = () => {
|
|
||||||
const [t] = useTranslation();
|
|
||||||
// useSetPage_title(
|
|
||||||
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.COURSE}`)}`,
|
|
||||||
// );
|
|
||||||
|
|
||||||
const { data, isLoading } = useGetAllCourse();
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="Course">
|
|
||||||
<Suspense fallback={<Spin />}>
|
|
||||||
|
|
||||||
<HeaderCardsSection data={data} isLoading={isLoading} />
|
|
||||||
<AddModalForm />
|
|
||||||
{/* <AreaChart /> */}
|
|
||||||
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Course;
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useDeleteEduClass, useGetAllEduClass } from "../../../api/eduClass";
|
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeleteEduClass();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
|
|
||||||
const { data: edu_class } = useGetAllEduClass({
|
|
||||||
show: edu_class_id,
|
|
||||||
});
|
|
||||||
const edu_class_name = edu_class?.data?.name || "";
|
|
||||||
const course_name = edu_class?.data?.course?.name || "";
|
|
||||||
const full_name = " " + course_name + " ( " + edu_class_name + " )";
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
navigate(-1);
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, navigate, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(edu_class_id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.EDUClASS_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.delete")} {full_name}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("input.name")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.name")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={edu_class_name !== inputValue ? "disabled_button" : ""}
|
|
||||||
disabled={edu_class_name !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import { notes } from "../../../types/App";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
const formik = useFormikContext();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik?.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
name="date"
|
|
||||||
label="date"
|
|
||||||
placeholder="date"
|
|
||||||
type="Date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
type="TextArea"
|
|
||||||
name="content"
|
|
||||||
placeholder="content"
|
|
||||||
label="content"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
name="type"
|
|
||||||
label="type"
|
|
||||||
placeholder="type"
|
|
||||||
type="Select"
|
|
||||||
option={notes}
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="attachments"
|
|
||||||
type="File"
|
|
||||||
name="attachments"
|
|
||||||
label="attachments"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./SendNotificationCourse";
|
|
||||||
import { getInitialValues, getValidationSchema } from "../Model/formUtil";
|
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { useAddNote } from "../../../api/note";
|
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { course_id } = useParams();
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddNote();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess, set_object_to_edit]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.log(values, "values");
|
|
||||||
const Data_To_Send = { ...values };
|
|
||||||
Data_To_Send["date"] = values.date?.format("YYYY-MM-DD");
|
|
||||||
mutate({
|
|
||||||
...values,
|
|
||||||
course_ids: [course_id],
|
|
||||||
attachments: [values?.attachments],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.COURSE_SENDNOTIFICATION}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>{t("practical.send_notification_to_course")} </header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { translateOptions } from "../../../../utils/translatedOptions";
|
|
||||||
import { Sex_Select_options } from "../../../../types/App";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="sex"
|
|
||||||
label="sex"
|
|
||||||
type="Select"
|
|
||||||
option={translateOptions(Sex_Select_options, t)}
|
|
||||||
name="sex"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useAddEduClass } from "../../../../api/eduClass";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { ParamsEnum } from "../../../../enums/params";
|
|
||||||
import { CYCLE_OBJECT_KEY } from "../../../../config/AppKey";
|
|
||||||
import { getLocalStorage } from "../../../../utils/LocalStorage";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddEduClass();
|
|
||||||
const { set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
const { course_id } = useParams<ParamsEnum>();
|
|
||||||
const cycleData = getLocalStorage(CYCLE_OBJECT_KEY);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
mutate({
|
|
||||||
...values,
|
|
||||||
course_id: course_id,
|
|
||||||
cycle_id: cycleData?.id,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.EDUClASS_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues([])}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.add")} {t("models.education_class")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
// console.log(objectToEdit?.name,"objectToEdit");
|
|
||||||
|
|
||||||
return {
|
|
||||||
sex: null,
|
|
||||||
name: null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
sex: Yup.string().required("validation.required"),
|
|
||||||
name: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
return {
|
|
||||||
content: null,
|
|
||||||
date: dayjs(Date()),
|
|
||||||
type: null,
|
|
||||||
attachments: null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
content: Yup.string().required("validation.required"),
|
|
||||||
date: Yup.string().required("validation.required"),
|
|
||||||
type: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
import HeaderCardsSection from "../../Components/EduClass/EduClassHeaderSection";
|
|
||||||
import TablePage from "../subject/Table/TablePage";
|
|
||||||
import { usePage_titleState } from "../../zustand/PageTitleState";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
import AddModalForm from "./Model/add/AddModel";
|
|
||||||
import SendNotificationModalForm from "./Model/SendNotificationCourseModel";
|
|
||||||
import DeleteModalForm from "../Course/Model/Delete";
|
|
||||||
import { ModalEnum } from "../../enums/Model";
|
|
||||||
import useModalHandler from "../../utils/useModalHandler";
|
|
||||||
import AddSubjectModalForm from "../subject/Model/AddModel";
|
|
||||||
import EditSubjectModalForm from "../subject/Model/EditModel";
|
|
||||||
import DeleteSubjectModalForm from "../subject/Model/Delete";
|
|
||||||
import { hasAbility } from "../../utils/hasAbility";
|
|
||||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
|
|
||||||
// import useSetPage_title from "../../Hooks/useSetPageTitle";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import DeleteModels from "../../Layout/Dashboard/DeleteModels";
|
|
||||||
import { useDeleteCourse } from "../../api/course";
|
|
||||||
const Page = () => {
|
|
||||||
const { title } = usePage_titleState((state) => state);
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
// useSetPage_title(
|
|
||||||
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.COURSE}`)} / ${t(`models.${ABILITIES_ENUM.EDUCATION_CLASS}`)}`,
|
|
||||||
// );
|
|
||||||
|
|
||||||
const store_subject_ability = hasAbility(
|
|
||||||
ABILITIES_ENUM?.SUBJECT,
|
|
||||||
ABILITIES_VALUES_ENUM?.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
const deleteMutation = useDeleteCourse();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="EduClass">
|
|
||||||
<HeaderCardsSection />
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header>
|
|
||||||
<h4 className="Bold Primary ">{t("models.subject")}</h4>
|
|
||||||
{store_subject_ability && (
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.SUBJECT_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.subject")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</header>
|
|
||||||
<TablePage />
|
|
||||||
</div>
|
|
||||||
<AddModalForm />
|
|
||||||
<SendNotificationModalForm />
|
|
||||||
<DeleteModalForm />
|
|
||||||
<AddSubjectModalForm />
|
|
||||||
<EditSubjectModalForm />
|
|
||||||
<DeleteSubjectModalForm />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Page;
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { useButtonState } from "../../../zustand/ButtonState";
|
|
||||||
import Student from "./Tables/Student/TableHeader";
|
|
||||||
import Programme from "./Tables/programme/Page";
|
|
||||||
import Registration from "./Tables/registration/TableHeader";
|
|
||||||
import EarlyDeparture from "./Tables/earlyDeparture/TableHeader";
|
|
||||||
import HomeWork from "./Tables/homework/TableHeader";
|
|
||||||
import SessionContent from "./Tables/sessionContent/TableHeader";
|
|
||||||
import Note from "./Tables/Note/TableHeader";
|
|
||||||
import Payment from "./Tables/Payment/TableHeader";
|
|
||||||
import Mark from "./Tables/mark/TableHeader";
|
|
||||||
import { hasAbility } from "../../../utils/hasAbility";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../enums/abilities";
|
|
||||||
|
|
||||||
export const EduClassComponents = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: "Student_Records",
|
|
||||||
component: <Student />,
|
|
||||||
abilities: ABILITIES_ENUM?.STUDENT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: "Attendance",
|
|
||||||
component: <Registration />,
|
|
||||||
abilities: ABILITIES_ENUM?.ABSENCE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: "Permissions",
|
|
||||||
component: <EarlyDeparture />,
|
|
||||||
abilities: ABILITIES_ENUM?.EARLY_DEPARTURE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: "Grades",
|
|
||||||
component: <Mark />,
|
|
||||||
abilities: ABILITIES_ENUM?.MARK,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
name: "Notes",
|
|
||||||
component: <Note />,
|
|
||||||
abilities: ABILITIES_ENUM?.NOTE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
name: "Financial_Status",
|
|
||||||
component: <Payment />,
|
|
||||||
abilities: ABILITIES_ENUM?.PAYMENT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
name: "Assignments",
|
|
||||||
component: <HomeWork />,
|
|
||||||
abilities: ABILITIES_ENUM?.HOMEWORK,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
name: "Class_Schedule",
|
|
||||||
component: <Programme />,
|
|
||||||
abilities: ABILITIES_ENUM?.SESSION,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 9,
|
|
||||||
name: "Curriculum_Follow_up",
|
|
||||||
component: <SessionContent />,
|
|
||||||
abilities: ABILITIES_ENUM?.SESSION_CONTENT,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const ActiveTabs = () => {
|
|
||||||
const { ActiveTab } = useButtonState((state) => state);
|
|
||||||
|
|
||||||
const filteredComponents = EduClassComponents?.filter((component) =>
|
|
||||||
hasAbility(component.abilities, ABILITIES_VALUES_ENUM.INDEX),
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderComponent = () => {
|
|
||||||
const selectedComponent = filteredComponents[Number(ActiveTab)];
|
|
||||||
|
|
||||||
return selectedComponent ? selectedComponent?.component : <></>;
|
|
||||||
};
|
|
||||||
|
|
||||||
return <div>{renderComponent()}</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ActiveTabs;
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import HeaderCardsSection from "../../../Components/EduClass/SingleEduClassHeaderSection";
|
|
||||||
import DeleteModalForm from "../Model/Delete";
|
|
||||||
import SendNotificationModalForm from "../show/model/SendNotificationEduClassModel";
|
|
||||||
|
|
||||||
import ActiveTabs from "./ActiveTable";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { useGetAllEduClass } from "../../../api/eduClass";
|
|
||||||
import { usePage_titleState } from "../../../zustand/PageTitleState";
|
|
||||||
|
|
||||||
const Page = () => {
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const { data: edu_class } = useGetAllEduClass({
|
|
||||||
show: edu_class_id,
|
|
||||||
});
|
|
||||||
const edu_class_name = edu_class?.data?.name || "";
|
|
||||||
const course_name = edu_class?.data?.course?.name || "";
|
|
||||||
const course_and_edu_class_name =
|
|
||||||
" " + course_name + " ( " + edu_class_name + " )";
|
|
||||||
const { set_title } = usePage_titleState();
|
|
||||||
useEffect(() => {
|
|
||||||
set_title(course_and_edu_class_name);
|
|
||||||
}, [course_and_edu_class_name, set_title]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="EduClass">
|
|
||||||
<HeaderCardsSection />
|
|
||||||
<ActiveTabs />
|
|
||||||
<DeleteModalForm />
|
|
||||||
<SendNotificationModalForm />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Page;
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { notes } from "../../../../../../types/App";
|
|
||||||
import { useGetAllRegistrationRecord } from "../../../../../../api/registrationRecord";
|
|
||||||
import registration_recordSelect from "../../../../../../utils/registration_recordSelect";
|
|
||||||
import useSearchQuery from "../../../../../../api/utils/useSearchQuery";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
const [searchQuery] = useSearchQuery("student_name");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
// formik.resetForm();
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const { data: registration_record,isLoading } = useGetAllRegistrationRecord({
|
|
||||||
edu_class_id: edu_class_id,
|
|
||||||
status: "active",
|
|
||||||
name: searchQuery,
|
|
||||||
});
|
|
||||||
// console.log(registration_record,"registration_record");
|
|
||||||
|
|
||||||
const recordSelect = registration_recordSelect(registration_record?.data);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="content" label="content" name="content" />
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="date"
|
|
||||||
label="date"
|
|
||||||
type="Date"
|
|
||||||
name="date"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="type"
|
|
||||||
label="type"
|
|
||||||
type="Select"
|
|
||||||
option={notes}
|
|
||||||
name="type"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="student_name"
|
|
||||||
label="student_name"
|
|
||||||
type="Search"
|
|
||||||
option={recordSelect}
|
|
||||||
name="registration_record_id"
|
|
||||||
searchBy="student_name"
|
|
||||||
isLoading={isLoading}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="attachments"
|
|
||||||
label="attachments"
|
|
||||||
type="MaltyFile"
|
|
||||||
name="attachments"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
import { useAddNote } from "../../../../../../api/note";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddNote();
|
|
||||||
const { set_object_to_edit, object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [isSuccess]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
date: "",
|
|
||||||
attachments: values?.attachments,
|
|
||||||
};
|
|
||||||
dataToSend["date"] = values?.date?.format("YYYY-MM-DD");
|
|
||||||
set_object_to_edit(values);
|
|
||||||
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.NOTES_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.add")} {t("models.note")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
import { useDeleteNote } from "../../../../../../api/note";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeleteNote();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
// console.log(object_to_edit,"object_to_edit");
|
|
||||||
const [t] = useTranslation();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(object_to_edit?.id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
console.log(object_to_edit, "object_to_edit");
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.NOTES_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.delete")} (
|
|
||||||
{object_to_edit?.registration_record?.fullName}){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("header.student_name")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={t("header.student_name")}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
object_to_edit?.registration_record?.fullName !== inputValue
|
|
||||||
? "disabled_button"
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
disabled={
|
|
||||||
object_to_edit?.registration_record?.fullName !== inputValue ||
|
|
||||||
isLoading
|
|
||||||
}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
import { notes } from "../../../../../../types/App";
|
|
||||||
import { useGetAllRegistrationRecord } from "../../../../../../api/registrationRecord";
|
|
||||||
import registration_recordSelect from "../../../../../../utils/registration_recordSelect";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
|
|
||||||
// console.log(registration_record,"registration_record");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="content" label="content" name="content" />
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="date"
|
|
||||||
label="date"
|
|
||||||
type="Date"
|
|
||||||
name="date"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="type"
|
|
||||||
label="type"
|
|
||||||
type="Select"
|
|
||||||
option={notes}
|
|
||||||
name="type"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="attachments"
|
|
||||||
label="attachments"
|
|
||||||
type="MaltyFile"
|
|
||||||
name="attachments"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
import { useUpdateNote } from "../../../../../../api/note";
|
|
||||||
import { areArraysEqual } from "../../../../../../utils/areArraysEqual";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
const { mutate, isSuccess, isLoading } = useUpdateNote();
|
|
||||||
// console.log(object_to_edit, "object_to_edit");
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
const data_to_send = { ...values };
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
formData.append("id", data_to_send?.id);
|
|
||||||
formData.append(
|
|
||||||
"registration_record_id",
|
|
||||||
data_to_send?.registration_record_id,
|
|
||||||
);
|
|
||||||
formData.append("type", data_to_send?.type);
|
|
||||||
formData.append("content", data_to_send?.content);
|
|
||||||
|
|
||||||
if (values?.date) {
|
|
||||||
formData.append("date", data_to_send?.date?.format("YYYY/MM/DD"));
|
|
||||||
}
|
|
||||||
const isEqual = areArraysEqual(
|
|
||||||
values?.attachments,
|
|
||||||
object_to_edit?.attachments,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (areArraysEqual(values?.attachments, object_to_edit?.attachments)) {
|
|
||||||
mutate(formData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (values?.attachments && Array.isArray(values?.attachments)) {
|
|
||||||
values.attachments.forEach((attachment: any, index: number) => {
|
|
||||||
if (typeof attachment === "object" && attachment?.id) {
|
|
||||||
formData.append(`attachments[${index}]`, attachment.id);
|
|
||||||
} else {
|
|
||||||
formData.append(`attachments[${index}]`, attachment);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (values?.attachments === null) {
|
|
||||||
formData.append("attachments", [] as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutate(formData);
|
|
||||||
};
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.NOTES_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
{object_to_edit && (
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.edit")} {t("models.note")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.edit")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
// console.log(objectToEdit,"objectToEdit");
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? null,
|
|
||||||
registration_record_id:
|
|
||||||
objectToEdit?.registration_record?.id ??
|
|
||||||
objectToEdit?.registration_record_id ??
|
|
||||||
null,
|
|
||||||
type: objectToEdit?.type ?? null,
|
|
||||||
content: objectToEdit?.content ?? null,
|
|
||||||
date: objectToEdit?.date
|
|
||||||
? dayjs(objectToEdit?.date, "YYYY/MM/DD")
|
|
||||||
: dayjs(Date()),
|
|
||||||
attachments: objectToEdit?.attachments ?? null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
registration_record_id: Yup.string().required("validation.required"),
|
|
||||||
type: Yup.string().required("validation.required"),
|
|
||||||
content: Yup.string().required("validation.required"),
|
|
||||||
date: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
import React, { useState, useRef, useEffect } from "react";
|
|
||||||
import { IoMdArrowDropdown } from "react-icons/io";
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
interface Option {
|
|
||||||
label: string;
|
|
||||||
value: string | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
options: Option[];
|
|
||||||
placeholder: string;
|
|
||||||
onChange?: (option: Option) => void;
|
|
||||||
searchBy?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomSelect: React.FC<Props> = ({
|
|
||||||
options,
|
|
||||||
placeholder,
|
|
||||||
onChange,
|
|
||||||
searchBy = "name",
|
|
||||||
}) => {
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
|
|
||||||
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
|
||||||
const node = useRef<HTMLDivElement>(null);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const location = useLocation();
|
|
||||||
const { param_to_send, set_param_to_send } = useObjectToEdit();
|
|
||||||
// console.log(param_to_send);
|
|
||||||
|
|
||||||
const toggleDropdown = () => {
|
|
||||||
setIsOpen(!isOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOptionClick = (option: Option) => {
|
|
||||||
setSelectedOption(option);
|
|
||||||
// console.log(option);
|
|
||||||
|
|
||||||
// console.log(`selected ${option?.value}`);
|
|
||||||
const newObj = { ...param_to_send };
|
|
||||||
newObj.state = option?.value;
|
|
||||||
set_param_to_send(newObj);
|
|
||||||
navigate(`${location.pathname}?type=${option?.value}`);
|
|
||||||
|
|
||||||
setIsOpen(false);
|
|
||||||
setSearchTerm("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const filteredOptions = options.filter((option) =>
|
|
||||||
option.label.toLowerCase().includes(searchTerm.toLowerCase()),
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Add event listener when component mounts
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
|
||||||
// Remove event listener when component unmounts
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("mousedown", handleClickOutside);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
|
||||||
// Close the dropdown if clicked outside the component
|
|
||||||
if (node.current && !node.current.contains(event.target as Node)) {
|
|
||||||
setIsOpen(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className={`custom-select ${isOpen ? "open" : ""}`} ref={node}>
|
|
||||||
<div className="select-header" onClick={toggleDropdown}>
|
|
||||||
<IoMdArrowDropdown
|
|
||||||
className={`custom_select_icon ${isOpen ? "open" : ""}`}
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder={selectedOption ? selectedOption.label : placeholder}
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
|
||||||
onFocus={() => setIsOpen(true)}
|
|
||||||
className="search-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{(isOpen || (searchTerm !== "" && filteredOptions.length > 0)) && (
|
|
||||||
<div className="options">
|
|
||||||
<div className="options-list">
|
|
||||||
{filteredOptions.map((option) => (
|
|
||||||
<div
|
|
||||||
key={option.value}
|
|
||||||
className="option"
|
|
||||||
onClick={() => handleOptionClick(option)}
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CustomSelect;
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import SearchField from "../../../../../Components/DataTable/SearchField";
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
|
||||||
import CustomSelect from "./Select/CustomSelect";
|
|
||||||
import EditHomeWorkModel from "./Model/EditModel";
|
|
||||||
import AddHomeWorkModel from "./Model/AddModel";
|
|
||||||
import DeleteHomeWorkModel from "./Model/Delete";
|
|
||||||
|
|
||||||
import type { DatePickerProps } from "antd";
|
|
||||||
import { DatePicker } from "antd";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import { notes } from "../../../../../types/App";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { translateOptions } from "../../../../../utils/translatedOptions";
|
|
||||||
import CustomDatePicker from "../../../../../Components/Ui/Custom/CustomDatePicker";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
const translateArray = translateOptions(
|
|
||||||
[...notes, { label: t("select.Note.all_note"), value: "" }],
|
|
||||||
t,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header>
|
|
||||||
<h6> {t("header.classroom_behavior_of_students")}</h6>
|
|
||||||
|
|
||||||
<div className="Selects">
|
|
||||||
<CustomSelect
|
|
||||||
options={translateArray}
|
|
||||||
placeholder={t("select.Note.all_note")}
|
|
||||||
searchBy="type"
|
|
||||||
/>
|
|
||||||
<CustomDatePicker/>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<SearchField
|
|
||||||
searchBy="student_name_note"
|
|
||||||
placeholder={t("practical.search_here")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<AddHomeWorkModel />
|
|
||||||
<EditHomeWorkModel />
|
|
||||||
<DeleteHomeWorkModel />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import { useColumns } from ".";
|
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import { useGetAllNote } from "../../../../../api/note";
|
|
||||||
import DataTable from "../../../../../Layout/Dashboard/Table/DataTable";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const [searchQuery, setSearchQuery] = React.useState<string>("");
|
|
||||||
const [searchQueryType, setSearchQueryType] = React.useState<string>("");
|
|
||||||
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
const { param_to_send } = useObjectToEdit();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const searchParams = new URLSearchParams(location?.search);
|
|
||||||
setSearchQuery(searchParams?.get("student_name_note") || "");
|
|
||||||
setSearchQueryType(searchParams?.get("type") || "");
|
|
||||||
}, [location, searchQuery, searchQueryType]);
|
|
||||||
|
|
||||||
const response = useGetAllNote({
|
|
||||||
student_name: searchQuery,
|
|
||||||
// [param_to_send?.state ?? "all"] : ,
|
|
||||||
date: param_to_send?.date,
|
|
||||||
notType: "attendence_note",
|
|
||||||
type: searchQueryType,
|
|
||||||
pagination: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { Table } from "antd";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import {
|
|
||||||
PaginationOptions,
|
|
||||||
useTableOnChange,
|
|
||||||
} from "../../../../../Layout/Dashboard/PaginationOptions";
|
|
||||||
import { useAddKeyToData } from "../../../../../Hooks/useAddKeyToData";
|
|
||||||
|
|
||||||
export {
|
|
||||||
Table,
|
|
||||||
useColumns,
|
|
||||||
PaginationOptions,
|
|
||||||
useAddKeyToData,
|
|
||||||
useTableOnChange,
|
|
||||||
};
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
import { Space, TableColumnsType, Tooltip } from "antd";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
|
|
||||||
import useModalHandler from "../../../../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import { RiDeleteBin6Fill } from "react-icons/ri";
|
|
||||||
import { MdOutlineEdit } from "react-icons/md";
|
|
||||||
import { notes } from "../../../../../types/App";
|
|
||||||
import { findLabelByValue } from "../../../../../utils/findLabelByValue";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { hasAbility } from "../../../../../utils/hasAbility";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../../../enums/abilities";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
|
|
||||||
const { set_object_to_edit } = useObjectToEdit((state) => state);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const handelDelete = (data: any) => {
|
|
||||||
set_object_to_edit(data);
|
|
||||||
handel_open_model(ModalEnum?.NOTES_DELETE);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
handel_open_model(ModalEnum?.NOTES_EDIT);
|
|
||||||
};
|
|
||||||
|
|
||||||
const can_edit_note = hasAbility(
|
|
||||||
ABILITIES_ENUM.NOTE,
|
|
||||||
ABILITIES_VALUES_ENUM.UPDATE,
|
|
||||||
);
|
|
||||||
const can_delete_note = hasAbility(
|
|
||||||
ABILITIES_ENUM.NOTE,
|
|
||||||
ABILITIES_VALUES_ENUM.DELETE,
|
|
||||||
);
|
|
||||||
const can_add_note = hasAbility(
|
|
||||||
ABILITIES_ENUM.NOTE,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns: TableColumnsType<any> = [
|
|
||||||
{
|
|
||||||
title: t("columns.id"),
|
|
||||||
dataIndex: "id",
|
|
||||||
key: "id",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.id,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: `${t("columns.student_name")}`,
|
|
||||||
dataIndex: "content",
|
|
||||||
key: "content",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.registration_record?.student?.full_name,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: t("columns.details"),
|
|
||||||
dataIndex: "content",
|
|
||||||
key: "content",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.content,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: t("columns.type"),
|
|
||||||
dataIndex: "type",
|
|
||||||
key: "type",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => {
|
|
||||||
const value = findLabelByValue(notes, record?.type);
|
|
||||||
return <>{t(`${value}`)}</>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: can_add_note ? (
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.NOTES_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.note")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
),
|
|
||||||
key: "actions",
|
|
||||||
align: "end",
|
|
||||||
className: "custom_add_button_column",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space size="middle" className={className}>
|
|
||||||
{can_edit_note && (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("practical.edit")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<span onClick={() => handleEdit(record)}>
|
|
||||||
<MdOutlineEdit
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{can_delete_note && (
|
|
||||||
<RiDeleteBin6Fill
|
|
||||||
onClick={() => handelDelete(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#C11313" }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { Payments } from "../../../../../../types/App";
|
|
||||||
import { useGetAllRegistrationRecord } from "../../../../../../api/registrationRecord";
|
|
||||||
import registration_recordSelect from "../../../../../../utils/registration_recordSelect";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import useSearchQuery from "../../../../../../api/utils/useSearchQuery";
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
const [searchQuery] = useSearchQuery("student_name");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
// formik.resetForm();
|
|
||||||
}
|
|
||||||
if (isOpen === "isSuccess") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen]);
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
|
|
||||||
const { data: registration_record,isLoading } = useGetAllRegistrationRecord({
|
|
||||||
edu_class_id: edu_class_id,
|
|
||||||
status: "active",
|
|
||||||
name: searchQuery,
|
|
||||||
});
|
|
||||||
// console.log(registration_record,"registration_record");
|
|
||||||
|
|
||||||
const recordSelect = registration_recordSelect(registration_record?.data);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="details" label="details" name="details" />
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="date"
|
|
||||||
label="date"
|
|
||||||
type="Date"
|
|
||||||
name="date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="receipt_number"
|
|
||||||
label="receipt_number"
|
|
||||||
name="receipt_number"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="payment_type"
|
|
||||||
label="payment_type"
|
|
||||||
type="Select"
|
|
||||||
option={Payments}
|
|
||||||
name="type"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="value"
|
|
||||||
label="value"
|
|
||||||
type="NumberFormate"
|
|
||||||
name="value"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="student_name"
|
|
||||||
label="student_name"
|
|
||||||
type="Search"
|
|
||||||
option={recordSelect}
|
|
||||||
name="registration_record_id"
|
|
||||||
searchBy="student_name"
|
|
||||||
isLoading={isLoading}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Add";
|
|
||||||
import { getInitialValues, getValidationSchemaADD } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
import { useAddPayment } from "../../../../../../api/payment";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { mutate, isSuccess, isLoading } = useAddPayment();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("isSuccess");
|
|
||||||
set_object_to_edit({});
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess, set_object_to_edit]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
date: "",
|
|
||||||
};
|
|
||||||
dataToSend["date"] = values?.date?.format("YYYY-MM-DD");
|
|
||||||
set_object_to_edit(values);
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.PAYMENT_ADD}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchemaADD}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.add")} {t("models.payment")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}> {t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.add")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Input, Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
import { useDeletePayment } from "../../../../../../api/payment";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const { mutate, isLoading, isSuccess } = useDeletePayment();
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit();
|
|
||||||
|
|
||||||
// console.log(object_to_edit,"object_to_edit");
|
|
||||||
const [t] = useTranslation();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
setInputValue("");
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
mutate({
|
|
||||||
id: Number(object_to_edit?.id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setInputValue("");
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
// Step 2: Handle changes to the input field
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.PAYMENT_DELETE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.delete")} {object_to_edit?.details}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">
|
|
||||||
{t("practical.to_confirm_deletion_please_re_enter")}{" "}
|
|
||||||
{t("input.details")} {t("models.payment")}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
size="large"
|
|
||||||
type="text"
|
|
||||||
placeholder={`${t("practical.enter")} ${t("input.details")} ${t("models.payment")} `}
|
|
||||||
value={inputValue}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.cancel")}</div>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
object_to_edit?.details !== inputValue ? "disabled_button" : ""
|
|
||||||
}
|
|
||||||
disabled={object_to_edit?.details !== inputValue || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.delete")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { Payments } from "../../../../../../types/App";
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
formik.resetForm();
|
|
||||||
}
|
|
||||||
}, [isOpen, formik]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField placeholder="details" label="details" name="details" />
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="date"
|
|
||||||
label="date"
|
|
||||||
type="Date"
|
|
||||||
name="date"
|
|
||||||
/>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="receipt_number"
|
|
||||||
label="receipt_number"
|
|
||||||
name="receipt_number"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="payment_type"
|
|
||||||
label="payment_type"
|
|
||||||
type="Select"
|
|
||||||
option={Payments}
|
|
||||||
name="type"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ValidationField
|
|
||||||
placeholder="value"
|
|
||||||
label="value"
|
|
||||||
type="NumberFormate"
|
|
||||||
name="value"
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
import { useUpdatePayment } from "../../../../../../api/payment";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, set_object_to_edit } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
const { mutate, isSuccess, isLoading } = useUpdatePayment();
|
|
||||||
// console.log(object_to_edit, "object_to_edit");
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
console.log(values, "values");
|
|
||||||
|
|
||||||
const dataToSend = {
|
|
||||||
...values,
|
|
||||||
date: "",
|
|
||||||
};
|
|
||||||
dataToSend["date"] = values?.date?.format("YYYY-MM-DD");
|
|
||||||
delete dataToSend["registration_record_id"];
|
|
||||||
|
|
||||||
mutate(dataToSend);
|
|
||||||
};
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
set_object_to_edit({});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
}
|
|
||||||
}, [setIsOpen, isSuccess]);
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.PAYMENT_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
{object_to_edit && (
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{" "}
|
|
||||||
{t("practical.edit")} {t("practical.details")} {t("models.payment")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button disabled={isLoading} type="submit">
|
|
||||||
{t("practical.edit")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { Payments } from "../../../../../../enums/Validation";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
console.log(objectToEdit, "objectToEdit");
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? null,
|
|
||||||
registration_record_id:
|
|
||||||
objectToEdit?.registration_record?.id ??
|
|
||||||
objectToEdit?.registration_record_id ??
|
|
||||||
null,
|
|
||||||
type: objectToEdit?.type ?? null,
|
|
||||||
value: objectToEdit?.value ?? null,
|
|
||||||
details: objectToEdit?.details ?? null,
|
|
||||||
receipt_number: objectToEdit?.receipt_number ?? null,
|
|
||||||
date: objectToEdit?.date
|
|
||||||
? dayjs(objectToEdit?.date, "YYYY/MM/DD")
|
|
||||||
: dayjs(Date()),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
type: Yup.string().required("validation.type_required"),
|
|
||||||
value: Yup.number()
|
|
||||||
.required("required")
|
|
||||||
.max(Payments?.MAX_VALUE, `validation.value_must_be_less_than_900000`)
|
|
||||||
.typeError("validation.Must_be_a_number"),
|
|
||||||
details: Yup.string().required("validation.required"),
|
|
||||||
receipt_number: Yup.string().required("validation.required"),
|
|
||||||
date: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchemaADD = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
registration_record_id: Yup.string().required("validation.required"),
|
|
||||||
type: Yup.string().required("validation.type_required"),
|
|
||||||
value: Yup.number()
|
|
||||||
.required("validation.required")
|
|
||||||
.max(Payments?.MAX_VALUE, `.value_must_be_less_than_900000`)
|
|
||||||
.typeError("validation.Must_be_a_number"),
|
|
||||||
details: Yup.string().required("validation.required"),
|
|
||||||
receipt_number: Yup.string().required("validation.required"),
|
|
||||||
date: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
import React, { useState, useRef, useEffect } from "react";
|
|
||||||
import { IoMdArrowDropdown } from "react-icons/io";
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
interface Option {
|
|
||||||
label: string;
|
|
||||||
value: string | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
options: Option[];
|
|
||||||
placeholder: string;
|
|
||||||
onChange?: (option: Option) => void;
|
|
||||||
searchBy?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomSelect: React.FC<Props> = ({
|
|
||||||
options,
|
|
||||||
placeholder,
|
|
||||||
onChange,
|
|
||||||
searchBy = "name",
|
|
||||||
}) => {
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
|
|
||||||
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
|
||||||
const node = useRef<HTMLDivElement>(null);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const location = useLocation();
|
|
||||||
const { param_to_send, set_param_to_send } = useObjectToEdit();
|
|
||||||
// console.log(param_to_send);
|
|
||||||
|
|
||||||
const toggleDropdown = () => {
|
|
||||||
setIsOpen(!isOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOptionClick = (option: Option) => {
|
|
||||||
setSelectedOption(option);
|
|
||||||
// console.log(option);
|
|
||||||
|
|
||||||
// console.log(`selected ${option?.value}`);
|
|
||||||
const newObj = { ...param_to_send };
|
|
||||||
newObj.state = option?.value;
|
|
||||||
set_param_to_send(newObj);
|
|
||||||
navigate(`${location.pathname}?type=${option?.value}`);
|
|
||||||
|
|
||||||
setIsOpen(false);
|
|
||||||
setSearchTerm("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const filteredOptions = options.filter((option) =>
|
|
||||||
option.label.toLowerCase().includes(searchTerm.toLowerCase()),
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Add event listener when component mounts
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
|
||||||
// Remove event listener when component unmounts
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("mousedown", handleClickOutside);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
|
||||||
// Close the dropdown if clicked outside the component
|
|
||||||
if (node.current && !node.current.contains(event.target as Node)) {
|
|
||||||
setIsOpen(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className={`custom-select ${isOpen ? "open" : ""}`} ref={node}>
|
|
||||||
<div className="select-header" onClick={toggleDropdown}>
|
|
||||||
<IoMdArrowDropdown
|
|
||||||
className={`custom_select_icon ${isOpen ? "open" : ""}`}
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder={selectedOption ? selectedOption.label : placeholder}
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
|
||||||
onFocus={() => setIsOpen(true)}
|
|
||||||
className="search-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{(isOpen || (searchTerm !== "" && filteredOptions.length > 0)) && (
|
|
||||||
<div className="options">
|
|
||||||
<div className="options-list">
|
|
||||||
{filteredOptions.map((option) => (
|
|
||||||
<div
|
|
||||||
key={option.value}
|
|
||||||
className="option"
|
|
||||||
onClick={() => handleOptionClick(option)}
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CustomSelect;
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import SearchField from "../../../../../Components/DataTable/SearchField";
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
|
||||||
import CustomSelect from "./Select/CustomSelect";
|
|
||||||
import EditHomeWorkModel from "./Model/EditModel";
|
|
||||||
import AddHomeWorkModel from "./Model/AddModel";
|
|
||||||
import DeleteHomeWorkModel from "./Model/Delete";
|
|
||||||
|
|
||||||
import type { DatePickerProps } from "antd";
|
|
||||||
import { DatePicker } from "antd";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import { Payments } from "../../../../../types/App";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { translateOptions } from "../../../../../utils/translatedOptions";
|
|
||||||
import CustomDatePicker from "../../../../../Components/Ui/Custom/CustomDatePicker";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
|
|
||||||
const translateArray = translateOptions(
|
|
||||||
[...Payments, { label: t("select.Payments.all_payment"), value: "" }],
|
|
||||||
t,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header>
|
|
||||||
<h6>
|
|
||||||
{t("models.payment")} {t("models.students")}
|
|
||||||
</h6>
|
|
||||||
<div className="Selects">
|
|
||||||
<CustomSelect
|
|
||||||
options={translateArray}
|
|
||||||
placeholder={t("select.Payments.all_payment")}
|
|
||||||
searchBy="type"
|
|
||||||
/>
|
|
||||||
<CustomDatePicker/>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<SearchField
|
|
||||||
searchBy="student_name_payment"
|
|
||||||
placeholder={t("practical.search_here")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<AddHomeWorkModel />
|
|
||||||
<EditHomeWorkModel />
|
|
||||||
<DeleteHomeWorkModel />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import { useColumns } from ".";
|
|
||||||
import { useLocation, useParams } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import { useGetAllPayment } from "../../../../../api/payment";
|
|
||||||
import DataTable from "../../../../../Layout/Dashboard/Table/DataTable";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const [searchQuery, setSearchQuery] = React.useState<string>("");
|
|
||||||
const [searchQueryType, setSearchQueryType] = React.useState<string>("");
|
|
||||||
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const searchParams = new URLSearchParams(location?.search);
|
|
||||||
setSearchQuery(searchParams?.get("student_name_payment") || "");
|
|
||||||
setSearchQueryType(searchParams?.get("type") || "");
|
|
||||||
}, [location, searchQuery, searchQueryType]);
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
|
|
||||||
const response = useGetAllPayment({
|
|
||||||
student_name: searchQuery,
|
|
||||||
pagination: true,
|
|
||||||
edu_class_id: edu_class_id,
|
|
||||||
type: searchQueryType,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { Table } from "antd";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import {
|
|
||||||
PaginationOptions,
|
|
||||||
useTableOnChange,
|
|
||||||
} from "../../../../../Layout/Dashboard/PaginationOptions";
|
|
||||||
import { useAddKeyToData } from "../../../../../Hooks/useAddKeyToData";
|
|
||||||
|
|
||||||
export {
|
|
||||||
Table,
|
|
||||||
useColumns,
|
|
||||||
PaginationOptions,
|
|
||||||
useAddKeyToData,
|
|
||||||
useTableOnChange,
|
|
||||||
};
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
import { Space, TableColumnsType, Tooltip } from "antd";
|
|
||||||
import { Payment } from "../../../../../types/Item";
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
|
|
||||||
import useModalHandler from "../../../../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import { RiDeleteBin6Fill } from "react-icons/ri";
|
|
||||||
import { MdOutlineEdit } from "react-icons/md";
|
|
||||||
import { Payments } from "../../../../../types/App";
|
|
||||||
import { findLabelByValue } from "../../../../../utils/findLabelByValue";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../../../../utils/hasAbility";
|
|
||||||
import { formatNumber } from "../../../../../utils/formatNumber";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
|
|
||||||
const { set_object_to_edit } = useObjectToEdit((state) => state);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const handelDelete = (data: any) => {
|
|
||||||
set_object_to_edit(data);
|
|
||||||
handel_open_model(ModalEnum?.PAYMENT_DELETE);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
set_object_to_edit(record);
|
|
||||||
handel_open_model(ModalEnum?.PAYMENT_EDIT);
|
|
||||||
};
|
|
||||||
|
|
||||||
const can_edit_payment = hasAbility(
|
|
||||||
ABILITIES_ENUM.PAYMENT,
|
|
||||||
ABILITIES_VALUES_ENUM.UPDATE,
|
|
||||||
);
|
|
||||||
const can_delete_payment = hasAbility(
|
|
||||||
ABILITIES_ENUM.PAYMENT,
|
|
||||||
ABILITIES_VALUES_ENUM.DELETE,
|
|
||||||
);
|
|
||||||
const can_add_payment = hasAbility(
|
|
||||||
ABILITIES_ENUM.PAYMENT,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns: TableColumnsType<Payment> = [
|
|
||||||
{
|
|
||||||
title: t("id"),
|
|
||||||
dataIndex: "id",
|
|
||||||
key: "id",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.id,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: `${t("columns.student_name")}`,
|
|
||||||
dataIndex: "date",
|
|
||||||
key: "date",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.student?.full_name,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.date"),
|
|
||||||
dataIndex: "date",
|
|
||||||
key: "date",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.date,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: t("columns.details"),
|
|
||||||
dataIndex: "details",
|
|
||||||
key: "details",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.details,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.receipt_number"),
|
|
||||||
dataIndex: "receipt_number",
|
|
||||||
key: "receipt_number",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => record?.receipt_number,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.payment_type"),
|
|
||||||
dataIndex: "type",
|
|
||||||
key: "type",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => {
|
|
||||||
const value = findLabelByValue(Payments, record?.type);
|
|
||||||
return <>{t(`${value}`)}</>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.value"),
|
|
||||||
dataIndex: "value",
|
|
||||||
key: "value",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => {
|
|
||||||
const formattedNumber = formatNumber(record?.value);
|
|
||||||
|
|
||||||
return formattedNumber;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: can_add_payment ? (
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.PAYMENT_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.payment")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
),
|
|
||||||
key: "actions",
|
|
||||||
align: "end",
|
|
||||||
className: "custom_add_button_column",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space size="middle" className={className}>
|
|
||||||
{can_edit_payment && (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={t("practical.edit")}
|
|
||||||
color="#E0E0E0"
|
|
||||||
>
|
|
||||||
<span onClick={() => handleEdit(record)}>
|
|
||||||
<MdOutlineEdit
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{can_delete_payment && (
|
|
||||||
<RiDeleteBin6Fill
|
|
||||||
onClick={() => handelDelete(record)}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#C11313" }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
// import Table from "./TestTableHeader";
|
|
||||||
|
|
||||||
import { FaPlus } from "react-icons/fa";
|
|
||||||
import SearchField from "../../../../../Components/DataTable/SearchField";
|
|
||||||
import useModalHandler from "../../../../../utils/useModalHandler";
|
|
||||||
import { ModalEnum } from "../../../../../enums/Model";
|
|
||||||
import { usePage_titleState } from "../../../../../zustand/PageTitleState";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import StudentModalForm from "../../../../../Components/EduClass/student/Add/Model/Modal";
|
|
||||||
|
|
||||||
import TransformStudent from "./model/TransformStudent";
|
|
||||||
import MoveStudent from "./model/MoveStudent";
|
|
||||||
import { hasAbility } from "../../../../../utils/hasAbility";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../../../enums/abilities";
|
|
||||||
const TableHeader = () => {
|
|
||||||
const { handel_open_model } = useModalHandler();
|
|
||||||
const { title } = usePage_titleState((state) => state);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
const can_use_add_ability = hasAbility(
|
|
||||||
ABILITIES_ENUM.STUDENT,
|
|
||||||
ABILITIES_VALUES_ENUM.STORE,
|
|
||||||
);
|
|
||||||
const can_use_import_ability = hasAbility(
|
|
||||||
ABILITIES_ENUM.STUDENT,
|
|
||||||
ABILITIES_VALUES_ENUM.IMPORT_STUDENTS,
|
|
||||||
);
|
|
||||||
const can_use_move_ability = hasAbility(
|
|
||||||
ABILITIES_ENUM.STUDENT,
|
|
||||||
ABILITIES_VALUES_ENUM.MOVE_STUDENTS,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header>
|
|
||||||
<h6>
|
|
||||||
{t("header.register_students")}
|
|
||||||
{title}
|
|
||||||
</h6>
|
|
||||||
<div className="Selects">
|
|
||||||
{can_use_import_ability && (
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.STUDENT_TRANSFORM)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("header.import_students")}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{can_use_move_ability && (
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.STUDENT_MOVE)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("header.move_student")}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{can_use_add_ability && (
|
|
||||||
<button
|
|
||||||
onClick={() => handel_open_model(ModalEnum?.STUDENT_ADD)}
|
|
||||||
className="add_button"
|
|
||||||
>
|
|
||||||
{t("practical.add")} {t("models.student")} <FaPlus />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<SearchField searchBy="name" placeholder={t("practical.search_here")} />
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
<StudentModalForm />
|
|
||||||
<MoveStudent />
|
|
||||||
<TransformStudent />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
import { useAddKeyToData, useColumns, Table } from ".";
|
|
||||||
import Loading from "../../../../../Components/DataState/Loading";
|
|
||||||
import EmptyData from "../../../../../Components/DataState/EmptyData";
|
|
||||||
import { useLocation, useParams } from "react-router-dom";
|
|
||||||
import { Student } from "../../../../../types/Item";
|
|
||||||
import React from "react";
|
|
||||||
import { useGetAllStudent } from "../../../../../api/student";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import usePagination from "../../../../../Layout/Dashboard/usePagination";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const [searchQuery, setSearchQuery] = React.useState<string>("");
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
/// first_name
|
|
||||||
React.useEffect(() => {
|
|
||||||
const searchParams = new URLSearchParams(location?.search);
|
|
||||||
setSearchQuery(searchParams?.get("name") || "");
|
|
||||||
// console.log(searchQuery,"searchQuery");
|
|
||||||
}, [location, searchQuery]);
|
|
||||||
|
|
||||||
const { data, isLoading } = useGetAllStudent({
|
|
||||||
name: searchQuery,
|
|
||||||
edu_class_id: edu_class_id,
|
|
||||||
pagination: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const students: Student[] = data?.data || [];
|
|
||||||
const dataSource = useAddKeyToData(students);
|
|
||||||
const columns = useColumns();
|
|
||||||
const { set_object_to_edit, set_object_ids } = useObjectToEdit(
|
|
||||||
(state) => state,
|
|
||||||
);
|
|
||||||
|
|
||||||
const getRowClassName = (record: any, index: number): string => {
|
|
||||||
return index % 2 === 0 ? "even-row" : "odd-row";
|
|
||||||
};
|
|
||||||
|
|
||||||
const rowSelection = {
|
|
||||||
onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
|
|
||||||
set_object_ids(selectedRows);
|
|
||||||
},
|
|
||||||
getCheckboxProps: (record: any) => ({
|
|
||||||
disabled: record.name === "Disabled User",
|
|
||||||
name: record.name,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const { pagination, handlePageChange } = usePagination(data);
|
|
||||||
|
|
||||||
function filterActiveRecords(dataSource: Student[]) {
|
|
||||||
return dataSource?.filter(
|
|
||||||
(item: Student) => item?.registration_record_status === "active",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<Table<Student>
|
|
||||||
columns={columns}
|
|
||||||
dataSource={filterActiveRecords(dataSource)}
|
|
||||||
className="DataTable"
|
|
||||||
rowClassName={(record, index) => getRowClassName(record, index)}
|
|
||||||
loading={{
|
|
||||||
spinning: isLoading,
|
|
||||||
indicator: <Loading />,
|
|
||||||
size: "large",
|
|
||||||
}}
|
|
||||||
locale={{
|
|
||||||
emptyText: (
|
|
||||||
<EmptyData
|
|
||||||
loading={isLoading}
|
|
||||||
header={t("Table.header")}
|
|
||||||
info={t("Table.info")}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
pagination={{
|
|
||||||
...pagination,
|
|
||||||
onChange: handlePageChange,
|
|
||||||
}}
|
|
||||||
rowSelection={{
|
|
||||||
type: "checkbox",
|
|
||||||
...rowSelection,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? 0,
|
|
||||||
name: objectToEdit?.name ?? "",
|
|
||||||
description: objectToEdit?.description ?? "",
|
|
||||||
categories_id:
|
|
||||||
{
|
|
||||||
label: objectToEdit?.categories?.name,
|
|
||||||
value: objectToEdit?.categories?.id,
|
|
||||||
} ?? "",
|
|
||||||
price: objectToEdit?.price ?? null,
|
|
||||||
is_published: objectToEdit?.is_published ?? false,
|
|
||||||
image: objectToEdit?.image ?? "",
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({
|
|
||||||
name: Yup.string().required("validation.required"),
|
|
||||||
description: Yup.string().required("validation.required"),
|
|
||||||
categories_id: Yup.string().required("validation.required"),
|
|
||||||
price: Yup.number().required("validation.required"),
|
|
||||||
is_published: Yup.boolean().required("validation.required"),
|
|
||||||
image: Yup.string().required("validation.required"),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { Table } from "antd";
|
|
||||||
import { useColumns } from "./useTableColumns";
|
|
||||||
import {
|
|
||||||
PaginationOptions,
|
|
||||||
useTableOnChange,
|
|
||||||
} from "../../../../../Layout/Dashboard/PaginationOptions";
|
|
||||||
import { useAddKeyToData } from "../../../../../Hooks/useAddKeyToData";
|
|
||||||
|
|
||||||
export {
|
|
||||||
Table,
|
|
||||||
useColumns,
|
|
||||||
PaginationOptions,
|
|
||||||
useAddKeyToData,
|
|
||||||
useTableOnChange,
|
|
||||||
};
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Modal, Select, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useGetAllEduClass } from "../../../../../../api/eduClass";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import useFormatDataToSelect from "../../../../../../utils/useFormatDataToSelect";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
import { useMoveStudent } from "../../../../../../api/student";
|
|
||||||
import { useQueryClient } from "react-query";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [selectValue, setSelectValue] = useState<any | null>(null);
|
|
||||||
|
|
||||||
const { mutate, isSuccess, isLoading } = useMoveStudent();
|
|
||||||
const { object_ids } = useObjectToEdit((state) => state);
|
|
||||||
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const { data } = useGetAllEduClass(
|
|
||||||
{
|
|
||||||
all: "all",
|
|
||||||
},
|
|
||||||
{ enabled: isOpen === ModalEnum?.STUDENT_MOVE },
|
|
||||||
);
|
|
||||||
|
|
||||||
const eduClassData: any[] = data?.data || [];
|
|
||||||
|
|
||||||
const filteredEduClasses: any[] =
|
|
||||||
eduClassData?.length > 0
|
|
||||||
? eduClassData?.filter(
|
|
||||||
(eduClass: any) => eduClass?.id !== Number(edu_class_id),
|
|
||||||
)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const formattedEduClasses: any = useFormatDataToSelect(filteredEduClasses);
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
queryClient.invalidateQueries(["student"]);
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
const registraion_records = object_ids?.map((item: any) => {
|
|
||||||
return item?.registration_record_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
if (object_ids?.length === 0) {
|
|
||||||
toast.error(t("validation.please_select_students"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (selectValue === null) {
|
|
||||||
toast.error(t("validation.please_fill_in_all_the_fields"));
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
mutate({
|
|
||||||
edu_class_id: selectValue,
|
|
||||||
registraion_records: registraion_records,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeSelect = (value: any | null) => {
|
|
||||||
setSelectValue(value);
|
|
||||||
};
|
|
||||||
const [t] = useTranslation();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.STUDENT_MOVE}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.move")} {t("models.students")}{" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label>
|
|
||||||
{t("input.name")} {t("models.education_class")}{" "}
|
|
||||||
</label>
|
|
||||||
<Select
|
|
||||||
size="large"
|
|
||||||
placeholder={`${t("input.name")} ${t("models.education_class")}`}
|
|
||||||
value={selectValue}
|
|
||||||
options={formattedEduClasses}
|
|
||||||
onChange={handleChangeSelect}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button
|
|
||||||
disabled={selectValue === null || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.move")}
|
|
||||||
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,141 +0,0 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Modal, Select, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useGetAllEduClass } from "../../../../../../api/eduClass";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import useFormatDataToSelect from "../../../../../../utils/useFormatDataToSelect";
|
|
||||||
import { useImportStudent } from "../../../../../../api/student";
|
|
||||||
import useFormatAuthDataToSelect from "../../../../../../utils/useFormatAuthDataToSelect";
|
|
||||||
import { useGetAllCycle } from "../../../../../../api/cycle";
|
|
||||||
import { useQueryClient } from "react-query";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { getLocalStorage } from "../../../../../../utils/LocalStorage";
|
|
||||||
import { CYCLE_OBJECT_KEY } from "../../../../../../config/AppKey";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const [selectValue, setSelectValue] = useState<any | null>(null);
|
|
||||||
const [SelectCycleValue, setSelectCycleValue] = useState<any | null>(null);
|
|
||||||
|
|
||||||
const { mutate, isSuccess, isLoading } = useImportStudent();
|
|
||||||
const cycle_id = getLocalStorage(CYCLE_OBJECT_KEY)?.id;
|
|
||||||
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
|
|
||||||
const { data } = useGetAllEduClass(
|
|
||||||
{
|
|
||||||
cycle_id: SelectCycleValue,
|
|
||||||
},
|
|
||||||
{ enabled: !!SelectCycleValue },
|
|
||||||
);
|
|
||||||
const eduClassData: any[] = data?.data || [];
|
|
||||||
|
|
||||||
const formattedEduClasses: any = useFormatDataToSelect(eduClassData);
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
setIsOpen("");
|
|
||||||
queryClient.invalidateQueries(["student"]);
|
|
||||||
}
|
|
||||||
}, [isSuccess, setIsOpen]);
|
|
||||||
|
|
||||||
const { data: CycleData } = useGetAllCycle(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
enabled: isOpen === ModalEnum?.STUDENT_TRANSFORM,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const filteredCycle: any[] =
|
|
||||||
CycleData?.data?.length > 0
|
|
||||||
? CycleData?.data?.filter((cycle: any) => cycle?.id !== Number(cycle_id))
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const BranchCycleData = useFormatAuthDataToSelect(filteredCycle);
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
const handleSubmit = () => {
|
|
||||||
if (selectValue === null) {
|
|
||||||
toast.error(t("validation.please_fill_in_all_the_fields"));
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
mutate({
|
|
||||||
// edu_class_id:edu_class_id,
|
|
||||||
// registraion_records:registraion_records
|
|
||||||
cycle_id: SelectCycleValue,
|
|
||||||
new_edu_class_id: selectValue,
|
|
||||||
old_edu_class_id: edu_class_id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeSelect = (value: any | null) => {
|
|
||||||
setSelectValue(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChangeCycleSelect = (value: any | null) => {
|
|
||||||
setSelectCycleValue(value);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm "
|
|
||||||
centered
|
|
||||||
width={"40vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.STUDENT_TRANSFORM}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<header>{t("practical.export_students")} </header>
|
|
||||||
<main className="main_modal">
|
|
||||||
<div className="ValidationField w-100 mb-5">
|
|
||||||
<label className="text ">{t("input.academic_year")} </label>
|
|
||||||
<Select
|
|
||||||
size="large"
|
|
||||||
placeholder={`${t("input.academic_year")}`}
|
|
||||||
value={SelectCycleValue}
|
|
||||||
options={BranchCycleData} // Ensure options are correctly formatted
|
|
||||||
onChange={handleChangeCycleSelect}
|
|
||||||
className="mb-4"
|
|
||||||
/>
|
|
||||||
<label className="text ">
|
|
||||||
{t("input.name")} {t("models.education_class")}
|
|
||||||
</label>
|
|
||||||
<Select
|
|
||||||
size="large"
|
|
||||||
placeholder={`${t("input.name")} ${t("models.education_class")}`}
|
|
||||||
value={selectValue}
|
|
||||||
options={formattedEduClasses} // Ensure options are correctly formatted
|
|
||||||
onChange={handleChangeSelect}
|
|
||||||
disabled={!SelectCycleValue}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button
|
|
||||||
disabled={selectValue === null || isLoading}
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>
|
|
||||||
{t("practical.move")}
|
|
||||||
{isLoading && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
import { Popover, TableColumnsType } from "antd";
|
|
||||||
import { Student } from "../../../../../types/Item";
|
|
||||||
import { FaEye } from "react-icons/fa";
|
|
||||||
import { FaEllipsisVertical } from "react-icons/fa6";
|
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
|
||||||
import { useDeleteRegistrationRecord } from "../../../../../api/registrationRecord";
|
|
||||||
import { useQueryClient } from "react-query";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
import { findLabelByValue } from "../../../../../utils/findLabelByValue";
|
|
||||||
import { Sex_Select_options_Student } from "../../../../../types/App";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
|
||||||
ABILITIES_ENUM,
|
|
||||||
ABILITIES_VALUES_ENUM,
|
|
||||||
} from "../../../../../enums/abilities";
|
|
||||||
import { hasAbility } from "../../../../../utils/hasAbility";
|
|
||||||
|
|
||||||
export const useColumns = () => {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const { mutate, isSuccess } = useDeleteRegistrationRecord();
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSuccess) {
|
|
||||||
queryClient.invalidateQueries(["student"]);
|
|
||||||
}
|
|
||||||
}, [isSuccess, queryClient]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const can_show_student = hasAbility(
|
|
||||||
ABILITIES_ENUM.STUDENT,
|
|
||||||
ABILITIES_VALUES_ENUM.SHOW,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columns: TableColumnsType<Student> = [
|
|
||||||
{
|
|
||||||
title: t("columns.id"),
|
|
||||||
dataIndex: "user_id",
|
|
||||||
key: "user_id",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.name"),
|
|
||||||
dataIndex: "first_name",
|
|
||||||
key: "first_name",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.sex"),
|
|
||||||
dataIndex: "sex",
|
|
||||||
key: "sex",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record) => {
|
|
||||||
const value = findLabelByValue(Sex_Select_options_Student, record?.sex);
|
|
||||||
return <>{t(`${value}`)}</>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.father_name"),
|
|
||||||
dataIndex: "father_name",
|
|
||||||
key: "father_name",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.last_name"),
|
|
||||||
dataIndex: "last_name",
|
|
||||||
key: "last_name",
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: t("columns.birthday"),
|
|
||||||
dataIndex: "birthday",
|
|
||||||
key: "birthday",
|
|
||||||
align: "center",
|
|
||||||
render: (text, record, index) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{record?.birth_place} {record?.birthday}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("columns.card"),
|
|
||||||
key: "name",
|
|
||||||
align: "center",
|
|
||||||
className: "SeeMoreEyeColumn",
|
|
||||||
hidden: !can_show_student,
|
|
||||||
render: (text, record, index) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onClick={() => navigate(`/student/${record?.id}`)}
|
|
||||||
className="SeeMoreEye"
|
|
||||||
>
|
|
||||||
<FaEye />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "",
|
|
||||||
key: "actions",
|
|
||||||
align: "center",
|
|
||||||
|
|
||||||
render: (text, record, index) => {
|
|
||||||
const handle_registered_student = (record: any) => {
|
|
||||||
// console.log(record,"record");
|
|
||||||
mutate({
|
|
||||||
id: record?.id + "/" + Number(edu_class_id),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const className =
|
|
||||||
index % 2 === 0 ? "even-row buttonAction" : "odd-row buttonAction";
|
|
||||||
|
|
||||||
const PopoverContent = (
|
|
||||||
<div className="PopoverContent">
|
|
||||||
<p onClick={() => handle_registered_student(record)}>
|
|
||||||
{" "}
|
|
||||||
{t("practical.cancel_registration")}{" "}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={className}>
|
|
||||||
<Popover
|
|
||||||
content={PopoverContent}
|
|
||||||
overlayClassName="Popover"
|
|
||||||
arrow={false}
|
|
||||||
placement="top"
|
|
||||||
>
|
|
||||||
<FaEllipsisVertical />
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import { Col, Row } from "reactstrap";
|
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import { StudentStatusEnum } from "../../../../../../enums/Items";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
const Form = () => {
|
|
||||||
const formik = useFormikContext<any>();
|
|
||||||
const { isOpen } = useModalState((state) => state);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen === "") {
|
|
||||||
formik.setErrors({});
|
|
||||||
}
|
|
||||||
}, [isOpen, formik]);
|
|
||||||
const [t] = useTranslation();
|
|
||||||
const Status = [
|
|
||||||
{
|
|
||||||
label: t("select.Student_Type.earlyDeparture"),
|
|
||||||
value: StudentStatusEnum?.EARLY_DEPARTURE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("select.Student_Type.presence"),
|
|
||||||
value: StudentStatusEnum?.PRESENCE,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const Type = [
|
|
||||||
{ label: t("select.Student_Type.justified"), value: "justified" },
|
|
||||||
{ label: t("select.Student_Type.not_justified"), value: "not_justified" },
|
|
||||||
];
|
|
||||||
|
|
||||||
// console.log(formik?.values);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className="w-100">
|
|
||||||
<Col>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="status"
|
|
||||||
label="status"
|
|
||||||
name="status"
|
|
||||||
type="Select"
|
|
||||||
option={Status}
|
|
||||||
/>
|
|
||||||
{formik?.values?.status !== StudentStatusEnum?.PRESENCE && (
|
|
||||||
<>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="type"
|
|
||||||
label="type"
|
|
||||||
type="Select"
|
|
||||||
name="type"
|
|
||||||
option={Type}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{formik?.values?.status !== StudentStatusEnum?.PRESENCE && (
|
|
||||||
<>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="departure_time"
|
|
||||||
label="departure_time"
|
|
||||||
name="departure_time"
|
|
||||||
type="Time"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
{formik?.values?.status !== StudentStatusEnum?.PRESENCE &&
|
|
||||||
formik?.values?.type === "justified" && (
|
|
||||||
<ValidationField
|
|
||||||
placeholder="justification"
|
|
||||||
label="justification"
|
|
||||||
name="justification"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{formik?.values?.status !== StudentStatusEnum?.PRESENCE && (
|
|
||||||
<>
|
|
||||||
<ValidationField
|
|
||||||
placeholder="attachment"
|
|
||||||
label="attachment"
|
|
||||||
type="File"
|
|
||||||
name="attachment"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
|
|
@ -1,206 +0,0 @@
|
||||||
import React, { useEffect } from "react";
|
|
||||||
import { Modal, Spin } from "antd";
|
|
||||||
import { useModalState } from "../../../../../../zustand/Modal";
|
|
||||||
import FormikForm from "../../../../../../Layout/Dashboard/FormikFormModel";
|
|
||||||
import ModelBody from "./Edit";
|
|
||||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
|
||||||
import { ModalEnum } from "../../../../../../enums/Model";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import {
|
|
||||||
useAddEarlyDeparture,
|
|
||||||
useDeleteEarlyDeparture,
|
|
||||||
useUpdateEarlyDeparture,
|
|
||||||
} from "../../../../../../api/earlyDeparture";
|
|
||||||
import { StudentStatusEnum } from "../../../../../../enums/Items";
|
|
||||||
import { useQueryClient } from "react-query";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { TERM_OBJECT_KEY } from "../../../../../../config/AppKey";
|
|
||||||
import { getLocalStorage } from "../../../../../../utils/LocalStorage";
|
|
||||||
|
|
||||||
const ModalForm: React.FC = () => {
|
|
||||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
|
||||||
const { object_to_edit, param_to_send } = useObjectToEdit((state) => state);
|
|
||||||
|
|
||||||
const {
|
|
||||||
mutate: mutate_EarlyDeparture,
|
|
||||||
isSuccess: isSuccess_mutate_EarlyDeparture,
|
|
||||||
isLoading: isLoading_mutate_EarlyDeparture,
|
|
||||||
} = useAddEarlyDeparture();
|
|
||||||
const {
|
|
||||||
mutate: update_EarlyDeparture,
|
|
||||||
isSuccess: isSuccess_update_EarlyDeparture,
|
|
||||||
isLoading: isLoading_update_EarlyDeparture,
|
|
||||||
} = useUpdateEarlyDeparture();
|
|
||||||
const {
|
|
||||||
mutate: mutate_presence,
|
|
||||||
isSuccess: isSuccess_mutate_presence,
|
|
||||||
isLoading: isLoading_mutate_presence,
|
|
||||||
} = useDeleteEarlyDeparture();
|
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
console.log(object_to_edit, "object_to_edit");
|
|
||||||
let Today = new Date() as any;
|
|
||||||
let dateToSend =
|
|
||||||
param_to_send?.date === "today"
|
|
||||||
? dayjs(Today).format("YYYY-MM-DD")
|
|
||||||
: param_to_send?.date ?? dayjs(Today).format("YYYY-MM-DD");
|
|
||||||
|
|
||||||
const term_id = getLocalStorage(TERM_OBJECT_KEY)?.id;
|
|
||||||
const [t] = useTranslation();
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
isSuccess_mutate_EarlyDeparture ||
|
|
||||||
isSuccess_update_EarlyDeparture ||
|
|
||||||
isSuccess_mutate_presence
|
|
||||||
) {
|
|
||||||
setIsOpen("");
|
|
||||||
queryClient.invalidateQueries(["attendence"]);
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
setIsOpen,
|
|
||||||
isSuccess_mutate_EarlyDeparture,
|
|
||||||
isSuccess_update_EarlyDeparture,
|
|
||||||
isSuccess_mutate_presence,
|
|
||||||
queryClient,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
|
||||||
// console.log(values,"values");
|
|
||||||
if (values?.status === StudentStatusEnum?.EARLY_DEPARTURE) {
|
|
||||||
if (!values?.departure_time) {
|
|
||||||
toast.error(t("validation.duration_is_required"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values?.type === "justified") {
|
|
||||||
if (!values?.justification) {
|
|
||||||
toast.error(t("validation.justification_is_required"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object_to_edit?.status === StudentStatusEnum?.EARLY_DEPARTURE) {
|
|
||||||
const NewData = {
|
|
||||||
id: object_to_edit?.[StudentStatusEnum?.EARLY_DEPARTURE]?.id,
|
|
||||||
type: values?.type,
|
|
||||||
justification: values?.justification,
|
|
||||||
term_id: term_id,
|
|
||||||
attachment: values?.attachment,
|
|
||||||
departure_time: "",
|
|
||||||
date: dateToSend,
|
|
||||||
};
|
|
||||||
NewData["departure_time"] = values?.departure_time?.format("HH:mm");
|
|
||||||
|
|
||||||
// if (typeof NewData?.attachment === "string") {
|
|
||||||
// delete NewData["attachment"];
|
|
||||||
// }
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
formData.append("id", NewData?.id);
|
|
||||||
formData.append("type", NewData?.type);
|
|
||||||
formData.append("date", NewData?.date);
|
|
||||||
formData.append("justification", NewData?.justification);
|
|
||||||
formData.append("term_id", NewData?.term_id as any);
|
|
||||||
formData.append("duration", NewData?.departure_time);
|
|
||||||
|
|
||||||
if (typeof NewData?.attachment === "string") {
|
|
||||||
delete NewData["attachment"];
|
|
||||||
} else if (NewData?.attachment) {
|
|
||||||
formData.append("attachment", NewData?.attachment);
|
|
||||||
} else {
|
|
||||||
formData.append("attachment", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
update_EarlyDeparture(formData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(object_to_edit);
|
|
||||||
|
|
||||||
const NewData = {
|
|
||||||
registration_record_id: object_to_edit?.id,
|
|
||||||
type: values?.type,
|
|
||||||
departure_time: "",
|
|
||||||
date: dateToSend,
|
|
||||||
justification: values?.justification,
|
|
||||||
term_id: term_id,
|
|
||||||
attachment: values?.attachment,
|
|
||||||
};
|
|
||||||
NewData["departure_time"] = values?.departure_time?.format("HH:mm");
|
|
||||||
|
|
||||||
if (typeof NewData?.attachment === "string") {
|
|
||||||
delete NewData["attachment"];
|
|
||||||
}
|
|
||||||
// console.log(NewData);
|
|
||||||
|
|
||||||
mutate_EarlyDeparture(NewData);
|
|
||||||
}
|
|
||||||
if (values?.status === StudentStatusEnum?.PRESENCE) {
|
|
||||||
if (object_to_edit?.status === StudentStatusEnum?.PRESENCE) {
|
|
||||||
toast.error(t("validation.pleas_do_any_changes"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mutate_presence({
|
|
||||||
id: Number(object_to_edit?.[StudentStatusEnum?.EARLY_DEPARTURE]?.id),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setIsOpen("");
|
|
||||||
};
|
|
||||||
// console.log(object_to_edit);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
className="ModalForm"
|
|
||||||
centered
|
|
||||||
width={"60vw"}
|
|
||||||
footer={null}
|
|
||||||
open={isOpen === ModalEnum?.EARLY_DEPARTURE_EDIT}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
>
|
|
||||||
<FormikForm
|
|
||||||
handleSubmit={handleSubmit}
|
|
||||||
initialValues={getInitialValues(object_to_edit)}
|
|
||||||
validationSchema={getValidationSchema}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
{t("practical.edit")} {t("practical.details")} ({" "}
|
|
||||||
{object_to_edit?.student?.full_name} ){" "}
|
|
||||||
</header>
|
|
||||||
<main className="main_modal w-100">
|
|
||||||
<ModelBody />
|
|
||||||
<div className="buttons">
|
|
||||||
<div onClick={handleCancel}>{t("practical.back")}</div>
|
|
||||||
<button
|
|
||||||
disabled={
|
|
||||||
isLoading_mutate_EarlyDeparture ||
|
|
||||||
isLoading_update_EarlyDeparture ||
|
|
||||||
isLoading_mutate_presence
|
|
||||||
}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
{t("practical.edit")}
|
|
||||||
{isLoading_mutate_EarlyDeparture ||
|
|
||||||
isLoading_update_EarlyDeparture ||
|
|
||||||
(isLoading_mutate_presence && (
|
|
||||||
<span className="Spinier_Div">
|
|
||||||
<Spin />
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</FormikForm>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ModalForm;
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
import { Button, Image, Upload, UploadFile } from "antd";
|
|
||||||
import { UploadOutlined } from "@ant-design/icons";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { FaRegFilePdf } from "react-icons/fa";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { ImageBaseURL } from "../../../../../../../api/config";
|
|
||||||
import useFormField from "../../../../../../../Hooks/useFormField";
|
|
||||||
import { useFormikContext } from "formik";
|
|
||||||
|
|
||||||
const PdfUploader = () => {
|
|
||||||
const name = "attachment";
|
|
||||||
const formik = useFormikContext<any>();
|
|
||||||
let FormikName = formik.values[name];
|
|
||||||
const imageUrl = formik.values[name] ? ImageBaseURL + FormikName : "";
|
|
||||||
const [Imageurl, setImageurl] = useState(null);
|
|
||||||
|
|
||||||
const FilehandleChange = (value: any) => {
|
|
||||||
// console.log(value.file.originFileObj, "value.file.originFileObj");
|
|
||||||
|
|
||||||
formik.setFieldValue(name, value.file.originFileObj);
|
|
||||||
setImageurl(value.file.originFileObj);
|
|
||||||
};
|
|
||||||
const customRequest = async ({ onSuccess }: any) => {
|
|
||||||
onSuccess();
|
|
||||||
};
|
|
||||||
const UploadProps = {
|
|
||||||
name: "file",
|
|
||||||
customRequest: customRequest,
|
|
||||||
onChange: FilehandleChange,
|
|
||||||
headers: {
|
|
||||||
authorization: "authorization-text",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="PdfUploader">
|
|
||||||
<div>التقرير الطبّي *</div>
|
|
||||||
<main>
|
|
||||||
{Imageurl === null ? (
|
|
||||||
<div className="ImagePdfUploader">
|
|
||||||
<Image src={"/Icon/Empty_Image.png"} />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="ImagePdfUploaderWrapper">
|
|
||||||
<Image src={URL.createObjectURL(Imageurl)} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Upload {...UploadProps}>
|
|
||||||
<Button>
|
|
||||||
{" "}
|
|
||||||
إضافة ملف <FaRegFilePdf />
|
|
||||||
</Button>
|
|
||||||
</Upload>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PdfUploader;
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import * as Yup from "yup";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { StudentStatusEnum } from "../../../../../../enums/Items";
|
|
||||||
|
|
||||||
export const getInitialValues = (objectToEdit: any): any => {
|
|
||||||
return {
|
|
||||||
id: objectToEdit?.id ?? null,
|
|
||||||
attachment:
|
|
||||||
objectToEdit?.[StudentStatusEnum?.EARLY_DEPARTURE]?.attachment ?? null,
|
|
||||||
type: objectToEdit?.type ?? "justified",
|
|
||||||
justification:
|
|
||||||
objectToEdit?.[StudentStatusEnum?.EARLY_DEPARTURE]?.justification ?? null,
|
|
||||||
departure_time: objectToEdit?.[StudentStatusEnum?.EARLY_DEPARTURE]
|
|
||||||
?.departure_time
|
|
||||||
? dayjs(
|
|
||||||
objectToEdit?.[StudentStatusEnum?.EARLY_DEPARTURE]?.departure_time,
|
|
||||||
"H:mm",
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
status: StudentStatusEnum?.EARLY_DEPARTURE,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getValidationSchema = () => {
|
|
||||||
// validate input
|
|
||||||
return Yup.object().shape({});
|
|
||||||
};
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
.custom-select {
|
|
||||||
position: relative;
|
|
||||||
z-index: 9;
|
|
||||||
color: gray;
|
|
||||||
|
|
||||||
.custom_select_icon {
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom_select_icon.open {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.options-list {
|
|
||||||
max-height: 120px;
|
|
||||||
overflow: auto;
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
scroll-padding: 10rem;
|
|
||||||
direction: ltr;
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle */
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #999999;
|
|
||||||
border-radius: 5px; /* Adjust border-radius as needed */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Track */
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
border-radius: 5px; /* Adjust border-radius as needed */
|
|
||||||
background-color: transparent; /* Set to desired background color */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.options {
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
background: var(--bg2);
|
|
||||||
border: 0.2vw solid var(--primary);
|
|
||||||
border-top: none;
|
|
||||||
padding: 0.1vw 0.3vw;
|
|
||||||
direction: rtl;
|
|
||||||
|
|
||||||
border-bottom-right-radius: 15px !important;
|
|
||||||
border-bottom-left-radius: 15px !important;
|
|
||||||
|
|
||||||
z-index: 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option {
|
|
||||||
padding: 0.6vw 1vw;
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option:hover {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 0.4vw;
|
|
||||||
padding: 0.6vw 1vw;
|
|
||||||
cursor: pointer;
|
|
||||||
background: transparent;
|
|
||||||
border: 0.2vw solid var(--primary);
|
|
||||||
color: var(--primary);
|
|
||||||
font-weight: bold;
|
|
||||||
border-radius: 70px;
|
|
||||||
text-align: center;
|
|
||||||
width: 12vw;
|
|
||||||
height: 2.5vw !important;
|
|
||||||
transition: 0.5s ease-in-out;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
font-size: 1.6vw;
|
|
||||||
color: var(--primary);
|
|
||||||
}
|
|
||||||
.search-input {
|
|
||||||
font-size: 1vw;
|
|
||||||
width: 70%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: transparent !important;
|
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-select.open .select-header {
|
|
||||||
border-bottom-right-radius: 0 !important;
|
|
||||||
border-bottom-left-radius: 0 !important;
|
|
||||||
border-top-right-radius: 30px !important;
|
|
||||||
border-top-left-radius: 30px !important;
|
|
||||||
|
|
||||||
transition: 0.5s ease-in-out;
|
|
||||||
// background-color: red !important;
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
import React, { useState, useRef, useEffect } from "react";
|
|
||||||
import { IoMdArrowDropdown } from "react-icons/io";
|
|
||||||
import "./CustomSelect.scss"; // Import CSS for styling
|
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|
||||||
|
|
||||||
interface Option {
|
|
||||||
label: string;
|
|
||||||
value: string | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
options: Option[];
|
|
||||||
placeholder: string;
|
|
||||||
onChange?: (option: Option) => void;
|
|
||||||
searchBy?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomSelect: React.FC<Props> = ({
|
|
||||||
options,
|
|
||||||
placeholder,
|
|
||||||
onChange,
|
|
||||||
searchBy = "name",
|
|
||||||
}) => {
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
|
|
||||||
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
|
||||||
const node = useRef<HTMLDivElement>(null);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const location = useLocation();
|
|
||||||
const { param_to_send, set_param_to_send } = useObjectToEdit();
|
|
||||||
// console.log(param_to_send);
|
|
||||||
|
|
||||||
const toggleDropdown = () => {
|
|
||||||
setIsOpen(!isOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOptionClick = (option: Option) => {
|
|
||||||
setSelectedOption(option);
|
|
||||||
// console.log(option);
|
|
||||||
|
|
||||||
// console.log(`selected ${option?.value}`);
|
|
||||||
const newObj = { ...param_to_send };
|
|
||||||
newObj.state = option?.value;
|
|
||||||
set_param_to_send(newObj);
|
|
||||||
navigate(
|
|
||||||
`${location.pathname}?${option?.value}=${newObj?.date ?? "today"}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
setIsOpen(false);
|
|
||||||
setSearchTerm("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const filteredOptions = options.filter((option) =>
|
|
||||||
option.label.toLowerCase().includes(searchTerm.toLowerCase()),
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Add event listener when component mounts
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
|
||||||
// Remove event listener when component unmounts
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("mousedown", handleClickOutside);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
|
||||||
// Close the dropdown if clicked outside the component
|
|
||||||
if (node.current && !node.current.contains(event.target as Node)) {
|
|
||||||
setIsOpen(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className={`custom-select ${isOpen ? "open" : ""}`} ref={node}>
|
|
||||||
<div className="select-header" onClick={toggleDropdown}>
|
|
||||||
<IoMdArrowDropdown
|
|
||||||
className={`custom_select_icon ${isOpen ? "open" : ""}`}
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder={selectedOption ? selectedOption.label : placeholder}
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
|
||||||
onFocus={() => setIsOpen(true)}
|
|
||||||
className="search-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{(isOpen || (searchTerm !== "" && filteredOptions.length > 0)) && (
|
|
||||||
<div className="options">
|
|
||||||
<div className="options-list">
|
|
||||||
{filteredOptions.map((option) => (
|
|
||||||
<div
|
|
||||||
key={option.value}
|
|
||||||
className="option"
|
|
||||||
onClick={() => handleOptionClick(option)}
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CustomSelect;
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
import Table from "./TablePage";
|
|
||||||
import SearchField from "../../../../../Components/DataTable/SearchField";
|
|
||||||
import { useGetAllEduClass } from "../../../../../api/eduClass";
|
|
||||||
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
|
||||||
import CustomSelect from "./Select/CustomSelect";
|
|
||||||
import EditAbsenceModel from "./Model/EditModel";
|
|
||||||
import type { DatePickerProps } from "antd";
|
|
||||||
import { DatePicker } from "antd";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import { StudentStatusEnum } from "../../../../../enums/Items";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import CustomDatePicker from "../../../../../Components/Ui/Custom/CustomDatePicker";
|
|
||||||
|
|
||||||
const TableHeader = () => {
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const { data: edu_class } = useGetAllEduClass({
|
|
||||||
show: edu_class_id,
|
|
||||||
});
|
|
||||||
const edu_class_name = edu_class?.data?.name || "";
|
|
||||||
const course_name = edu_class?.data?.course?.name || "";
|
|
||||||
const full_name = " " + course_name + " ( " + edu_class_name + " )";
|
|
||||||
|
|
||||||
|
|
||||||
const [t] = useTranslation();
|
|
||||||
|
|
||||||
const OptionsType = [
|
|
||||||
{
|
|
||||||
value: "all",
|
|
||||||
label: t("select.Student_Type.all_students"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("select.Student_Type.earlyDeparture"),
|
|
||||||
value: StudentStatusEnum?.EARLY_DEPARTURE,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const Today = new Date() as any;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="TableWithHeader">
|
|
||||||
<header>
|
|
||||||
<h6>
|
|
||||||
{t("header.earlyDepartures")}
|
|
||||||
{full_name}
|
|
||||||
</h6>
|
|
||||||
<div className="Selects">
|
|
||||||
<CustomSelect
|
|
||||||
options={OptionsType}
|
|
||||||
placeholder={t("select.Student_Type.all_students")}
|
|
||||||
searchBy="type"
|
|
||||||
/>
|
|
||||||
<CustomDatePicker/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<SearchField
|
|
||||||
searchBy="student_name_early_departure"
|
|
||||||
placeholder={t("practical.search_here")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Table />
|
|
||||||
|
|
||||||
<EditAbsenceModel />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableHeader;
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
import { useColumns } from ".";
|
|
||||||
import { useLocation, useParams } from "react-router-dom";
|
|
||||||
import React from "react";
|
|
||||||
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { useGetAllEarlyDeparture } from "../../../../../api/earlyDeparture";
|
|
||||||
import DataTable from "../../../../../Layout/Dashboard/Table/DataTable";
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const { edu_class_id } = useParams();
|
|
||||||
const [searchQuery, setSearchQuery] = React.useState<string>("");
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
const { param_to_send } = useObjectToEdit();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const searchParams = new URLSearchParams(location?.search);
|
|
||||||
setSearchQuery(searchParams?.get("student_name_early_departure") || "");
|
|
||||||
// console.log(searchQuery,"searchQuery");
|
|
||||||
}, [location, searchQuery]);
|
|
||||||
let Today = new Date() as any;
|
|
||||||
let dateToSend =
|
|
||||||
param_to_send?.date === "today"
|
|
||||||
? dayjs(Today).format("YYYY-MM-DD")
|
|
||||||
: param_to_send?.date ?? dayjs(Today).format("YYYY-MM-DD");
|
|
||||||
|
|
||||||
const response = useGetAllEarlyDeparture({
|
|
||||||
student_name: searchQuery,
|
|
||||||
edu_class_id: edu_class_id,
|
|
||||||
[param_to_send?.state ?? "all"]: dateToSend,
|
|
||||||
date: dateToSend,
|
|
||||||
pagination: true,
|
|
||||||
status: "active",
|
|
||||||
});
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user