This commit is contained in:
karimalden 2024-08-07 16:23:25 +03:00
parent 435c8ddad1
commit 893d564334
26 changed files with 255 additions and 180 deletions

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 861 B

After

Width:  |  Height:  |  Size: 861 B

View File

@ -0,0 +1,16 @@
import { MdExpandLess, MdExpandMore } from "react-icons/md";
interface DropdownToggleProps {
isOpen: boolean;
onClick: () => void;
}
const DropdownToggle: React.FC<DropdownToggleProps> = ({ isOpen, onClick }) => {
return (
<div className="DropDownIcon" onClick={onClick}>
{isOpen ? <MdExpandLess /> : <MdExpandMore />}
</div>
);
};
export default DropdownToggle;

View File

@ -0,0 +1,37 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import DropdownToggle from "./DropdownToggle"; // Adjust the import path as necessary
import SubMenu from "./SubMenu"; // Adjust the import path as necessary
export const MenuItem = ({ item, location, index }: any) => {
const isActive = location.pathname.split("/")[1] === item.path?.slice(1);
const [openDropdown, setOpenDropdown] = useState<number | null>(null);
const [t] = useTranslation();
const navigate = useNavigate();
const handleDropdown = (index: number) => {
setOpenDropdown((prev) => (prev === index ? null : index));
};
const isDropdownOpen = openDropdown === index;
return (
<>
<div
className={`link ${isActive ? "active" : ""} ${item?.children && "DropDownLink"}`}
onClick={() => navigate(item.path || "/")}
>
<i>{item.icon}</i>
<Link to={item.path || "/"}>{t(item.text)}</Link>
{item?.children && (
<DropdownToggle isOpen={isDropdownOpen} onClick={() => handleDropdown(index)} />
)}
</div>
{item?.children && isDropdownOpen && (
<SubMenu items={item.children} location={location} />
)}
</>
);
};

View File

@ -0,0 +1,54 @@
import React from 'react'
import { getLocalStorage } from '../../../utils/LocalStorage';
import { USER_KEY } from '../../../config/AppKey';
import { translateOptions } from '../../../utils/translatedOptions';
import { search_array } from '../../../Routes';
import { useTranslation } from 'react-i18next';
import SearchFieldWithSelect from '../../DataTable/SearchFieldWithSelect';
import { Tooltip } from 'antd';
import useModalHandler from '../../../utils/useModalHandler';
import { ModalEnum } from '../../../enums/Model';
import Image from '../../Ui/Image';
const NavBarRightSide = () => {
const userData = getLocalStorage(USER_KEY);
const [t] = useTranslation()
const translateArray = translateOptions(search_array, t);
const { handel_open_model } = useModalHandler();
const handleEdit = () => {
handel_open_model(ModalEnum.CHANGE_PASSWORD);
};
return (
<article>
<div className="header_search">
<SearchFieldWithSelect
options={translateArray}
placeholder={t("practical.search_here")}
/>
</div>
<span className="header_icons">
<div>
<Image src="/Icon/bell.png" alt="Notifications" />
</div>
<Tooltip
placement="top"
title={<div onClick={handleEdit}>{t("header.change_your_current_password")}</div>}
color="#E0E0E0"
>
<div className="gear">
<Image src="/Icon/gear.png" alt="Settings" />
</div>
</Tooltip>
</span>
<div className="header_profile">
<span>
<h6>{userData?.username}</h6>
<p>{userData?.type}</p>
</span>
<Image src="/Layout/DefaultStudentImage.png" alt="Profile" />
</div>
</article>
)
}
export default NavBarRightSide

View File

@ -0,0 +1,19 @@
import React from "react";
import { MenuItem } from "./MenuItem"; // Adjust the import path as necessary
interface SubMenuProps {
items: any[];
location: any;
}
const SubMenu: React.FC<SubMenuProps> = ({ items, location }) => {
return (
<div className="sub-menu">
{items.map((childItem, index) => (
<MenuItem key={index} item={childItem} location={location} index={index} />
))}
</div>
);
};
export default SubMenu;

View File

