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 && (
<div
onClick={() => handleTabClick(index)}
className={`ModelBodyTab ${ActiveTab === index ? "activeModeltab" : ""}`}
className={`ModelBodyTab ${ActiveTab === index ? "activeModelTab" : ""}`}
key={index}
>
<div>{index + 1}</div>

View File

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

View File

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

View File

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

View File

@ -1,86 +1,40 @@
import React from "react";
import Image from "../../Components/Ui/Image";
import SearchField from "../../Components/DataTable/SearchFieldWithSelect";
import { usePage_titleState } from "../../zustand/PageTitleState";
import React, { lazy, Suspense } from "react";
import { usePageTitleState } from "../../zustand/PageTitleState";
import { MdOutlineArrowForwardIos } from "react-icons/md";
import { useLocation, useNavigate, useParams } 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 { useLocation, useNavigate } from "react-router-dom";
import { getPrevPathRoute } from "../../utils/getPrevPathRoute";
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 { Page_title } = usePage_titleState((state) => state);
const userData = getLocalStorage(USER_KEY);
const [t] = useTranslation();
const { PageTitle } = usePageTitleState((state) => state);
const location = useLocation();
const translateArray = translateOptions(search_array, t);
const navigate = useNavigate();
const PrevPath = getPrevPathRoute(location.pathname);
const handelNavigate = () => {
if (PrevPath === 0) {
return 0;
return;
}
navigate(deletePathSegments(location.pathname, PrevPath));
};
const { handel_open_model } = useModalHandler();
const handleEdit = (record: any) => {
handel_open_model(ModalEnum?.CHANGE_PASSWORD);
};
return (
<div className="NavBar">
<span className="navbar_link" onClick={handelNavigate}>
<MdOutlineArrowForwardIos /> {Page_title}
<MdOutlineArrowForwardIos /> {PageTitle}
</span>
<article>
<div className="header_search">
{/* <NavBarSelect /> */}
<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>
<NavBarRightSide/>
<Suspense fallback={<SpinContainer/>}>
<ChangePasswordModel />
</Suspense>
</div>
);
};

View File

@ -1,72 +1,16 @@
import React, { useState } from "react";
import React from "react";
import { Divider } from "antd";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { useLocation, useNavigate } from "react-router-dom";
import { menuItems } from "../../Routes";
import { MdLogout, MdExpandMore, MdExpandLess } from "react-icons/md";
import { MdLogout } from "react-icons/md";
import useAuthState from "../../zustand/AuthState";
import { hasAbility } from "../../utils/hasAbility";
import { useTranslation } from "react-i18next";
import { getLocalStorage } from "../../utils/LocalStorage";
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 location = useLocation();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
display: none !important;
}
.Show_More_Button {
.ShowMoreButton {
position: absolute;
bottom: 1vw;
right: 0.5vw;
@ -64,24 +64,13 @@
}
}
.activeModeltab {
.activeModelTab {
> div {
background: #bfe2fd;
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 {
padding: 2vw;

View File

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

View File

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

View File

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

View File

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