Compare commits

..

6 Commits

Author SHA1 Message Date
karimalden
f5e0bebeb0 fix header 2024-07-27 15:07:07 +03:00
karimalden
4b9a4f4d23 change lower case 2024-07-27 14:57:06 +03:00
karimalden
2c77beab03 Delete IMage 2024-07-27 14:49:44 +03:00
karimalden
fe6ccaaee0 add loading and change ability 2024-07-27 14:43:46 +03:00
karimalden
d721b8417c change_route 2024-07-27 14:17:51 +03:00
karimalden
9530ea30e7 fix bug and remove unnesasery 2024-07-27 14:14:12 +03:00
336 changed files with 4261 additions and 17820 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -18,6 +18,7 @@
"tagcontainer", "tagcontainer",
"toastify", "toastify",
"Viewelement", "Viewelement",
"webp",
"zustand", "zustand",
"مطلوب" "مطلوب"
], ],

File diff suppressed because one or more lines are too long

View File

@ -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",

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/App/SyriaLogo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 619 KiB

View File

@ -1,5 +0,0 @@
<svg viewBox="0 0 377 446" fill="none" xmlns="http://www.w3.org/2000/svg">
<ellipse opacity="0.1" cx="293" cy="326.206" rx="293" ry="326.206" fill="white" fill-opacity="0.66"/>
<ellipse opacity="0.1" cx="293" cy="326.207" rx="181.81" ry="202.415" fill="white" fill-opacity="0.66"/>
<ellipse opacity="0.1" cx="292.999" cy="326.206" rx="94.6615" ry="105.39" fill="white" fill-opacity="0.66"/>
</svg>

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,18 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1082" height="138" viewBox="0 0 1082 138">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_1" data-name="Rectangle 1" width="1082" height="138" transform="translate(419 362)" fill="#fff"/>
</clipPath>
</defs>
<g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(-419 -362)" clip-path="url(#clip-path)">
<g id="cover" transform="translate(369 332)">
<g id="Group_1" data-name="Group 1">
<path id="Path_1" data-name="Path 1" d="M50,50A20,20,0,0,1,70,30H1112a20,20,0,0,1,20,20V170H50Z" fill="#3182ce"/>
</g>
<g id="Group_2" data-name="Group 2">
<rect id="Rectangle_1-2" data-name="Rectangle 1" width="280.439" height="275.13" rx="20" transform="translate(230.408 111.564)" fill="#fb7d5b"/>
<rect id="Rectangle_2" data-name="Rectangle 2" width="280.439" height="275.13" rx="20" transform="translate(92 61)" fill="#fcc43e"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -8,7 +8,6 @@ import { useChangeLanguage } from "./Hooks/useChangeLanguage";
import useAuthState from "./zustand/AuthState"; import useAuthState from "./zustand/AuthState";
import { TMenuItem } from "./types/App"; import { TMenuItem } from "./types/App";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import useSetPage_title from "./Hooks/useSetPageTitle";
import SpinContainer from "./Components/Layout/SpinContainer"; import SpinContainer from "./Components/Layout/SpinContainer";
const Page404 = lazy(() => import("./Layout/Ui/NotFoundPage")); const Page404 = lazy(() => import("./Layout/Ui/NotFoundPage"));
@ -40,7 +39,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 +80,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;

View File

@ -50,14 +50,14 @@ const HeaderSection = () => {
); );
const [, setActiveButton] = useState(0); const [, setActiveButton] = useState(0);
const { setActiveTab, ActiveTab } = useButtonState((state) => state); const { setActiveTab, ActiveTab } = useButtonState((state) => state);
const { set_param_to_send } = useObjectToEdit(); const { setParamToSend } = useObjectToEdit();
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const handleButtonClick = (index: number) => { const handleButtonClick = (index: number) => {
setActiveButton(index); setActiveButton(index);
setActiveTab(index); setActiveTab(index);
set_param_to_send({}); setParamToSend({});
navigate(`${location.pathname}`); navigate(`${location.pathname}`);
}; };
return ( return (

Binary file not shown.

View File

@ -9,17 +9,17 @@ import { DateEnum } from '../../../enums/Date';
const CustomDatePicker = () => { const CustomDatePicker = () => {
const [t] = useTranslation(); const [t] = useTranslation();
const { set_param_to_send, param_to_send } = useObjectToEdit(); const { setParamToSend, paramToSend } = useObjectToEdit();
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const onChange: DatePickerProps["onChange"] = (date, dateString) => { const onChange: DatePickerProps["onChange"] = (date, dateString) => {
// console.log(date, dateString); // console.log(date, dateString);
const newObj = { ...param_to_send }; const newObj = { ...paramToSend };
newObj.date = dateString; newObj.date = dateString;
set_param_to_send(newObj); setParamToSend(newObj);
navigate( navigate(
`${location.pathname}?${param_to_send?.state ?? "all"}=${dateString}`, `${location.pathname}?${paramToSend?.state ?? "all"}=${dateString}`,
); );
}; };
const Today = new Date() as any; const Today = new Date() as any;

View File

@ -8,19 +8,19 @@ import { QUESTION_OBJECT_KEY } from '../../config/AppKey';
const Header = () => { const Header = () => {
const [t] = useTranslation(); const [t] = useTranslation();
const { values, setFieldValue,setValues } = useFormikContext<any>(); const { values, setFieldValue,setValues } = useFormikContext<any>();
const {isBseQuestion,set_isBseQuestion} = useObjectToEdit() const {isBseQuestion,setIsBseQuestion} = useObjectToEdit()
const {set_SavedQuestionData} = useObjectToEdit() const {setSavedQuestionData} = useObjectToEdit()
const handleChange = () => { const handleChange = () => {
set_SavedQuestionData(null) setSavedQuestionData(null)
localStorage.removeItem(QUESTION_OBJECT_KEY) localStorage.removeItem(QUESTION_OBJECT_KEY)
if (isBseQuestion) { if (isBseQuestion) {
set_isBseQuestion(false) setIsBseQuestion(false)
setValues(null) setValues(null)
setFieldValue("isBase",0) setFieldValue("isBase",0)
} else { } else {
set_isBseQuestion(true) setIsBseQuestion(true)
setValues(null) setValues(null)
setFieldValue("isBase",1) setFieldValue("isBase",1)
} }

View 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;

View 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;

View File

@ -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;

View File

@ -22,7 +22,7 @@ const DeleteModels: React.FC<ModalFormProps> = ({
const [inputValue, setInputValue] = useState(""); const [inputValue, setInputValue] = useState("");
const { mutate, isLoading, isSuccess } = deleteMutation; const { mutate, isLoading, isSuccess } = deleteMutation;
const { object_to_edit, set_object_to_edit } = useObjectToEdit(); const { objectToEdit, setObjectToEdit } = useObjectToEdit();
useEffect(() => { useEffect(() => {
if (isSuccess) { if (isSuccess) {
@ -33,14 +33,14 @@ const DeleteModels: React.FC<ModalFormProps> = ({
const handleSubmit = () => { const handleSubmit = () => {
mutate({ mutate({
id: Number(object_to_edit?.id), id: Number(objectToEdit?.id),
}); });
}; };
const handleCancel = () => { const handleCancel = () => {
setInputValue(""); setInputValue("");
setIsOpen(""); setIsOpen("");
set_object_to_edit({}); setObjectToEdit({});
}; };
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@ -48,7 +48,7 @@ const DeleteModels: React.FC<ModalFormProps> = ({
}; };
const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => { const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" && object_to_edit?.[objectValue] === inputValue) { if (e.key === "Enter" && objectToEdit?.[objectValue] === inputValue) {
handleSubmit(); handleSubmit();
} }
}; };
@ -71,7 +71,7 @@ const DeleteModels: React.FC<ModalFormProps> = ({
<div className="ValidationField w-100 mb-5"> <div className="ValidationField w-100 mb-5">
<label className="text "> <label className="text ">
{t("practical.to_confirm_deletion_please_re_enter")}{" "} {t("practical.to_confirm_deletion_please_re_enter")}{" "}
{t(`input.${objectValue}`)} ({object_to_edit?.[objectValue]}) {t(`input.${objectValue}`)} ({objectToEdit?.[objectValue]})
</label> </label>
<Input <Input
@ -88,11 +88,11 @@ const DeleteModels: React.FC<ModalFormProps> = ({
<div onClick={handleCancel}>{t("practical.cancel")}</div> <div onClick={handleCancel}>{t("practical.cancel")}</div>
<button <button
className={ className={
object_to_edit?.[objectValue] !== inputValue objectToEdit?.[objectValue] !== inputValue
? "disabled_button" ? "disabled_button"
: "" : ""
} }
disabled={object_to_edit?.[objectValue] !== inputValue || isLoading} disabled={objectToEdit?.[objectValue] !== inputValue || isLoading}
onClick={handleSubmit} onClick={handleSubmit}
type="button" type="button"
> >

View File

@ -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();

View File

@ -13,12 +13,12 @@ import { useUpdateAdmin } from "../../../api/users";
const ModalForm: React.FC = () => { const ModalForm: React.FC = () => {
const { isOpen, setIsOpen } = useModalState((state) => state); const { isOpen, setIsOpen } = useModalState((state) => state);
const { mutate, isSuccess, isLoading } = useUpdateAdmin(); const { mutate, isSuccess, isLoading } = useUpdateAdmin();
const { set_object_to_edit } = useObjectToEdit(); const { setObjectToEdit } = useObjectToEdit();
useEffect(() => { useEffect(() => {
if (isSuccess) { if (isSuccess) {
setIsOpen(""); setIsOpen("");
set_object_to_edit({}); setObjectToEdit({});
} }
}, [setIsOpen, isSuccess]); }, [setIsOpen, isSuccess]);
@ -32,7 +32,7 @@ const ModalForm: React.FC = () => {
const handleCancel = () => { const handleCancel = () => {
setIsOpen(""); setIsOpen("");
set_object_to_edit({}); setObjectToEdit({});
}; };
const [t] = useTranslation(); const [t] = useTranslation();
return ( return (

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -24,7 +24,7 @@ const FormField = ({ isLoading }: FormFieldType) => {
const [t] = useTranslation(); const [t] = useTranslation();
return ( return (
<Form className="AuthForm"> <Form className="AuthForm">
<Image src="../Layout/Logo.png" /> <Image src="../App/Logo.png" />
<div className="AuthInput"> <div className="AuthInput">

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"),
});
};

View File

@ -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;

View File

@ -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;

Some files were not shown because too many files have changed in this diff Show More