@ -0,0 +1,63 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { MdExpandLess, MdExpandMore } from "react-icons/md";
import { Link, useNavigate } from "react-router-dom";
export const MenuItem = ({ item, location, index }: any) => {
const isActive = location.pathname.split("/")[1] === item.path?.slice(1);
// console.log(location.pathname.split("/")[1]);
const [openDropdown, setOpenDropdown] = useState<number | null>(null);
const handleDropdown = (index: number) => {
setOpenDropdown((prev) => (prev === index ? null : index));
};
const isDropdownOpen = openDropdown === index;
const [t] = useTranslation();
const navigate = useNavigate();
return (
<>
<div
className={`link ${isActive ? "active" : ""} ${item?.children && "DropDownLink"} `}
onClick={() => navigate(item.path || "/")}
>
<i>{item.icon}</i>
<Link to={item.path || "/"}>{t(item.text)}</Link>
{item?.children && (
<>
{isDropdownOpen ? (
<div
className="DropDownIcon"
onClick={() => handleDropdown(index)}
>
<MdExpandLess />
</div>
) : (
<div
className="DropDownIcon"
onClick={() => handleDropdown(index)}
>
<MdExpandMore />
</div>
)}
</>
)}
</div>
{item?.children && isDropdownOpen && (
<div className="sub-menu">
{item.children.map((childItem: any, index: any) => (
<MenuItem
key={index}
item={childItem}
location={location}
index={index}
/>
))}
</div>
)}
</>
);
};

View File

@ -15,7 +15,7 @@ const TabsBar = ({ steps }: any) => {
!step.hidden && ( !step.hidden && (
<div <div
onClick={() => handleTabClick(index)} onClick={() => handleTabClick(index)}
className={`ModelBodyTab ${ActiveTab === index ? "activeModeltab" : ""}`} className={`ModelBodyTab ${ActiveTab === index ? "activeModelTab" : ""}`}
key={index} key={index}
> >
<div>{index + 1}</div> <div>{index + 1}</div>

View File

@ -1,6 +1,6 @@
import { Layout } from "antd";
import { Suspense } from "react"; import { Suspense } from "react";
import SpinContainer from "../Layout/SpinContainer"; import SpinContainer from "../Layout/SpinContainer";
import Layout from "../../Layout/Ui/Layout";
export const RenderRouteElement = (route: any) => ( export const RenderRouteElement = (route: any) => (
<Suspense <Suspense

View File

@ -1,12 +1,12 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { usePage_titleState } from "../zustand/PageTitleState"; import { usePageTitleState } from "../zustand/PageTitleState";
const useSetPageTitle = (title: any) => { const useSetPageTitle = (title: any) => {
const setPage_title = usePage_titleState((state) => state.setPage_title); const setPageTitle = usePageTitleState((state) => state.setPageTitle);
useEffect(() => { useEffect(() => {
setPage_title(title); setPageTitle(title);
}, [title, setPage_title]); }, [title, setPageTitle]);
}; };
export default useSetPageTitle; export default useSetPageTitle;

View File

@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import { useLocation } from "react-router-dom";
import NavBar from "./NavBar"; import NavBar from "./NavBar";
import SideBar from "./SideBar"; import SideBar from "./SideBar";
import ProtectedRouteProvider from "../../lib/ProtectedRouteProvider"; import ProtectedRouteProvider from "../../lib/ProtectedRouteProvider";
@ -13,7 +12,7 @@ const Layout = ({
}) => { }) => {
return ( return (
<>
<ProtectedRouteProvider className="Layout"> <ProtectedRouteProvider className="Layout">
<main className={`${className} Layout_Body`}> <main className={`${className} Layout_Body`}>
<NavBar /> <NavBar />
@ -21,7 +20,7 @@ const Layout = ({
</main> </main>
<SideBar /> <SideBar />
</ProtectedRouteProvider> </ProtectedRouteProvider>
</>
); );
}; };

View File

@ -1,86 +1,40 @@
import React from "react"; import React, { lazy, Suspense } from "react";
import Image from "../../Components/Ui/Image";
import SearchField from "../../Components/DataTable/SearchFieldWithSelect"; import { usePageTitleState } from "../../zustand/PageTitleState";
import { usePage_titleState } from "../../zustand/PageTitleState";
import { MdOutlineArrowForwardIos } from "react-icons/md"; import { MdOutlineArrowForwardIos } from "react-icons/md";
import { useLocation, useNavigate, useParams } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import { search_array } from "../../Routes";
import { BRANCH_OBJECT_KEY, USER_KEY } from "../../config/AppKey";
import { useTranslation } from "react-i18next";
import { translateOptions } from "../../utils/translatedOptions";
import { ParamsEnum } from "../../enums/params";
import { Tooltip } from "antd";
import useModalHandler from "../../utils/useModalHandler";
import { ModalEnum } from "../../enums/Model";
import ChangePasswordModel from "./model/AddModel";
import { getLocalStorage } from "../../utils/LocalStorage";
import { getPrevPathRoute } from "../../utils/getPrevPathRoute"; import { getPrevPathRoute } from "../../utils/getPrevPathRoute";
import { deletePathSegments } from "../../utils/deletePathSegments"; import { deletePathSegments } from "../../utils/deletePathSegments";
import SpinContainer from "../../Components/Layout/SpinContainer";
import NavBarRightSide from "../../Components/Layout/Navbar/NavBarRightSide";
// Lazy load the ChangePasswordModel
const ChangePasswordModel = lazy(() => import("./model/AddModel"));
const NavBar = () => { const NavBar = () => {
const { Page_title } = usePage_titleState((state) => state); const { PageTitle } = usePageTitleState((state) => state);
const userData = getLocalStorage(USER_KEY);
const [t] = useTranslation();
const location = useLocation(); const location = useLocation();
const translateArray = translateOptions(search_array, t);
const navigate = useNavigate(); const navigate = useNavigate();
const PrevPath = getPrevPathRoute(location.pathname); const PrevPath = getPrevPathRoute(location.pathname);
const handelNavigate = () => { const handelNavigate = () => {
if (PrevPath === 0) { if (PrevPath === 0) {
return 0; return;
} }
navigate(deletePathSegments(location.pathname, PrevPath)); navigate(deletePathSegments(location.pathname, PrevPath));
}; };
const { handel_open_model } = useModalHandler();
const handleEdit = (record: any) => {
handel_open_model(ModalEnum?.CHANGE_PASSWORD);
};
return ( return (
<div className="NavBar"> <div className="NavBar">
<span className="navbar_link" onClick={handelNavigate}> <span className="navbar_link" onClick={handelNavigate}>
<MdOutlineArrowForwardIos /> {Page_title} <MdOutlineArrowForwardIos /> {PageTitle}
</span> </span>
<article> <NavBarRightSide/>
<div className="header_search"> <Suspense fallback={<SpinContainer/>}>
{/* <NavBarSelect /> */} <ChangePasswordModel />
</Suspense>
<SearchField
options={translateArray}
placeholder={t("practical.search_here")}
/>
</div>
<span className="header_icons">
<div>
<Image src="/Icon/bell.png" />
</div>
<Tooltip
placement="top"
title={
<div onClick={handleEdit}>
{" "}
{t("header.change_your_current_password")}{" "}
</div>
}
color="#E0E0E0"
>
<div className="gear">
<Image src="/Icon/gear.png" />
</div>
</Tooltip>
</span>
<div className="header_profile">
<span>
<h6>{userData?.username}</h6>
<p>{userData?.type}</p>
</span>
<Image src="/Layout/DefultStudentImage.png" />
</div>
</article>
<ChangePasswordModel />
</div> </div>
); );
}; };

View File

@ -1,72 +1,16 @@
import React, { useState } from "react"; import React from "react";
import { Divider } from "antd"; import { Divider } from "antd";
import { Link, useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import { menuItems } from "../../Routes"; import { menuItems } from "../../Routes";
import { MdLogout, MdExpandMore, MdExpandLess } from "react-icons/md"; import { MdLogout } from "react-icons/md";
import useAuthState from "../../zustand/AuthState"; import useAuthState from "../../zustand/AuthState";
import { hasAbility } from "../../utils/hasAbility"; import { hasAbility } from "../../utils/hasAbility";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { getLocalStorage } from "../../utils/LocalStorage"; import { getLocalStorage } from "../../utils/LocalStorage";
import { BRANCH_OBJECT_KEY } from "../../config/AppKey"; import { BRANCH_OBJECT_KEY } from "../../config/AppKey";
import { MenuItem } from "../../Components/Layout/SideBar/MenuItem";
const MenuItem = ({ item, location, index }: any) => {
const isActive = location.pathname.split("/")[1] === item.path?.slice(1);
// console.log(location.pathname.split("/")[1]);
const [openDropdown, setOpenDropdown] = useState<number | null>(null);
const handleDropdown = (index: number) => {
setOpenDropdown((prev) => (prev === index ? null : index));
};
const isDropdownOpen = openDropdown === index;
const [t] = useTranslation();
const navigate = useNavigate();
return (
<>
<div
className={`link ${isActive ? "active" : ""} ${item?.children && "DropDownLink"} `}
onClick={() => navigate(item.path || "/")}
>
<i>{item.icon}</i>
<Link to={item.path || "/"}>{t(item.text)}</Link>
{item?.children && (
<>
{isDropdownOpen ? (
<div
className="DropDownIcon"
onClick={() => handleDropdown(index)}
>
<MdExpandLess />
</div>
) : (
<div
className="DropDownIcon"
onClick={() => handleDropdown(index)}
>
<MdExpandMore />
</div>
)}
</>
)}
</div>
{item?.children && isDropdownOpen && (
<div className="sub-menu">
{item.children.map((childItem: any, index: any) => (
<MenuItem
key={index}
item={childItem}
location={location}
index={index}
/>
))}
</div>
)}
</>
);
};
const SideBar = () => { const SideBar = () => {
const location = useLocation(); const location = useLocation();

View File

@ -5,7 +5,6 @@ import FormikForm from "../../../Layout/Dashboard/FormikFormModel";
import ModelBody from "./Add"; import ModelBody from "./Add";
import { getInitialValues, getValidationSchema } from "./formUtil"; import { getInitialValues, getValidationSchema } from "./formUtil";
import { ModalEnum } from "../../../enums/Model"; import { ModalEnum } from "../../../enums/Model";
import { useParams } from "react-router-dom";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useUpdateAdmin } from "../../../api/users"; import { useUpdateAdmin } from "../../../api/users";

View File

@ -26,7 +26,7 @@ const TableHeader = () => {
"/" + "/" +
`${SubjectName}` + `${SubjectName}` +
"/" + "/" +
t(`page_title.unit`) + t(`PageTitle.unit`) +
"/" + "/" +
`${unitName}`, `${unitName}`,
); );

View File

@ -59,15 +59,15 @@ const AddPage: React.FC = () => {
"/" + "/" +
`${SubjectName}` + `${SubjectName}` +
"/" + "/" +
t(`page_title.unit`) + t(`PageTitle.unit`) +
"/" + "/" +
`${unitName}` + `${unitName}` +
"/" + "/" +
t(`page_title.lesson`) + t(`PageTitle.lesson`) +
"/" + "/" +
`${lessonName}` + `${lessonName}` +
"/" + "/" +
t(`page_title.questions`), t(`PageTitle.questions`),
); );
const handleSubmit = ( const handleSubmit = (

View File

@ -70,15 +70,15 @@ const EditPage: React.FC = () => {
"/" + "/" +
`${SubjectName}` + `${SubjectName}` +
"/" + "/" +
t(`page_title.unit`) + t(`PageTitle.unit`) +
"/" + "/" +
`${unitName}` + `${unitName}` +
"/" + "/" +
t(`page_title.lesson`) + t(`PageTitle.lesson`) +
"/" + "/" +
`${lessonName}` + `${lessonName}` +
"/" + "/" +
t(`page_title.questions`), t(`PageTitle.questions`),
); );
const handleSubmit = (values: any) => { const handleSubmit = (values: any) => {

View File

@ -24,15 +24,15 @@ const TableHeader = () => {
"/" + "/" +
`${SubjectName}` + `${SubjectName}` +
"/" + "/" +
t(`page_title.unit`) + t(`PageTitle.unit`) +
"/" + "/" +
`${unitName}` + `${unitName}` +
"/" + "/" +
t(`page_title.lesson`) + t(`PageTitle.lesson`) +
"/" + "/" +
`${lessonName}` + `${lessonName}` +
"/" + "/" +
t(`page_title.questions`), t(`PageTitle.questions`),
); );
return ( return (

View File

@ -1,12 +1,12 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { FaArrowRight, FaPlus } from "react-icons/fa"; import { FaArrowRight, FaPlus } from "react-icons/fa";
import { useButtonState } from "../../../zustand/ButtonState"; import { useButtonState } from "../../../zustand/ButtonState";
import { usePage_titleState } from "../../../zustand/PageTitleState"; import { usePageTitleState } from "../../../zustand/PageTitleState";
const FillterNavWithRadio = () => { const FillterNavWithRadio = () => {
const [activeButton, setActiveButton] = useState(0); const [activeButton, setActiveButton] = useState(0);
const { setActiveTab } = useButtonState((state) => state); const { setActiveTab } = useButtonState((state) => state);
const { title } = usePage_titleState(); const { title } = usePageTitleState();
// Function to handle button click // Function to handle button click
const handleButtonClick = (index: number) => { const handleButtonClick = (index: number) => {

View File

@ -88,7 +88,7 @@
display: none !important; display: none !important;
} }
.Show_More_Button { .ShowMoreButton {
position: absolute; position: absolute;
bottom: 1vw; bottom: 1vw;
right: 0.5vw; right: 0.5vw;

View File

@ -9,14 +9,14 @@
.absence_icon { .absence_icon {
background-color: red; background-color: red;
} }
.lateArrival_icon { .late_arrival_icon {
background-color: orange; background-color: orange;
} }
.presence_icon { .presence_icon {
background-color: #31ce83 !important; background-color: #31ce83 !important;
} }
.earlyDeparture_Details { .earlyDepartureDetails {
// color: gray; // color: gray;
svg { svg {
color: #a098ae; color: #a098ae;
@ -33,7 +33,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.custom_add_button_column_Mark { .custom_add_button_column_mark {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -46,7 +46,7 @@
// font-size: 7px; // font-size: 7px;
// } // }
.column_studentBlock { .column_student_block {
width: 20px; width: 20px;
height: 20px; height: 20px;
border-radius: 4px; border-radius: 4px;
@ -72,16 +72,16 @@
border: 2px solid var(--absence); border: 2px solid var(--absence);
} }
.earlyDeparture_student { .earlyDepartureStudent {
background-color: var(--earlyDeparture); background-color: var(--earlyDeparture);
} }
.not_earlyDeparture_student { .not_earlyDepartureStudent {
border: 2px solid var(--earlyDeparture); border: 2px solid var(--earlyDeparture);
} }
.lateArrival_student { .lateArrivalStudent {
background-color: var(--lateArrival); background-color: var(--lateArrival);
} }
.not_lateArrival_student { .notLateArrivalStudent {
border: 2px solid var(--lateArrival); border: 2px solid var(--lateArrival);
} }

View File

@ -2,7 +2,7 @@
display: none !important; display: none !important;
} }
.Show_More_Button { .ShowMoreButton {
position: absolute; position: absolute;
bottom: 1vw; bottom: 1vw;
right: 0.5vw; right: 0.5vw;
@ -64,24 +64,13 @@
} }
} }
.activeModeltab { .activeModelTab {
> div { > div {
background: #bfe2fd; background: #bfe2fd;
color: black; color: black;
} }
} }
&::after {
z-index: 1;
position: absolute;
bottom: 0;
right: -2.4vw;
content: "";
background: url("../../../public/Icon/cercile.svg");
width: 15vw;
height: 15vw;
background-repeat: no-repeat;
}
} }
.ModelBodyForm { .ModelBodyForm {
padding: 2vw; padding: 2vw;

View File

@ -6,7 +6,7 @@
@import "./Course.scss"; @import "./Course.scss";
@import "./EduClass.scss"; @import "./EduClass.scss";
@import "./programme.scss"; @import "./programme.scss";
@import "./Coulmns.scss"; @import "./Columns.scss";
@import "./subject.scss"; @import "./subject.scss";
@import "./Marks.scss"; @import "./Marks.scss";
@import "./exercise.scss"; @import "./exercise.scss";

View File

@ -656,7 +656,7 @@
"some_thing_went_wrong": "حدث خطأ ما", "some_thing_went_wrong": "حدث خطأ ما",
"the_possess_done_successful": "تمت العملية بنجاح" "the_possess_done_successful": "تمت العملية بنجاح"
}, },
"page_title": { "PageTitle": {
"main_page": "الصفحة الرئيسية", "main_page": "الصفحة الرئيسية",
"course": "الصفوف", "course": "الصفوف",
"education_class": "الشعب", "education_class": "الشعب",

View File

@ -1,5 +1,6 @@
import { create } from "zustand"; import { create } from "zustand";
import { ABILITIES_KEY, TOKEN_KEY, USER_KEY } from "../config/AppKey"; import { ABILITIES_KEY, TOKEN_KEY, USER_KEY } from "../config/AppKey";
import { useNavigate } from "react-router-dom";
interface AuthStore { interface AuthStore {
token: string | null | undefined; token: string | null | undefined;

View File

@ -1,15 +1,15 @@
import { create } from "zustand"; import { create } from "zustand";
interface Page_titleState { interface PageTitleState {
Page_title: string; PageTitle: string;
setPage_title: (value: string) => void; setPageTitle: (value: string) => void;
title: string | null; title: string | null;
set_title: (value: string) => void; set_title: (value: string) => void;
} }
export const usePage_titleState = create<Page_titleState>((set) => ({ export const usePageTitleState = create<PageTitleState>((set) => ({
Page_title: "", PageTitle: "",
setPage_title: (value: string) => set(() => ({ Page_title: value })), setPageTitle: (value: string) => set(() => ({ PageTitle: value })),
title: null, title: null,
set_title: (value: string) => set(() => ({ title: value })), set_title: (value: string) => set(() => ({ title: value })),
})); }));