Compare commits

...

2 Commits

Author SHA1 Message Date
karimalden
b873ac0bba format 2024-08-07 14:52:29 +03:00
karimalden
a4c3459efa remove file 2024-08-07 14:47:50 +03:00
222 changed files with 7426 additions and 8602 deletions

File diff suppressed because one or more lines are too long

View File

@ -5,18 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" sizes="180x180" href="/App/Logo.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/App/Logo.png" />
<link <link rel="icon" type="image/png" sizes="32x32" href="/App/Logo.png" />
rel="icon" <link rel="icon" type="image/png" sizes="16x16" href="/App/Logo.png" />
type="image/png"
sizes="32x32"
href="/App/Logo.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/App/Logo.png"
/>
<link rel="manifest" href="/site.webmanifest" /> <link rel="manifest" href="/site.webmanifest" />
<meta <meta
name="description" name="description"

View File

@ -1,6 +1,7 @@
{ {
"name": "my-app", "name": "my-app",
"version": "0.1.0", "version": "0.1.0",
"type": "module",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.3.7", "@ant-design/icons": "^5.3.7",

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -17,7 +17,7 @@ const App = () => {
const { changeLanguage } = useChangeLanguage(); const { changeLanguage } = useChangeLanguage();
const navigate = useNavigate(); const navigate = useNavigate();
const { isAuthenticated } = useAuthState(); const { isAuthenticated } = useAuthState();
const [t] = useTranslation() const [t] = useTranslation();
useEffect(() => { useEffect(() => {
if (!isAuthenticated) { if (!isAuthenticated) {
@ -26,7 +26,14 @@ const App = () => {
}, [isAuthenticated, navigate]); }, [isAuthenticated, navigate]);
const renderRouteElement = (route: any) => ( const renderRouteElement = (route: any) => (
<Suspense fallback={<Layout> <SpinContainer/> </Layout>}> <Suspense
fallback={
<Layout>
{" "}
<SpinContainer />{" "}
</Layout>
}
>
{route.header ? ( {route.header ? (
<Layout>{route.element}</Layout> <Layout>{route.element}</Layout>
) : ( ) : (
@ -35,11 +42,11 @@ const App = () => {
</Suspense> </Suspense>
); );
const renderRoutesRecursively = (routes:TMenuItem[]) => const renderRoutesRecursively = (routes: TMenuItem[]) =>
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); // useSetPageTitle(tableHeader,route?.path);
if (useAbility) { if (useAbility) {
return ( return (
@ -80,7 +87,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); // useSetPageTitle(tableHeader,route?.path);
if (!useAbility) { if (!useAbility) {
return false; return false;

View File

@ -1,58 +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: "datetime",
categories: [
"2018-09-19T00:00:00.000Z",
"2018-09-19T01:30:00.000Z",
"2018-09-19T02:30:00.000Z",
"2018-09-19T03:30:00.000Z",
"2018-09-19T04:30:00.000Z",
"2018-09-19T05:30:00.000Z",
"2018-09-19T06:30:00.000Z",
],
},
tooltip: {
x: {
format: "dd/MM/yy HH:mm",
},
},
});
const [series, setSeries] = useState<any>([
{ name: "series1", data: [31, 40, 28, 51, 42, 109, 100], color: "#FCC43E" },
{ name: "series2", data: [11, 32, 45, 32, 34, 52, 41], color: "#FB7D5B" },
]);
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,95 +0,0 @@
import { Radio, Select } from "antd";
import React, { useState } from "react";
import ReactApexChart from "react-apexcharts";
import { IoMdArrowDropdown } from "react-icons/io";
const ColumnChart: React.FC = () => {
const series = [
{
name: "غياب",
data: [44, 55, 57, 56, 61, 58],
color: "#FB7D5B",
},
{
name: "حضور",
data: [76, 85, 70, 98, 87, 80],
color: "#FCC43E",
},
];
const options: any = {
chart: {
type: "bar",
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: "35%",
endingShape: "rounded",
},
},
dataLabels: {
enabled: false,
},
xaxis: {
categories: ["Feb", "Mar", "Apr", "May", "Jun", "Jul"],
},
// yaxis: {
// title: {
// text: '$ (thousands)'
// }
// },
fill: {
opacity: 1,
colors: ["#FB7D5B", "#FCC43E"], // Red and Green colors
},
tooltip: {
y: {
formatter: function (val: number) {
return val + " طالب";
},
},
},
legend: {
show: false, // Hide the legend
},
};
const [value, setValue] = useState(1);
const handleChangeSelect = (value: string) => {};
return (
<div className="ColumnChart">
<div className="ColumnChart_header">
<span>الغياب المتكرر</span>
<span className="Legend">
<div data-attr="red">غياب</div>
<div>حضور</div>
</span>
<Select
defaultValue="هذا الأسبوع"
onChange={handleChangeSelect}
suffixIcon={<IoMdArrowDropdown size={30} />}
options={[
{ value: "هذا الأسبوع", label: "هذا الأسبوع" },
{ value: "هذا الأسبوع", label: "هذا الأسبوع" },
{ value: "هذا الأسبوع", label: "هذا الأسبوع" },
]}
/>
</div>
<div className="ColumnChartWrapper" id="chart">
<ReactApexChart
options={options}
series={series}
type="bar"
height={"100%"}
/>
</div>
<div id="html-dist"></div>
</div>
);
};
export default ColumnChart;

View File

@ -1,61 +0,0 @@
import React from "react";
import Chart from "react-apexcharts";
const LineChart: React.FC = () => {
const series = [
{
name: "Desktops",
data: [10, 41, 35, 51, 49, 62, 69, 91, 148],
},
];
const options: any = {
chart: {
height: 350,
type: "line",
zoom: {
enabled: false,
},
},
dataLabels: {
enabled: false,
},
stroke: {
curve: "straight",
},
title: {
text: "Product Trends by Month",
align: "left",
},
grid: {
row: {
colors: ["#f3f3f3", "transparent"], // takes an array which will be repeated on columns
opacity: 0.5,
},
},
xaxis: {
categories: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
],
},
};
return (
<div>
<div id="chart">
<Chart options={options} series={series} type="line" height={350} />
</div>
<div id="html-dist"></div>
</div>
);
};
export default LineChart;

View File

@ -1,38 +0,0 @@
import React from "react";
import Chart from "react-apexcharts";
const PieChart = () => {
const series = [44, 55, 13] as any;
const options: any = {
series: [44, 55, 13],
chart: {
width: 380,
type: "pie",
},
labels: ["Team A", "Team B", "Team C", "Team D", "Team E"],
legend: {
position: "bottom",
},
responsive: [
{
breakpoint: 480,
options: {
chart: {
width: 200,
},
legend: {
position: "bottom",
},
},
},
],
};
return (
<div id="chart">
<Chart options={options} series={series} type="pie" width={380} />
</div>
);
};
export default PieChart;

View File

@ -1,14 +0,0 @@
import React from "react";
import { Segmented } from "antd";
const ClassesSegmented: React.FC = () => (
<Segmented<string>
options={["الأحد", "اللإثنين", "الثلاثاء", "الأربعاء", "الخميس"]}
onChange={(value) => {}}
className="Segmented"
block
defaultChecked
/>
);
export default ClassesSegmented;

View File

@ -1,105 +0,0 @@
import React, { useState } from "react";
import { FaPlus, FaUser } from "react-icons/fa";
import { IoMdArrowDropdown, IoMdArrowDropup } from "react-icons/io";
import { useNavigate } from "react-router-dom";
import { Popover, Spin } from "antd";
import { CourseItem } from "../../types/Item";
import { ModalEnum } from "../../enums/Model";
import useModalHandler from "../../utils/useModalHandler";
import { FaEllipsis } from "react-icons/fa6";
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
import { hasAbility } from "../../utils/hasAbility";
import { useTranslation } from "react-i18next";
const HeaderCardsSection = ({ data, isLoading }: any) => {
const [showAll, setShowAll] = useState<boolean>(false);
const [t] = useTranslation();
const toggleShowAll = () => {
setShowAll(!showAll);
};
const navigate = useNavigate();
const index_eduClass_ability = hasAbility(
ABILITIES_ENUM?.EDUCATION_CLASS,
ABILITIES_VALUES_ENUM?.INDEX,
);
const handelnavigate = (item: CourseItem) => {
if (index_eduClass_ability) {
navigate(
`/${ABILITIES_ENUM?.COURSE}/${item?.id}/${ABILITIES_ENUM?.EDUCATION_CLASS}`,
);
// set_title(item?.name);
}
};
const { handel_open_model } = useModalHandler();
const Courses = data?.data || [];
if (isLoading) {
return <Spin />;
}
const PopoverContent = (
<div className="PopoverContent">
<p onClick={() => handel_open_model(ModalEnum?.COURSE_ADD)}>
{" "}
{t("practical.add")} {t("models.course")} <FaPlus />{" "}
</p>
</div>
);
const store_course_ability = hasAbility(
ABILITIES_ENUM?.COURSE,
ABILITIES_VALUES_ENUM?.STORE,
);
return (
<div className="header_cards_section">
<div className="CountCards">
{Courses?.length > 0 &&
Courses?.map((item: CourseItem, index: number) => {
return (
<div
onClick={() => handelnavigate(item)}
key={item?.id}
className={`CountCard ${!showAll && index >= 6 ? "hidden" : ""}`}
>
<i>
<FaUser />
</i>
<h4>{item?.name}</h4>
<h5>
{item?.student_count} {t("models.student")}{" "}
</h5>
</div>
);
})}
</div>
{Courses?.length > 4 &&
(showAll ? (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropup />
</span>
) : (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropdown />
</span>
))}
{store_course_ability && (
<Popover
content={PopoverContent}
overlayClassName="Popover"
arrow={false}
placement="bottomRight"
trigger={"click"}
>
<FaEllipsis />
</Popover>
)}
</div>
);
};
export default HeaderCardsSection;

View File

@ -1,67 +0,0 @@
import React, { useState } from "react";
import { useModalState } from "../../zustand/Modal";
import { ModalEnum } from "../../enums/Model";
import { FaMoneyBill } from "react-icons/fa";
import { IoMdArrowDropdown, IoMdArrowDropup } from "react-icons/io";
const DivisionsHeaderSection = () => {
const [showAll, setShowAll] = useState<boolean>(false);
const toggleShowAll = () => {
setShowAll(!showAll);
};
const { isOpen, setIsOpen } = useModalState((state) => state);
const handelOpenModal = () => {
setIsOpen(ModalEnum?.DIVISION_ADD);
};
// Define the interface for your data
interface Item {
icon: JSX.Element;
name: string;
}
const data: Item[] = [
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
{ icon: <FaMoneyBill />, name: "الطالبات" },
];
return (
<div className="Divisions_header_section">
<div className="CountCards">
{data?.map((item: Item, index: number) => {
return (
<div
key={index}
className={`CountCard ${!showAll && index >= 5 ? "hidden" : ""}`}
>
<i>{item?.icon}</i>
<h4>{item?.name}</h4>
</div>
);
})}
</div>
{showAll ? (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropup />
</span>
) : (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropdown />
</span>
)}
<button className="Add_button" onClick={handelOpenModal}>
إضافة مادة
</button>
</div>
);
};
export default DivisionsHeaderSection;

View File

@ -1,128 +0,0 @@
import React, { useState } from "react";
import { ModalEnum } from "../../enums/Model";
import { FaPlus, FaUser } from "react-icons/fa";
import { IoMdArrowDropdown, IoMdArrowDropup } from "react-icons/io";
import { FaEllipsis } from "react-icons/fa6";
import { Popover, Spin } from "antd";
import { useGetAllEduClass } from "../../api/eduClass";
import { useNavigate, useParams } from "react-router-dom";
import { EduClassItem } from "../../types/Item";
import useModalHandler from "../../utils/useModalHandler";
import { usePage_titleState } from "../../zustand/PageTitleState";
import { hasAbility } from "../../utils/hasAbility";
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
import { useTranslation } from "react-i18next";
const HeaderSection = () => {
const [showAll, setShowAll] = useState<boolean>(false);
const toggleShowAll = () => {
setShowAll(!showAll);
};
const { course_id } = useParams();
const { data, isLoading } = useGetAllEduClass({ course_id: course_id });
const eduClass = data?.data || [];
const { set_title } = usePage_titleState((state) => state);
const { handel_open_model } = useModalHandler();
const navigate = useNavigate();
const show_eduClass_ability = hasAbility(
ABILITIES_ENUM?.EDUCATION_CLASS,
ABILITIES_VALUES_ENUM?.SHOW,
);
const handelNavigate = (item: EduClassItem) => {
if (show_eduClass_ability) {
navigate(`${item?.id}`);
set_title(`${item?.name}`);
}
};
const [t] = useTranslation();
const store_eduClass_ability = hasAbility(
ABILITIES_ENUM?.EDUCATION_CLASS,
ABILITIES_VALUES_ENUM?.STORE,
);
const delete_course_ability = hasAbility(
ABILITIES_ENUM?.COURSE,
ABILITIES_VALUES_ENUM?.DELETE,
);
const store_note_ability = hasAbility(
ABILITIES_ENUM?.NOTE,
ABILITIES_VALUES_ENUM?.STORE,
);
const PopoverContent = (
<div className="PopoverContent">
{store_eduClass_ability && (
<p onClick={() => handel_open_model(ModalEnum?.EDUClASS_ADD)}>
{" "}
{t("practical.add")} {t("models.education_class")} <FaPlus />{" "}
</p>
)}
{store_note_ability && (
<p
onClick={() => handel_open_model(ModalEnum?.COURSE_SENDNOTIFICATION)}
>
{" "}
{t("practical.Send_Direct_Notification")}
</p>
)}
{delete_course_ability && (
<p onClick={() => handel_open_model(ModalEnum?.COURSE_DELETE)}>
{" "}
{t("practical.delete")} {t("models.course")}
</p>
)}
</div>
);
if (isLoading) {
return <Spin />;
}
return (
<div className="header_cards_section">
<div className="CountCards">
{eduClass?.map((item: EduClassItem, index: number) => {
return (
<div
onClick={() => handelNavigate(item)}
key={index}
className={`CountCard ${!showAll && index >= 6 ? "hidden" : ""}`}
>
<i>
<FaUser />
</i>
<h4>{item?.name}</h4>
<h5>
{item?.students_count} {t("models.student")}{" "}
</h5>
</div>
);
})}
</div>
{eduClass?.length > 4 &&
(showAll ? (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropup />
</span>
) : (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropdown />
</span>
))}
<Popover
content={PopoverContent}
overlayClassName="Popover"
arrow={false}
placement="bottomRight"
>
<FaEllipsis />
</Popover>
</div>
);
};
export default HeaderSection;

View File

@ -1,103 +0,0 @@
import React, { useState } from "react";
import { ModalEnum } from "../../enums/Model";
import { FaUser } from "react-icons/fa";
import { IoMdArrowDropdown, IoMdArrowDropup } from "react-icons/io";
import { FaEllipsis } from "react-icons/fa6";
import { Popover } from "antd";
import { useLocation, useNavigate } from "react-router-dom";
import { Item } from "../../types/Item";
import useModalHandler from "../../utils/useModalHandler";
import { useButtonState } from "../../zustand/ButtonState";
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
import { useTranslation } from "react-i18next";
import { ABILITIES_VALUES_ENUM } from "../../enums/abilities";
// import useSetPage_title from "../../Hooks/useSetPageTitle";
import { EduClassComponents } from "../../Pages/EduClass/show/ActiveTable";
import { hasAbility } from "../../utils/hasAbility";
const HeaderSection = () => {
const [showAll, setShowAll] = useState<boolean>(true);
const toggleShowAll = () => {
setShowAll(!showAll);
};
const [t] = useTranslation();
// useSetPage_title(
// `${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t(`models.${ABILITIES_ENUM.COURSE}`)} / ${t(`models.${ABILITIES_ENUM.EDUCATION_CLASS}`)} / ${t(`input.details`)}`,
// );
const { handel_open_model } = useModalHandler();
const filteredComponents = EduClassComponents?.filter((component) =>
hasAbility(component.abilities, ABILITIES_VALUES_ENUM.INDEX),
);
const PopoverContent = (
<div className="PopoverContent">
<p
onClick={() => handel_open_model(ModalEnum?.EDUClASS_SENDNOTIFICATION)}
>
{" "}
{t("practical.Send_Direct_Notification")}
</p>
<p onClick={() => handel_open_model(ModalEnum?.EDUClASS_DELETE)}>
{" "}
{t("practical.delete")} {t("models.education_class")}
</p>
</div>
);
const [, setActiveButton] = useState(0);
const { setActiveTab, ActiveTab } = useButtonState((state) => state);
const { setParamToSend } = useObjectToEdit();
const location = useLocation();
const navigate = useNavigate();
const handleButtonClick = (index: number) => {
setActiveButton(index);
setActiveTab(index);
setParamToSend({});
navigate(`${location.pathname}`);
};
return (
<div className="header_cards_section">
<div className="CountCards">
{filteredComponents?.map((item: Item, index: number) => {
return (
<div
key={index}
onClick={() => handleButtonClick(index)}
className={`CountCard ${!showAll && index >= 6 ? "hidden" : ""} ${ActiveTab === index ? "active" : ""} `}
>
<i>
<FaUser />
</i>
<h4> {t(`education_class_actions.${item?.name}`)} </h4>
</div>
);
})}
</div>
{filteredComponents?.length > 4 &&
(showAll ? (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropup />
</span>
) : (
<span className="Show_More_Button" onClick={toggleShowAll}>
<IoMdArrowDropdown />
</span>
))}
<Popover
content={PopoverContent}
overlayClassName="Popover"
arrow={false}
placement="bottomRight"
>
<FaEllipsis />
</Popover>
</div>
);
};
export default HeaderSection;

View File

@ -1,21 +0,0 @@
import { Col, Row } from "reactstrap";
import React from "react";
import ValidationField from "../../../../ValidationField/ValidationField";
const AttachmentsDetails = () => {
return (
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col xs="6" sm="6">
<ValidationField
name="attachment1"
type="DropFile"
label="school_document"
/>
{/* <ValidationField name='attachment2' type='DropFile' label='الوثيقة'/> */}
</Col>
<Col xs="6" sm="6"></Col>
</Row>
);
};
export default AttachmentsDetails;

View File

@ -1,36 +0,0 @@
import { Col, Row } from "reactstrap";
import React from "react";
import ValidationField from "../../../../ValidationField/ValidationField";
const ContactDetails = () => {
return (
<div className="bigRow">
<ValidationField
type="number"
name="phone_number_1"
label="phone_number"
/>
<ValidationField
type="number"
name="phone_number_2"
label="additional_phone_number"
/>
<ValidationField
type="TextArea"
name="address"
label="address"
placeholder="address"
/>
<ValidationField
type="TextArea"
name="notes"
label="note"
placeholder="note"
/>
</div>
);
};
export default ContactDetails;

View File

@ -1,34 +0,0 @@
import { Col, Row } from "reactstrap";
import React, { useRef } from "react";
import ValidationField from "../../../../ValidationField/ValidationField";
const ParentDetails = () => {
const handelClick = () => {};
return (
<div className="bigRow">
<ValidationField name="father_name" label="father_name" />
<ValidationField name="father_job" label="father_job" />
<ValidationField
type="number"
name="father_phone_number"
label="father_phone_number"
/>
<ValidationField name="mother_name" label="mother_name" />
<ValidationField name="mother_job" label="mother_job" />
<ValidationField
type="number"
name="mother_phone_number"
label="mother_phone_number"
/>
{/* <Col xs="8" sm="8">
</Col> */}
</div>
);
};
export default ParentDetails;

View File

@ -1,72 +0,0 @@
import { Col, Row } from "reactstrap";
import React from "react";
import ValidationField from "../../../../ValidationField/ValidationField";
import {
Sex_Select_options_Student,
nationalities,
religion_Select_options,
} from "../../../../../types/App";
const PersonalDetails = () => {
return (
<Row>
<Col xs="8" sm="8">
<ValidationField name="email" label="email" />
<div className="TowValidationItems">
<ValidationField name="first_name" label="first_name" />
<ValidationField name="last_name" label="last_name" />
</div>
<div className="TowValidationItems">
<ValidationField name="username" label="username" />
<ValidationField name="password" label="password" />
</div>
<div className="TowValidationItems">
<ValidationField
name="nationality"
type="LocalSearch"
option={nationalities}
label="nationality"
placeholder="nationality"
/>
<ValidationField
name="religion"
type="Select"
option={religion_Select_options}
no_label
placeholder="religion"
/>
</div>
<div className="TowValidationItems">
<ValidationField
name="birthday"
type="Date"
label="birthday"
placeholder="birthday"
/>
<ValidationField
name="birth_place"
no_label
placeholder="birth_place"
/>
</div>
<ValidationField
name="sex"
label="sex"
type="Select"
option={Sex_Select_options_Student}
placeholder="sex"
/>
</Col>
<Col xs="4" sm="4">
<ValidationField name="image" type="DropFile" label="image" />
</Col>
</Row>
);
};
export default PersonalDetails;

View File

@ -1,46 +0,0 @@
import React from "react";
import Image from "../../../../Ui/Image";
import { useModalTabsState } from "../../../../../zustand/ModalTabsState";
import { useModalState } from "../../../../../zustand/Modal";
import { useFormikContext } from "formik";
import { useTranslation } from "react-i18next";
const Successful = () => {
const { setActiveTab } = useModalTabsState((state) => state);
const { setIsOpen } = useModalState((state) => state);
const formik = useFormikContext<any>();
const [t] = useTranslation();
return (
<div className="AddedSuccessfully">
<Image src="/DataState/successfully.png" />
<h1> {t("header.Student_added_successfully")} </h1>
<p>
{t(
"header.the_student_has_been_added_Do_you_want_to_add_another_student",
)}
</p>
<div className="TowButton">
<button
onClick={() => {
setActiveTab(0);
formik?.resetForm();
}}
>
{t("header.Add_a_new_student")}
</button>
<button
onClick={() => {
setIsOpen("");
setActiveTab(0);
formik?.resetForm();
}}
>
{t("practical.skip")}
</button>
</div>
</div>
);
};
export default Successful;

View File

@ -1,80 +0,0 @@
import React, { useEffect } from "react";
import { Modal } from "antd";
import { useModalState } from "../../../../../zustand/Modal";
import FormikForm from "../../../../../Layout/Dashboard/FormikForm";
import ModelBody from "./ModelBody";
import TabsSubmite from "./TabsSubmite";
import { getInitialValues, getValidationSchema } from "./formUtil";
import { ModalEnum } from "../../../../../enums/Model";
import { useAddStudent } from "../../../../../api/student";
import { useParams } from "react-router-dom";
import { useModalTabsState } from "../../../../../zustand/ModalTabsState";
const ModalForm: React.FC = () => {
const { isOpen, setIsOpen } = useModalState((state) => state);
const { mutate, isSuccess, isLoading } = useAddStudent();
const { edu_class_id } = useParams();
const handleSubmit = (values: any) => {
const Data_To_Send = { ...values };
delete Data_To_Send["id"];
Data_To_Send.attachments = [];
if (Data_To_Send.attachment1 !== null) {
Data_To_Send.attachments.push({
name: "attachment1",
file: Data_To_Send.attachment1,
});
}
if (Data_To_Send.attachment2 !== null) {
Data_To_Send.attachments.push({
name: "attachment2",
file: Data_To_Send.attachment2,
});
}
Data_To_Send["edu_class_id"] = edu_class_id;
Data_To_Send["birthday"] = values.birthday?.format(
"YYYY-MM-DD HH:mm:ss.SSS",
);
if (!values?.attachment1) {
delete Data_To_Send["attachments"];
}
// console.log(Data_To_Send);
mutate(Data_To_Send);
};
const { setActiveTab } = useModalTabsState((state) => state);
useEffect(() => {
if (isSuccess) {
setActiveTab(4);
getInitialValues([]);
}
}, [isSuccess, setActiveTab]);
return (
<>
<Modal
className="AddModalForm"
centered
width={"80vw"}
footer={null}
open={isOpen === ModalEnum.STUDENT_ADD}
onOk={() => setIsOpen("")}
onCancel={() => setIsOpen("")}
>
<FormikForm
handleSubmit={handleSubmit}
initialValues={getInitialValues([])}
validationSchema={getValidationSchema}
>
<ModelBody />
<TabsSubmite isLoading={isLoading} steps={4} />
</FormikForm>
</Modal>
</>
);
};
export default ModalForm;

View File

@ -1,67 +0,0 @@
import PersonalDetails from "../Form/PersonalDetails";
import TabsBar from "../../../../Layout/Tabs/TabsBar";
import ActiveTabs from "../../../../Layout/Tabs/ActiveTabs";
import { usePage_titleState } from "../../../../../zustand/PageTitleState";
import ParentDetails from "../Form/ParentDetails";
import ContactDetails from "../Form/ContactDetails";
import AttachmentsDetails from "../Form/AttachmentsDetails";
import Successful from "../Form/Successful";
import { useModalState } from "../../../../../zustand/Modal";
import { useFormikContext } from "formik";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
const ModelBody = () => {
const { title } = usePage_titleState((state) => state);
const [t] = useTranslation();
const steps = [
{
title: `${t(`practical.Step`)} 1`,
description: t("header.Student_Information"),
component: <PersonalDetails />,
},
{
title: `${t(`practical.Step`)} 2`,
description: t("header.Parent_Information"),
component: <ParentDetails />,
},
{
title: `${t(`practical.Step`)} 3`,
description: t("header.Contact_Information"),
component: <ContactDetails />,
},
{
title: `${t(`practical.Step`)} 4`,
description: t("header.Attachment_Images"),
component: <AttachmentsDetails />,
},
{
title: "hidden",
description: "hidden",
hidden: true,
component: <Successful />,
},
];
const { isOpen } = useModalState((state) => state);
const formik = useFormikContext();
useEffect(() => {
formik.setErrors({});
}, [isOpen === ""]);
return (
<div className="ModelBody">
<TabsBar steps={steps} />
<div className="ModelBodyForm">
<header>
{" "}
{t("practical.add")} {t("models.student")}{" "}
{" " + title === null ? "" : title}{" "}
</header>
<ActiveTabs steps={steps} />
</div>
</div>
);
};
export default ModelBody;

View File

@ -1,128 +0,0 @@
import React, { useEffect } from "react";
import { useModalTabsState } from "../../../../../zustand/ModalTabsState";
import { useModalState } from "../../../../../zustand/Modal";
import { useFormikContext } from "formik";
import { toast } from "react-toastify";
import { Spin } from "antd";
import { useTranslation } from "react-i18next";
interface TabsSubmiteProps {
steps: number;
isLoading: boolean;
}
const TabsSubmite: React.FC<TabsSubmiteProps> = ({ steps, isLoading }) => {
const { values, isValid, submitForm } = useFormikContext<any>();
const { ActiveTab, setActiveTab } = useModalTabsState((state) => state);
const IsSubmite = ActiveTab + 1 !== steps;
const {
first_name,
last_name,
username,
password,
nationality,
religion,
birthday,
birth_place,
sex,
} = values;
const {
father_name,
father_job,
father_phone_number,
mother_name,
mother_job,
mother_phone_number,
} = values;
const { address, attachment1 } = values;
const is_1_valued =
first_name &&
username &&
last_name &&
password &&
nationality &&
religion &&
birthday &&
birth_place &&
sex;
const is_2_valued =
father_name &&
father_job &&
father_phone_number &&
mother_name &&
mother_job &&
mother_phone_number;
const is_3_valued = address;
const is_4_valued = attachment1;
const [t] = useTranslation();
function handelNext() {
// console.log("submited");
// console.log(isValid,"isValid");
if (!is_1_valued && Number(ActiveTab) === 0) {
toast.error(t("validation.pleas_fill_all_label"));
return;
}
if (!is_2_valued && Number(ActiveTab) === 1) {
toast.error(t("validation.pleas_fill_all_label"));
return;
}
if (!is_3_valued && Number(ActiveTab) === 2) {
toast.error(t("validation.pleas_fill_all_label"));
return;
}
if (!is_4_valued && Number(ActiveTab) === 3) {
toast.error(t("validation.pleas_fill_all_label"));
return;
}
if (Number(ActiveTab) >= steps) {
return;
}
setActiveTab(Number(ActiveTab) + 1);
}
function handelPre() {
setActiveTab(Number(ActiveTab) - 1);
}
const handleSubmit = () => {
if (isValid) {
submitForm();
} else {
submitForm();
// console.log('Validation errors:', formik.errors);
// setActiveTab(4)
toast.error(t("validation.pleas_fill_all_label"));
}
};
// console.log(ActiveTab,"ActiveTab");
if (ActiveTab === steps) {
return <></>;
}
return (
<div className="SubmitButton">
<div onClick={handelPre}>
{ActiveTab > 0 ? "رجوع للخطوة السابقة" : ""}
</div>
<span
onClick={isLoading ? undefined : IsSubmite ? handelNext : handleSubmit}
{...(!IsSubmite && !isLoading ? { type: "submit" } : {})}
>
{isLoading
? "جار الاضافة ...."
: IsSubmite
? "الخطوة التالية"
: "إضافة الطالب"}
</span>
</div>
);
};
export default TabsSubmite;

View File

@ -1,76 +0,0 @@
import * as Yup from "yup";
export const getInitialValues = (objectToEdit: any): any => {
return {
id: objectToEdit?.id ?? null,
// username:objectToEdit?.username ?? null ,
email: objectToEdit?.email ?? "",
username: objectToEdit?.username ?? null,
password: objectToEdit?.password ?? null,
notes: objectToEdit?.notes ?? null,
image: objectToEdit?.image ?? null,
nationality: objectToEdit?.nationality ?? null,
birth_place: objectToEdit?.birth_place ?? null,
birthday: objectToEdit?.birthday ?? null,
phone_number_2: objectToEdit?.phone_number_2 ?? null,
phone_number_1: objectToEdit?.phone_number_1 ?? null,
mother_name: objectToEdit?.mother_name ?? null,
father_name: objectToEdit?.father_name ?? null,
last_name: objectToEdit?.last_name ?? null,
first_name: objectToEdit?.first_name ?? null,
religion: objectToEdit?.religion ?? null,
attachments: objectToEdit?.attachments ?? null,
attachment1: objectToEdit?.attachment1 ?? null,
attachment2: objectToEdit?.attachment2 ?? null,
address: objectToEdit?.address ?? null,
father_job: objectToEdit?.father_job ?? null,
mother_phone_number: objectToEdit?.mother_phone_number ?? null,
father_phone_number: objectToEdit?.father_phone_number ?? null,
mother_job: objectToEdit?.mother_job ?? null,
edu_class_id: objectToEdit?.edu_class_id ?? null,
sex: objectToEdit?.sex ?? null,
};
};
export const getValidationSchema = () => {
return Yup.object().shape({
// username: Yup.string().required('Username is required'),
email: Yup.string().email("validation.Invalid_email"),
username: Yup.string().required("validation.required"),
// .required("validation.Email_is_required"),
password: Yup.string()
.required("validation.Password_is_required")
.min(8, "validation.Password_must_be_at_least_8_characters_long"),
// notes: Yup.string(),
// image: Yup.string().required(),
nationality: Yup.string().required("validation.Nationality_is_required"),
address: Yup.string().required("validation.Address_is_required"),
birth_place: Yup.string().required("validation.Place_of_birth_is_required"),
birthday: Yup.string().required("validation.Date_of_birth_is_required"),
// phone_number_2: Yup.number(),
// phone_number_1: Yup.number(),
mother_name: Yup.string().required("validation.Mother's_name_is_required"),
father_name: Yup.string().required("validation.Father's_name_is_required"),
last_name: Yup.string().required("validation.Last_name_is_required"),
first_name: Yup.string().required("validation.First_name_is_required"),
religion: Yup.string().required("validation.Religion_is_required"),
sex: Yup.string().required("validation.Gender_is_required"),
// attachments: Yup.string(),
// attachment1: Yup.string(),
// attachment2: Yup.string(),
// attachment1: Yup.string().required("validation.Attachment1_is_required"),
father_job: Yup.string().required("validation.Father's_job_is_required"),
// mother_phone_number: Yup.string().required(
// "validation.Mother's_phone_number_is_required",
// ),
father_phone_number: Yup.string().required(
"validation.Father's_phone_number_is_required",
),
// mother_job: Yup.string().required("validation.Mother's_job_is_required"),
});
};

View File

@ -1,48 +0,0 @@
import React, { useState, ReactNode } from "react";
import type { DrawerProps } from "antd";
import { Drawer, Space } from "antd";
interface WithDrawerProps {
button: React.ReactNode;
children: ReactNode;
title: string;
className?: string;
}
const WithDrawer: React.FC<WithDrawerProps> = ({
button,
children,
title = "Basic Drawer",
className,
}) => {
const [open, setOpen] = useState(false);
const [placement, setPlacement] = useState<DrawerProps["placement"]>("right");
return (
<>
<Space>
{React.cloneElement(button as React.ReactElement, {
onClick: () => setOpen(true),
})}
</Space>
<Drawer
title={title}
placement={placement}
closable={false}
onClose={() => setOpen(false)}
open={open}
key={placement}
>
<div className={className}>{children}</div>
</Drawer>
</>
);
};
export default WithDrawer;
// <WithDrawer
// button={<Button type="primary">Open</Button>}
// >
// {/* Your content goes here */}
// </WithDrawer>

View File

@ -1,28 +0,0 @@
import { Form, Formik } from "formik";
import React from "react";
import * as Yup from "yup";
const WithFormik = ({ children }: any) => {
const getInitialValues = () => {
return { name: "" };
};
const getValidationSchema = () => {
return Yup.object().shape({});
};
const handleSubmit = () => {};
return (
<div className="WithFormik">
{
<Formik
onSubmit={handleSubmit}
initialValues={getInitialValues}
validationSchema={getValidationSchema}
>
{(formik) => <Form>{children}</Form>}
</Formik>
}
</div>
);
};
export default WithFormik;

View File

@ -1,32 +0,0 @@
import { useEffect, useRef, useState } from "react";
// This is your Layout Component
const Visibale = ({ children, ...props }: any) => {
const ref = useRef<any>();
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
if (isVisible === false) {
setIsVisible(entry.isIntersecting);
}
});
if (ref.current) {
observer.observe(ref.current);
}
return () => {
if (ref.current) {
// eslint-disable-next-line react-hooks/exhaustive-deps
observer.unobserve(ref.current);
}
};
}, [isVisible]); // Empty array ensures effect is only run on mount and unmount
return (
<div ref={ref} {...props}>
{isVisible && children}
</div>
);
};
export default Visibale;

View File

@ -1,59 +0,0 @@
import React from "react";
import Image from "../Ui/Image";
const ActivitySection = () => {
// Static fake data array
const ActivitysData = [
{
id: 1,
image: "/Image/1.png",
info: "3 طالبات حصلوا على جائزة في مسابقة الشطرنج",
time: "منذ 3 ساعات",
},
{
id: 2,
image: "/Image/1.png",
info: "3 طالبات حصلوا على جائزة في مسابقة الشطرنج",
time: "منذ 3 ساعات",
},
{
id: 3,
image: "/Image/1.png",
info: "3 طالبات حصلوا على جائزة في مسابقة الشطرنج",
time: "منذ 3 ساعات",
},
{
id: 4,
image: "/Image/1.png",
info: "3 طالبات حصلوا على جائزة في مسابقة الشطرنج",
time: "منذ 3 ساعات",
},
{
id: 5,
image: "/Image/1.png",
info: "3 طالبات حصلوا على جائزة في مسابقة الشطرنج",
time: "منذ 3 ساعات",
},
];
return (
<div className="ActivitySection">
<header>
<h4>النشاط الطلابي </h4>
</header>
<div className="ActivityScrollerChanger">
<div className="Activitys">
{ActivitysData.map((Activity) => (
<article key={Activity.id}>
<Image src={Activity.image} />
<h5>{Activity.info}</h5>
<p>{Activity?.time}</p>
</article>
))}
</div>
</div>
</div>
);
};
export default ActivitySection;

View File

@ -1,123 +0,0 @@
import React, { useState } from "react";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import type { Dayjs } from "dayjs";
import dayLocaleData from "dayjs/plugin/localeData";
import {
Calendar,
Col,
DatePicker,
Popover,
Radio,
Row,
Select,
Typography,
theme,
} from "antd";
import type { CalendarProps } from "antd";
import { IoMdArrowDropdown } from "react-icons/io";
import { MdOutlineEdit } from "react-icons/md";
import { RiDeleteBin6Fill } from "react-icons/ri";
dayjs.extend(dayLocaleData);
const App: React.FC = () => {
const [year, setYear] = useState<number>(dayjs().year());
const [month, setMonth] = useState<number>(dayjs().month());
const onChangeDatePicker = (value: any) => {
if (value) {
setYear(value.$y); // Extract year from the selected date and update the year state
setMonth(value.$M); // Extract month from the selected date and update the month state
} else {
const today = dayjs(); // Get the current date
setYear(today.year()); // Update the year state to the current year
setMonth(today.month());
}
};
const popoverDays = [
{
day: 10,
month: 3,
year: 2024,
title: "مسابقة الشطرنج الدولية",
time: "الساعة 11",
},
{
day: 22,
month: 3,
year: 2024,
title: "مسابقة الشطرنج الدولية",
time: "الساعة 12",
},
];
const [actionsVisible, setActionsVisible] = useState(0);
const toggleActionsVisibility = (day: number) => {
setActionsVisible(day);
};
const dateCellRender = (value: dayjs.Dayjs) => {
const day = value.date();
const month = value.month() + 1;
const year = value.year();
const matchingDay = popoverDays.find(
(date) => date.day === day && date.month === month && date.year === year,
);
if (matchingDay) {
return (
<Popover
placement="top"
className="CalenderPop"
rootClassName="CalenderPop"
trigger="hover"
content={
<div
className="Calendar_Popover"
onClick={() => toggleActionsVisibility(day)}
>
<h5>{matchingDay.title}</h5>
<h6>{matchingDay.time}</h6>
{actionsVisible === day && ( // Only show actions if actionsVisible is true
<span className="Actions">
<MdOutlineEdit size={22} style={{ color: "#A098AE" }} />
<RiDeleteBin6Fill size={22} style={{ color: "#C11313" }} />
</span>
)}
</div>
}
// open={true}
>
<div className="Calendar_ActiveDiv">{day}</div>
</Popover>
);
}
return <div className="Calendar_Div">{day}</div>;
};
return (
<div className={"CalendarSection"}>
<Calendar
fullscreen={false}
fullCellRender={dateCellRender}
value={dayjs(`${year}-${month + 1}-01`)}
headerRender={() => {
return (
<div className="CalendarHeader">
<h4>تقويم المدرسة</h4>
<DatePicker
suffixIcon={<IoMdArrowDropdown size={30} />}
onChange={(newDate: number) => onChangeDatePicker(newDate)}
picker="month"
/>
</div>
);
}}
/>
</div>
);
};
export default App;

View File

@ -1,31 +0,0 @@
import React from "react";
import { FaMoneyBill } from "react-icons/fa";
import Image from "../Ui/Image";
const CountSection = () => {
const data = [
{ icon: <FaMoneyBill />, name: "الطالبات", number: 900 },
{ icon: <FaMoneyBill />, name: "الطالبات", number: 900 },
{ icon: <FaMoneyBill />, name: "الطالبات", number: 900 },
{ icon: <FaMoneyBill />, name: "الطالبات", number: 900 },
{ icon: <FaMoneyBill />, name: "الطالبات", number: 900 },
];
return (
<div className="CountSection">
<div className="CountCards">
{data?.map((item: any, index: any) => {
return (
<div key={index} className="CountCard">
<i>{item?.icon}</i>
<h4>{item?.name}</h4>
<h6>{item?.number}</h6>
</div>
);
})}
</div>
<Image src="../Home/HomeCounter.png" />
</div>
);
};
export default CountSection;

View File

@ -1,82 +0,0 @@
import React from "react";
import { FaMoneyBill } from "react-icons/fa";
const NoteSection = () => {
// Static fake data array
const notesData = [
{
id: 1,
icon: <FaMoneyBill />,
title: "ملاحظة مالية",
content: [
"الرسوم الدراسية: المبلغ المطلوب من الأهل 200000 ل.س",
"مبلغ أخر: المبلغ المطلوب من الأهل 300000 ل.س",
],
},
{
id: 2,
icon: <FaMoneyBill />,
title: "ملاحظة مالية",
content: [
"الرسوم الدراسية: المبلغ المطلوب من الأهل 200000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
],
},
{
id: 3,
icon: <FaMoneyBill />,
title: "ملاحظة مالية",
content: [
"الرسوم الدراسية: المبلغ المطلوب من الأهل 200000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
],
},
{
id: 4,
icon: <FaMoneyBill />,
title: "ملاحظة مالية",
content: [
"الرسوم الدراسية: المبلغ المطلوب من الأهل 200000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
],
},
{
id: 5,
icon: <FaMoneyBill />,
title: "ملاحظة مالية",
content: [
"الرسوم الدراسية: المبلغ المطلوب من الأهل 200000 ل.س",
"تكلفة أخرى: المبلغ المطلوب من الأهل 150000 ل.س",
],
},
];
return (
<div className="NoteSection">
<header>
<h4>ملاحظات اليوم</h4> <h6>8/3/2021</h6>
</header>
<div className="NoteScrollerChanger">
<div className="Notes">
{notesData.map((note) => (
<article key={note.id}>
<div>
<i>{note.icon}</i>
<h5>{note.title}</h5>
</div>
{note.content.map((item, index) => (
<span key={index}>{item}</span>
))}
</article>
))}
</div>
</div>
</div>
);
};
export default NoteSection;

View File

@ -1,72 +0,0 @@
import { Progress, Select } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaLaptop } from "react-icons/fa";
import { IoMdArrowDropdown } from "react-icons/io";
import Image from "../Ui/Image";
const StudentSubjects = () => {
const [selectedOption, setSelectedOption] = useState("هذا الأسبوع");
const Options = [
{ value: "هذا الأسبوع", label: "هذا الأسبوع" },
{ value: "الأسبوع الماضي", label: "الأسبوع الماضي" },
{ value: "الشهر الماضي", label: "الشهر الماضي" },
];
const handleChangeSelect = (value: any) => {
setSelectedOption(value);
// console.log(`Selected ${value}`);
};
const [t] = useTranslation();
// Define static data
const staticData = [
{
SubjectImage: "/Subject/algebra.png",
SubjectName: "طالبات",
StudentSubjectsPercent: 50,
},
{
SubjectImage: "/Subject/flask.png",
SubjectName: "طالبات",
StudentSubjectsPercent: 60,
},
{
SubjectImage: "/Subject/koran.png",
SubjectName: "طالبات",
StudentSubjectsPercent: 70,
},
];
return (
<div className="StudentSubjects">
<header>
<h6>{t("عدد الطالبات")}</h6>
<Select
defaultValue={selectedOption}
onChange={handleChangeSelect}
suffixIcon={<IoMdArrowDropdown size={30} />}
options={Options}
/>
</header>
<main>
{staticData.map((item, index) => (
<div key={index}>
<Progress
type="circle"
size={"small"}
strokeColor={"#0052B4"}
strokeWidth={7}
percent={item?.StudentSubjectsPercent}
/>
<h6>{item.SubjectName}</h6>
<Image src={item?.SubjectImage} />
</div>
))}
</main>
</div>
);
};
export default StudentSubjects;

View File

@ -1,11 +1,11 @@
import { Spin } from 'antd' import { Spin } from "antd";
const SpinContainer = () => { const SpinContainer = () => {
return ( return (
<div className='SpinContainer'> <div className="SpinContainer">
<Spin/> <Spin />
</div> </div>
) );
} };
export default SpinContainer export default SpinContainer;

View File

@ -1,46 +0,0 @@
import { Col, Row } from "reactstrap";
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
const Form = () => {
return (
<Row>
<Col xs="8" sm="8">
{" "}
{/* This column will take up 8 units on extra small screens and 6 units on small screens */}
<ValidationField name="الجنس" />
<ValidationField name="الاسم الأول *" />
<ValidationField name="اسم العائلة" />
<div className="TowValidationItems">
<ValidationField name="اسم العائلة" />
<ValidationField name="اسم العائلة" no_label />
</div>
<div className="TowValidationItems">
<ValidationField name="اسم العائلة" type="Select" option={[]} />
<ValidationField name="اسم العائلة" />
</div>
{/* <div className='TowValidationItems'>
<ValidationField name='اسم العائلة'/>
<ValidationField name='اسم العائلة' no_label/>
</div>
<div className='TowValidationItems'>
<ValidationField name='اسم العائلة'/>
<ValidationField name='اسم العائلة' no_label/>
</div> */}
</Col>
<Col xs="4" sm="4">
{" "}
{/* This column will take up 4 units on extra small screens and 6 units on small screens */}
<ValidationField name="DropFile" type="DropFile" label="الصورة *" />
<ValidationField
name="DropFile"
type="DropFile"
label="الوثيقة المدرسية *"
/>
</Col>
</Row>
);
};
export default Form;

View File

@ -1,38 +0,0 @@
import React, { useState } from "react";
import { Modal } from "antd";
import { useModalState } from "../../../../zustand/Modal";
import FormikForm from "../../../../Layout/Dashboard/FormikForm";
import * as Yup from "yup";
import ModelBody from "./ModelBody";
import TabsSubmite from "../../../../Components/Layout/Tabs/TabsSubmite";
import { getInitialValues, getValidationSchema } from "./formUtil";
import { ModalEnum } from "../../../../enums/Model";
const ModalForm: React.FC = () => {
const { isOpen, setIsOpen } = useModalState((state) => state);
return (
<>
<Modal
className="AddModalForm"
centered
width={"80vw"}
footer={null}
open={isOpen === ModalEnum.STUDENT_ADD}
onOk={() => setIsOpen("")}
onCancel={() => setIsOpen("")}
>
<FormikForm
handleSubmit={() => {}}
initialValues={getInitialValues}
validationSchema={getValidationSchema}
>
<ModelBody />
{/* <TabsSubmite steps={5} /> */}
</FormikForm>
</Modal>
</>
);
};
export default ModalForm;

View File

@ -1,60 +0,0 @@
import { Divider, Steps } from "antd";
import React, { useState } from "react";
import { useTabsState } from "../../../../zustand/TabsState";
import { useModalTabsState } from "../../../../zustand/ModalTabsState";
import Form from "./Form";
import TabsBar from "../../../../Components/Layout/Tabs/TabsBar";
import ActiveTabs from "../../../../Components/Layout/Tabs/ActiveTabs";
const ModelBody = () => {
const { ActiveTab, setActiveTab } = useModalTabsState((state) => state);
function handelTabClick(index: number) {
setActiveTab(index);
}
const steps = [
{
title: "الخطوة 1",
description: "التفاصيل الشخصية",
component: <Form />,
},
{
title: "الخطوة 2",
description: "التفاصيل الشخصية",
component: <>H2</>,
},
{
title: "الخطوة 3",
description: "التفاصيل الشخصية",
component: <>H2</>,
},
{
title: "الخطوة 4",
description: "التفاصيل الشخصية",
component: <>H2</>,
},
{
title: "الخطوة 5",
description: "التفاصيل الشخصية",
component: <>H2</>,
},
{
title: "الخطوة 5",
description: "التفاصيل الشخصية",
component: <>H2</>,
hidden: true,
},
];
return (
<div className="ModelBody">
<TabsBar steps={steps} />
<div className="ModelBodyForm">
<header>إضافة طالب</header>
<ActiveTabs steps={steps} />
</div>
</div>
);
};
export default ModelBody;

View File

@ -1,15 +0,0 @@
import * as Yup from "yup";
export const getInitialValues = (objectToEdit: any): any => {
return {
id: objectToEdit?.id ?? 0,
name: objectToEdit?.name ?? "",
};
};
export const getValidationSchema = () => {
// validate input
return Yup.object().shape({
name: Yup.string().required("مطلوب"),
});
};

View File

@ -1,26 +0,0 @@
import React from "react";
import { FaMoneyBill } from "react-icons/fa";
import Image from "../Ui/Image";
const CountSection = () => {
return (
<div className="CountSection">
<div className="CountCards">
{[1, 2, 3, 4, 5]?.map((item: any, index: any) => {
return (
<div key={index} className="CountCard">
<i>
<FaMoneyBill />
</i>
<h4>الطالبات</h4>
<h6>932</h6>
</div>
);
})}
</div>
{/* <Image src='../Home/HomeCounter.png'/> */}
</div>
);
};
export default CountSection;

View File

@ -1,21 +0,0 @@
import React from "react";
import { FaChalkboardTeacher } from "react-icons/fa";
import { IoSchool } from "react-icons/io5";
import { useNavigate } from "react-router-dom";
const DetailsCard = () => {
const navigate = useNavigate();
const handelclick = () => {
navigate("/student/add");
};
return (
<div className="DetailsCard" onClick={() => handelclick()}>
<h6>إضافة طالب</h6>
<div>
<IoSchool />
</div>
</div>
);
};
export default DetailsCard;

View File

@ -1,56 +0,0 @@
import { Select } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { FaLaptop } from "react-icons/fa";
import { IoMdArrowDropdown } from "react-icons/io";
const StudentCount = () => {
const [selectedOption, setSelectedOption] = useState("هذا الأسبوع");
const Options = [
{ value: "هذا الأسبوع", label: "هذا الأسبوع" },
{ value: "الأسبوع الماضي", label: "الأسبوع الماضي" },
{ value: "الشهر الماضي", label: "الشهر الماضي" },
];
const handleChangeSelect = (value: any) => {
setSelectedOption(value);
// console.log(`Selected ${value}`);
};
const [t] = useTranslation();
// Define static data
const staticData = [
{ studentName: "طالبات الشعبة الأولى 1", studentCount: 50 },
{ studentName: "طالبات الشعبة الأولى 2", studentCount: 60 },
{ studentName: "طالبات الشعبة الأولى 3", studentCount: 70 },
{ studentName: "طالبات الشعبة الأولى 4", studentCount: 80 },
];
return (
<div className="StudentCount">
<header>
<h6>{t("عدد الطالبات")}</h6>
<Select
defaultValue={selectedOption}
onChange={handleChangeSelect}
suffixIcon={<IoMdArrowDropdown size={30} />}
options={Options}
/>
</header>
<main>
{staticData.map((item, index) => (
<div key={index}>
<span>
<h6>{item.studentName}</h6>
<p>{item.studentCount} طالب</p>
</span>
<FaLaptop />
</div>
))}
</main>
</div>
);
};
export default StudentCount;

View File

@ -1,54 +0,0 @@
import React from "react";
import { FaMoneyBill } from "react-icons/fa";
import Image from "../../Ui/Image";
import { useNavigate, useParams } from "react-router-dom";
import { useGetOverView } from "../../../api/payment";
import { useTranslation } from "react-i18next";
import { Currency } from "../../../config/AppKey";
import { formatNumber } from "../../../utils/formatNumber";
const MoneyState = () => {
const navigation = useNavigate();
const { student_id } = useParams();
const handelnavigate = () => {
navigation(`payment`);
};
const { data } = useGetOverView({
student_id: student_id,
});
const [t] = useTranslation();
const to_be_paid = Number(data?.data?.to_be_paid) || 0;
const paid = Number(data?.data?.paid) || 0;
const dues = formatNumber(to_be_paid - paid);
return (
<div className="MoneyState">
<header>{t("header.The_student_financial_situation")}</header>
<main>
<button>
{t("select.Payments.dues")} : {dues} {Currency}
</button>
<div>
<div>
<FaMoneyBill />
</div>
<span>
<h6>{t("select.Payments.to_be_paid")}</h6>
<p>
{formatNumber(to_be_paid)} {Currency}
</p>
</span>
</div>
<article>
<span onClick={handelnavigate}>
<Image src="/Icon/cash.png" />
<h5>{t("models.payment")}</h5>
<button>{t("practical.details")}</button>
</span>
</article>
</main>
</div>
);
};
export default MoneyState;

View File

@ -1,35 +0,0 @@
import React, { useState } from "react";
function FakeIntegration() {
const [integrationInput, setIntegrationInput] = useState("");
const [integrationResult, setIntegrationResult] = useState("");
const handleSubmit = (event: any) => {
event.preventDefault();
// Simulated integration result
const fakeResult = "∫(x^2)dx = (1/3)x^3 + C";
setIntegrationResult(fakeResult);
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={integrationInput}
onChange={(e) => setIntegrationInput(e.target.value)}
placeholder="Enter integration expression"
/>
<button type="submit">Calculate</button>
</form>
<div>
<h2>Integration Input:</h2>
<p>{integrationInput}</p>
<h2>Integration Result:</h2>
<p>{integrationResult}</p>
</div>
</div>
);
}
export default FakeIntegration;

View File

@ -1,11 +1,11 @@
import { DatePicker } from 'antd' import { DatePicker } from "antd";
import React from 'react' import React from "react";
import { useTranslation } from 'react-i18next'; import { useTranslation } from "react-i18next";
import { useObjectToEdit } from '../../../zustand/ObjectToEditState'; import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useLocation, useNavigate } from 'react-router-dom'; import { useLocation, useNavigate } from "react-router-dom";
import type { DatePickerProps } from "antd"; import type { DatePickerProps } from "antd";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { DateEnum } from '../../../enums/Date'; import { DateEnum } from "../../../enums/Date";
const CustomDatePicker = () => { const CustomDatePicker = () => {
const [t] = useTranslation(); const [t] = useTranslation();
@ -24,7 +24,6 @@ const CustomDatePicker = () => {
}; };
const Today = new Date() as any; const Today = new Date() as any;
return ( return (
<div className="CustomDatePicker"> <div className="CustomDatePicker">
<DatePicker <DatePicker
@ -34,7 +33,7 @@ const CustomDatePicker = () => {
format={DateEnum?.FORMATE} format={DateEnum?.FORMATE}
/> />
</div> </div>
) );
} };
export default CustomDatePicker export default CustomDatePicker;

View File

@ -1,56 +0,0 @@
import React, { memo } from "react";
import type { MenuProps } from "antd";
import { Button, Dropdown, Space } from "antd";
import { useTranslation } from "react-i18next";
import { BsFillMoonStarsFill, BsFillSunFill } from "react-icons/bs";
import { useChangeTheme } from "../../Hooks/useChangeTheme";
const Theme: React.FC = () => {
const { currentTheme, changeTheme } = useChangeTheme();
const { t } = useTranslation();
const LightTheme = memo(() => (
<div className="MenuChange" onClick={lightThemeClickHandler}>
<BsFillSunFill />
{t("light")}
</div>
));
const DarkTheme = memo(() => (
<div className="MenuChange" onClick={darkThemeClickHandler}>
<BsFillMoonStarsFill />
{t("dark")}
</div>
));
const lightThemeClickHandler = React.useCallback(() => {
changeTheme("light");
}, [changeTheme]);
const darkThemeClickHandler = React.useCallback(() => {
changeTheme("dark");
}, [changeTheme]);
const items: MenuProps["items"] = [
{
key: "1",
label: <LightTheme />,
},
{
key: "2",
label: <DarkTheme />,
},
];
return (
<Space direction="vertical">
<Dropdown menu={{ items }} placement="top">
<Button>
{currentTheme === "dark" ? <DarkTheme /> : <LightTheme />}
</Button>
</Dropdown>
</Space>
);
};
export default Theme;

View File

@ -31,11 +31,11 @@ const components: { [key: string]: React.FC<any> } = {
MaltyFile: MaltyFile, MaltyFile: MaltyFile,
Checkbox: CheckboxField, Checkbox: CheckboxField,
NumberFormate: NumberFormate, NumberFormate: NumberFormate,
Number:NumberField Number: NumberField,
}; };
const ValidationField: React.FC<ValidationFieldProps> = React.memo( const ValidationField: React.FC<ValidationFieldProps> = React.memo(
({ type, ...otherProps }:any) => { ({ type, ...otherProps }: any) => {
const Component = components[type as ValidationFieldType]; const Component = components[type as ValidationFieldType];
if (!Component) { if (!Component) {

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import useFormField from "../../../Hooks/useFormField"; import useFormField from "../../../Hooks/useFormField";
import { Checkbox, Form } from "antd"; import { Checkbox, Form } from "antd";
import {getNestedValue} from '../utils/getNestedValue' import { getNestedValue } from "../utils/getNestedValue";
const CheckboxField = ({ const CheckboxField = ({
name, name,
label, label,

View File

@ -25,9 +25,7 @@ const Default = ({
<label htmlFor={name} className="text"> <label htmlFor={name} className="text">
{label2} {label2}
</label> </label>
) ) : no_label ? (
:no_label ? (
<label htmlFor={name} className="text"> <label htmlFor={name} className="text">
<span>empty</span> <span>empty</span>
</label> </label>
@ -58,7 +56,6 @@ const Default = ({
name={name} name={name}
disabled={isDisabled} disabled={isDisabled}
size="large" size="large"
{...(type === "number" && { min: 0 })} {...(type === "number" && { min: 0 })}
{...props} {...props}
/> />

View File

@ -12,27 +12,27 @@ const File = ({
className, className,
props, props,
}: any) => { }: any) => {
const { formik, t, isError,errorMsg } = useFormField(name, props); const { formik, t, isError, errorMsg } = useFormField(name, props);
let imageUrl = formik?.values?.[name] ?? null; let imageUrl = formik?.values?.[name] ?? null;
console.log(imageUrl); console.log(imageUrl);
console.log(typeof imageUrl === 'string'); console.log(typeof imageUrl === "string");
const fileList: UploadFile[] = useMemo(() => { const fileList: UploadFile[] = useMemo(() => {
if (!imageUrl) return []; if (!imageUrl) return [];
return [ return [
typeof imageUrl === 'string' typeof imageUrl === "string"
? { ? {
uid: '-1', uid: "-1",
name: 'uploaded-image', name: "uploaded-image",
status: 'done', status: "done",
url: imageUrl, url: imageUrl,
thumbUrl: imageUrl, thumbUrl: imageUrl,
} }
: { : {
uid: imageUrl.uid || '-1', uid: imageUrl.uid || "-1",
name: imageUrl.name || 'uploaded-image', name: imageUrl.name || "uploaded-image",
status: 'done', status: "done",
originFileObj: imageUrl, originFileObj: imageUrl,
}, },
]; ];
@ -70,7 +70,6 @@ const File = ({
icon={<UploadOutlined />} icon={<UploadOutlined />}
> >
{placholder ?? t("input.Click_to_upload_the_image")} {placholder ?? t("input.Click_to_upload_the_image")}
</Button> </Button>
<div className="Error_color"> {isError ? "required" : ""}</div> <div className="Error_color"> {isError ? "required" : ""}</div>
{errorMsg} {errorMsg}

View File

@ -16,12 +16,12 @@ const NumberField = ({
label_icon, label_icon,
...props ...props
}: ValidationFieldPropsInput) => { }: ValidationFieldPropsInput) => {
const { errorMsg, isError, t ,formik} = useFormField(name, props); const { errorMsg, isError, t, formik } = useFormField(name, props);
const handleChange = ( const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => { ) => {
console.log('Change:', e); console.log("Change:", e);
formik.setFieldValue(name, e); formik.setFieldValue(name, e);
}; };

View File

@ -64,7 +64,6 @@ const NumberFormate = ({
disabled={isDisabled} disabled={isDisabled}
size="large" size="large"
// onChange={onChange ? onChange : handleChange} // onChange={onChange ? onChange : handleChange}
/> />
</Form.Item> </Form.Item>

View File

@ -17,7 +17,7 @@ const SearchField = ({
props, props,
no_label, no_label,
label_icon, label_icon,
isLoading isLoading,
}: any) => { }: any) => {
const { errorMsg, isError, t, formik } = useFormField(name, props); const { errorMsg, isError, t, formik } = useFormField(name, props);
const [searchQuery, setSearchQuery] = useState<string>(""); const [searchQuery, setSearchQuery] = useState<string>("");
@ -78,8 +78,7 @@ const SearchField = ({
onChange={onChange || SelectableChange} onChange={onChange || SelectableChange}
showSearch showSearch
optionFilterProp="label" optionFilterProp="label"
notFoundContent={isLoading ? <Spin/> : "لا يوجد" } notFoundContent={isLoading ? <Spin /> : "لا يوجد"}
onSearch={SearchHandleChange} onSearch={SearchHandleChange}
/> />
</Form.Item> </Form.Item>

View File

@ -15,7 +15,7 @@ const TextField = ({
props, props,
no_label, no_label,
label_icon, label_icon,
className className,
}: any) => { }: any) => {
const { formik, isError, errorMsg, t } = useFormField(name, props); const { formik, isError, errorMsg, t } = useFormField(name, props);
const TextFilehandleChange = ( const TextFilehandleChange = (
@ -33,13 +33,13 @@ const TextField = ({
) : label_icon ? ( ) : label_icon ? (
<div className="LabelWithIcon"> <div className="LabelWithIcon">
<label htmlFor={name} className="text"> <label htmlFor={name} className="text">
{label2 ? label2 : t(`input.${label ? label : name}`) } {label2 ? label2 : t(`input.${label ? label : name}`)}
</label> </label>
<MdOutlineEdit size={22} style={{ color: "#A098AE" }} /> <MdOutlineEdit size={22} style={{ color: "#A098AE" }} />
</div> </div>
) : ( ) : (
<label htmlFor={name} className="text"> <label htmlFor={name} className="text">
{label2 ? label2 : t(`input.${label ? label : name}`) } {label2 ? label2 : t(`input.${label ? label : name}`)}
</label> </label>
)} )}
@ -57,9 +57,7 @@ const TextField = ({
showCount showCount
maxLength={1000} maxLength={1000}
onChange={onChange || TextFilehandleChange} onChange={onChange || TextFilehandleChange}
style={{height:120}} style={{ height: 120 }}
/> />
</Form.Item> </Form.Item>
</div> </div>

View File

@ -62,9 +62,8 @@
} }
.Checkboxs { .Checkboxs {
padding: 4%; padding: 4%;
} }
.ant-checkbox-wrapper{ .ant-checkbox-wrapper {
min-width: 100px; min-width: 100px;
} }
.SearchField { .SearchField {
@ -203,27 +202,26 @@ input:-webkit-autofill:hover {
margin-bottom: 20px; margin-bottom: 20px;
} }
.ant-checkbox-wrapper {
.ant-checkbox-wrapper{
margin-top: 25px !important; margin-top: 25px !important;
} }
.add_new_button{ .add_new_button {
margin-bottom: 20px; margin-bottom: 20px;
svg{ svg {
color: var(--primary); color: var(--primary);
} }
} }
.ValidationField:has(.input_number){ .ValidationField:has(.input_number) {
max-width: 100px; max-width: 100px;
.input_number{ .input_number {
max-width: 100px; max-width: 100px;
} }
} }
.flex{ .flex {
display: flex; display: flex;
gap: 30px ; gap: 30px;
max-width: 80% !important; max-width: 80% !important;
} }

View File

@ -1,9 +1,7 @@
export function getNestedValue(obj: any, path: any) {
export function getNestedValue(obj:any, path:any) {
return path return path
.replace(/\?.\[|\]\[|\]\.?/g, '.') // Replace question mark and square brackets .replace(/\?.\[|\]\[|\]\.?/g, ".") // Replace question mark and square brackets
.split('.') // Split by dots .split(".") // Split by dots
.filter(Boolean) // Remove empty strings .filter(Boolean) // Remove empty strings
.reduce((acc:any, key:any) => acc && acc[key], obj); // Access nested properties .reduce((acc: any, key: any) => acc && acc[key], obj); // Access nested properties
} }

View File

@ -73,7 +73,7 @@ export interface ValidationFieldPropsSearch {
option: any[]; option: any[];
isMulti?: boolean; isMulti?: boolean;
searchBy: string; searchBy: string;
isLoading?:any isLoading?: any;
} }
export interface ValidationFieldPropsDataRange { export interface ValidationFieldPropsDataRange {
name: string; name: string;
@ -151,7 +151,7 @@ export interface ValidationFieldPropstext {
| "TextArea" | "TextArea"
| "NumberFormate"; | "NumberFormate";
label?: string; label?: string;
label2?:string; label2?: string;
className?: string; className?: string;
placeholder?: string; placeholder?: string;
isDisabled?: boolean; isDisabled?: boolean;
@ -161,31 +161,26 @@ export interface ValidationFieldPropstext {
[key: string]: any; // Index signature to allow any additional props [key: string]: any; // Index signature to allow any additional props
} }
///// new ///// new
export interface BaseField { export interface BaseField {
name: string; name: string;
label?: string; label?: string;
placeholder?: string; placeholder?: string;
} }
export type OmitBaseType = 'placeholder' | 'name' | 'label' | 'type'; export type OmitBaseType = "placeholder" | "name" | "label" | "type";
export type OmitPicker = OmitBaseType | 'format'; export type OmitPicker = OmitBaseType | "format";
export interface ValidationFieldPropsInput export interface ValidationFieldPropsInput
extends Omit<InputProps, OmitBaseType>, extends Omit<InputProps, OmitBaseType>,
BaseField { BaseField {
type: 'text' | 'number' | 'password' | 'email' | "Number"; type: "text" | "number" | "password" | "email" | "Number";
isDisabled?:boolean isDisabled?: boolean;
no_label?:string no_label?: string;
label_icon?:string label_icon?: string;
label2?:string label2?: string;
} }
export type ValidationFieldProps = export type ValidationFieldProps =
| ValidationFieldPropsInput | ValidationFieldPropsInput
| ValidationFieldPropsSelect | ValidationFieldPropsSelect

View File

@ -1,60 +0,0 @@
import Image from "../Ui/Image";
import { Student } from "../../types/Item";
import { useNavigate, useParams } from "react-router-dom";
import { useGetStudent } from "../../api/student";
import { useTranslation } from "react-i18next";
const StudentBehavior = () => {
const { student_id } = useParams();
const { data: studentData } = useGetStudent({
show: student_id,
});
const userData: Student | {} = studentData?.data ?? {};
const { positiveNote, warningNote, alertNote } = userData as Student;
const [t] = useTranslation();
const navigate = useNavigate();
const handelnavigate = () => {
navigate(`note`);
};
const Data = [
{
icon: "/Icon/medal.png",
title: t("array.UserInfo.appreciation"),
value: positiveNote,
buttonText: t("practical.show"),
},
{
icon: "/Icon/warning.png",
title: t("array.UserInfo.warning"),
value: warningNote,
buttonText: t("practical.show"),
},
{
icon: "/Icon/Error.png",
title: t("array.UserInfo.alert"),
value: alertNote,
buttonText: t("practical.show"),
},
];
return (
<div className="StudentBehavior">
<header>{t("header.Student_classroom_behavior")}</header>
<main>
{Data.map((item, index) => (
<article key={index} onClick={handelnavigate}>
<Image src={item.icon} />
<div>
<h6>{item.title}</h6>
<p>{item.value}</p>
</div>
<button>{item.buttonText}</button>
</article>
))}
</main>
</div>
);
};
export default StudentBehavior;

View File

@ -1,97 +0,0 @@
import React from "react";
import { getColorName } from "../../Hooks/usePercentage";
import { useNavigate, useParams } from "react-router-dom";
import { useGetStudent } from "../../api/student";
import { Student } from "../../types/Item";
import { useTranslation } from "react-i18next";
interface StudentTimeData {
id: number;
absences: number;
justified: number;
unjustified: number;
totalDays: number;
name: string;
}
const StudentsTime = () => {
const { student_id } = useParams();
const { data: studentData } = useGetStudent({
show: student_id,
});
const userData: Student | {} = studentData?.data ?? {};
const { ealryDeparture, absence, lateArrival } = userData as Student;
const [t] = useTranslation();
const data = [
{
name: t("models.absence"),
id: 1,
absences: absence?.justified + absence?.not_justified,
justified: absence?.justified,
unjustified: absence?.not_justified,
totalDays: absence?.total,
},
{
name: t("models.late_arrival"),
id: 2,
absences: lateArrival?.justified + lateArrival?.not_justified,
justified: lateArrival?.justified,
unjustified: lateArrival?.not_justified,
totalDays: lateArrival?.total,
},
{
name: t("models.earlyDeparture"),
id: 3,
absences: ealryDeparture?.justified + ealryDeparture?.not_justified,
justified: ealryDeparture?.justified,
unjustified: ealryDeparture?.not_justified,
totalDays: ealryDeparture?.total,
},
];
const navigate = useNavigate();
const handel_naviagate = () => {
navigate(`status`);
};
return (
<div className="StudentsTime">
<header>{t("header.student_status")}</header>
<main>
{data?.length > 0 &&
data.map((item: StudentTimeData, index: number) => {
return (
<article key={item.id} onClick={handel_naviagate}>
<span>
<h6>{item?.name}</h6>
<p data-color={getColorName(item.absences)}>
{item.absences}
</p>
</span>
<div>
<span>
<div>
{t("select.Student_Type.justified")}
<span>{item.justified}</span>
</div>
<div>
{t("select.Student_Type.not_justified")}
<span>{item.unjustified}</span>
</div>
</span>
<span>
<div className="StudentsTimeTotal">المجموع</div>
<p>
{item.absences} من {item.totalDays} يوم
</p>
</span>
</div>
</article>
);
})}
</main>
</div>
);
};
export default StudentsTime;

View File

@ -1,28 +1,26 @@
import { useFormikContext } from 'formik'; import { useFormikContext } from "formik";
import React from 'react'; import React from "react";
import { useTranslation } from 'react-i18next'; import { useTranslation } from "react-i18next";
import { GoArrowSwitch } from 'react-icons/go'; import { GoArrowSwitch } from "react-icons/go";
import { useObjectToEdit } from '../../zustand/ObjectToEditState'; import { useObjectToEdit } from "../../zustand/ObjectToEditState";
import { QUESTION_OBJECT_KEY } from '../../config/AppKey'; 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,setIsBseQuestion} = useObjectToEdit() const { isBseQuestion, setIsBseQuestion } = useObjectToEdit();
const {setSavedQuestionData} = useObjectToEdit() const { setSavedQuestionData } = useObjectToEdit();
const handleChange = () => { const handleChange = () => {
setSavedQuestionData(null) setSavedQuestionData(null);
localStorage.removeItem(QUESTION_OBJECT_KEY) localStorage.removeItem(QUESTION_OBJECT_KEY);
if (isBseQuestion) { if (isBseQuestion) {
setIsBseQuestion(false) setIsBseQuestion(false);
setValues(null) setValues(null);
setFieldValue("isBase",0) setFieldValue("isBase", 0);
} else { } else {
setIsBseQuestion(true);
setIsBseQuestion(true) setValues(null);
setValues(null) setFieldValue("isBase", 1);
setFieldValue("isBase",1)
} }
}; };
@ -33,7 +31,9 @@ const Header = () => {
</div> </div>
<div> <div>
<GoArrowSwitch onClick={handleChange} className="m-2" /> <GoArrowSwitch onClick={handleChange} className="m-2" />
{isBseQuestion || values?.isBase === 1 ? t("header.malty_exercise") :t("header.exercise") } {isBseQuestion || values?.isBase === 1
? t("header.malty_exercise")
: t("header.exercise")}
</div> </div>
</header> </header>
); );

View File

@ -1,62 +0,0 @@
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

@ -1,68 +0,0 @@
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,4 +1,3 @@
export const useAddKeyToData = (dataSource: any, identifier = "id") => { export const useAddKeyToData = (dataSource: any, identifier = "id") => {
if (!dataSource || !Array.isArray(dataSource)) { if (!dataSource || !Array.isArray(dataSource)) {
return []; return [];

View File

@ -1,23 +0,0 @@
import { useCallback, useEffect, useState } from "react";
export const useChangeTheme = () => {
const [currentTheme, setCurrentTheme] = useState(
localStorage.getItem("theme") ?? "light",
);
useEffect(() => {
if (currentTheme === "dark") {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
localStorage.setItem("theme", currentTheme);
}, [currentTheme]);
const changeTheme = useCallback((newTheme: any) => {
setCurrentTheme(newTheme);
}, []);
return { currentTheme, changeTheme };
};

View File

@ -1,18 +0,0 @@
import { useState } from "react";
const useDifferenceData = (values: any, data: any) => {
const [newData, setNewData] = useState({});
for (const key in data) {
if (values[key] !== data[key]) {
setNewData((prevData) => ({
...prevData,
[key]: values[key],
}));
}
}
return newData;
};
export default useDifferenceData;

View File

@ -1,40 +0,0 @@
import { useEffect } from "react";
const useDisableShortcutsAndRightClick = () => {
useEffect(() => {
const disableShortcutsAndRightClick = (event: Event) => {
// Check for Ctrl+Shift+C or F12
if (
(event as KeyboardEvent).ctrlKey &&
(event as KeyboardEvent).shiftKey &&
((event as KeyboardEvent).key === "C" ||
(event as KeyboardEvent).key === "c" ||
(event as KeyboardEvent).keyCode === 123) /* F12 key code */
) {
event.preventDefault();
}
};
const disableRightClick = (event: MouseEvent) => {
event.preventDefault();
};
document.addEventListener("keydown", disableShortcutsAndRightClick);
document.addEventListener("contextmenu", disableRightClick);
// Attempt to prevent F12 key default behavior
document.addEventListener("keydown", (event) => {
if (event.key === "F12" || event.keyCode === 123) {
event.preventDefault();
return false;
}
});
return () => {
document.removeEventListener("keydown", disableShortcutsAndRightClick);
document.removeEventListener("contextmenu", disableRightClick);
};
}, []);
};
export default useDisableShortcutsAndRightClick;

View File

@ -1,8 +1,12 @@
import { useEffect } from 'react'; import { useEffect } from "react";
type ModifierKey = 'ctrlKey' | 'shiftKey' | 'altKey' | 'metaKey'; type ModifierKey = "ctrlKey" | "shiftKey" | "altKey" | "metaKey";
const useKeyPress = (targetKey: string, modifierKey: ModifierKey, callback:any) => { const useKeyPress = (
targetKey: string,
modifierKey: ModifierKey,
callback: any,
) => {
useEffect(() => { useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if (event[modifierKey] && event.key === targetKey) { if (event[modifierKey] && event.key === targetKey) {
@ -11,10 +15,10 @@ const useKeyPress = (targetKey: string, modifierKey: ModifierKey, callback:any)
} }
}; };
document.addEventListener('keydown', handleKeyDown); document.addEventListener("keydown", handleKeyDown);
return () => { return () => {
document.removeEventListener('keydown', handleKeyDown); document.removeEventListener("keydown", handleKeyDown);
}; };
}, [targetKey, modifierKey, callback]); }, [targetKey, modifierKey, callback]);
}; };

View File

@ -1,24 +0,0 @@
import { useState, useEffect } from "react";
function useLoadingState(
initialValue: boolean,
duration: number,
): [boolean, () => void] {
const [loading, setLoading] = useState<boolean>(initialValue);
useEffect(() => {
const timeoutId = setTimeout(() => {
setLoading(false);
}, duration);
return () => clearTimeout(timeoutId);
}, [duration]);
const resetLoading = () => {
setLoading(true);
};
return [loading, resetLoading];
}
export default useLoadingState;

View File

@ -1,45 +0,0 @@
import { Pagination } from "antd";
import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
export const PaginationBody = ({ data, no_label, label_icon }: any) => {
const navigate = useNavigate();
const location = useLocation();
const pagination = location?.search || "";
const currentPage = parseInt(
new URLSearchParams(location.search).get("page") || "1",
10,
);
const pageSize = parseInt(
new URLSearchParams(location.search).get("per_page") || "8",
10,
);
const [searchParams] = useSearchParams();
const onChange = (page: number, pageSize?: number) => {
navigate(
`?page=${page}&per_page=${pageSize || data?.per_page}&search=${searchParams.get("search")}`,
{ replace: true },
);
};
const onShowSizeChange = (current: number, pageSize: number) => {
navigate(
`?page=${current}&per_page=${pageSize}&search=${searchParams.get("search")}`,
{ replace: true },
);
};
return (
<Pagination
className="text-center mt-3 paginateStyle"
total={data}
showTotal={(total: any) => `Total ${total} items`}
pageSize={pageSize}
pageSizeOptions={[8, 16, 24, 32, 40]}
defaultCurrent={currentPage}
current={currentPage} // Adding this line will set the current page correctly
onChange={onChange}
onShowSizeChange={onShowSizeChange}
/>
);
};

View File

@ -1,72 +0,0 @@
import { RiArrowLeftDownLine, RiArrowRightUpLine } from "react-icons/ri";
export const PercentageImageSrc = (percentage: number) => {
if (percentage >= 90) {
return "../ArrowType/90.png";
} else if (percentage >= 80) {
return "../ArrowType/80.png";
} else if (percentage >= 60) {
return "../ArrowType/60.png";
} else if (percentage >= 40) {
return "../ArrowType/40.png";
} else if (percentage >= 20) {
return "../ArrowType/20.png";
}
return "";
};
export const getColorName = (percentage: number) => {
if (percentage >= 6) {
return "Red";
} else if (percentage >= 4) {
return "Orange";
} else if (percentage >= 2) {
return "Green";
} else {
return "Green";
}
};
export const getStrokeColor = (percentage: number) => {
if (percentage >= 90) {
return "#87d068"; // Green color
} else if (percentage >= 80) {
return "#87d068"; // Blue color
} else if (percentage >= 60) {
return "#ffec3d"; // Yellow color
} else if (percentage >= 40) {
return "#faad14"; // Orange color
} else if (percentage >= 20) {
return "#f5222d"; // Red color
} else {
return "#f5222d"; // Red color
}
};
export const getPercentageIcon = (percentage: number) => {
if (percentage >= 60) {
return <RiArrowRightUpLine />;
} else if (percentage >= 40) {
return <></>;
} else {
return <RiArrowLeftDownLine />;
}
};
export const getPercentageText = (percentage: number) => {
if (percentage >= 60) {
return "مرتفع";
} else if (percentage >= 40) {
return "متوسط";
} else {
return "منخفض";
}
};
{
/* <RiArrowRightUpLine /> */
}
{
/* <RiArrowLeftDownLine /> */
}

View File

@ -1,32 +0,0 @@
import { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
const usePreviousPath = () => {
const location = useLocation();
const navigate = useNavigate();
const [previousPath, setPreviousPath] = useState(null);
console.log(previousPath);
useEffect(() => {
// Update the previous path whenever the location changes
const currentPath = location.pathname as any;
setPreviousPath(currentPath);
// Clean up
return () => {
setPreviousPath(null);
};
}, [location]);
const navigateToPreviousPath = () => {
if (previousPath) {
navigate(previousPath);
} else {
navigate(-1); // Fallback to default behavior
}
};
return { navigateToPreviousPath };
};
export default usePreviousPath;

View File

@ -1,42 +0,0 @@
import { useState, useEffect } from "react";
interface ResponsiveHookProps {
initialState: boolean;
setIs: any;
widthThreshold: number;
}
const useResponsive = ({
initialState,
setIs,
widthThreshold,
}: ResponsiveHookProps) => {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
const [isBoolean, setIsBoolean] = useState<boolean>(initialState);
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth);
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
useEffect(() => {
if (windowWidth < widthThreshold && isBoolean) {
setIs(false);
setIsBoolean(false);
} else if (windowWidth >= widthThreshold && !isBoolean) {
setIs(true);
setIsBoolean(true);
}
}, [windowWidth, isBoolean, setIs, widthThreshold]);
return { windowWidth, isBoolean, setIsBoolean };
};
export default useResponsive;

View File

@ -1,17 +1,18 @@
import { useEffect } from 'react'; import { useEffect } from "react";
import { setLocalStorageQuestions } from '../utils/setLocalStorageQuestions'; import { setLocalStorageQuestions } from "../utils/setLocalStorageQuestions";
import { setLocalStorageBaseQuestions } from '../utils/setLocalStorageBaseQuestions';
const useSaveOnDisconnect = (noChange: boolean, QUESTION_OBJECT_KEY: string, SavedQuestionData: any) => { const useSaveOnDisconnect = (
noChange: boolean,
QUESTION_OBJECT_KEY: string,
SavedQuestionData: any,
) => {
useEffect(() => { useEffect(() => {
const handleBeforeUnload = (event: BeforeUnloadEvent) => { const handleBeforeUnload = (event: BeforeUnloadEvent) => {
console.log("disconnect"); console.log("disconnect");
if (noChange) { if (noChange) {
if(SavedQuestionData?.isBase ===1){ if (SavedQuestionData?.isBase === 1) {
setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData); setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData);
} else {
}else{
setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData); setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData);
} }
} }
@ -20,24 +21,22 @@ const useSaveOnDisconnect = (noChange: boolean, QUESTION_OBJECT_KEY: string, Sav
const handleOffline = () => { const handleOffline = () => {
console.log("disconnect"); console.log("disconnect");
if (noChange) { if (noChange) {
if(SavedQuestionData?.isBase ===1){ if (SavedQuestionData?.isBase === 1) {
setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData); setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData);
} else {
}else{
setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData); setLocalStorageQuestions(QUESTION_OBJECT_KEY, SavedQuestionData);
} }
} }
}; };
// Add event listeners // Add event listeners
window.addEventListener('beforeunload', handleBeforeUnload); window.addEventListener("beforeunload", handleBeforeUnload);
window.addEventListener('offline', handleOffline); window.addEventListener("offline", handleOffline);
// Cleanup function // Cleanup function
return () => { return () => {
window.removeEventListener('beforeunload', handleBeforeUnload); window.removeEventListener("beforeunload", handleBeforeUnload);
window.removeEventListener('offline', handleOffline); window.removeEventListener("offline", handleOffline);
}; };
}, [noChange, QUESTION_OBJECT_KEY, SavedQuestionData]); // Add dependencies to the hook }, [noChange, QUESTION_OBJECT_KEY, SavedQuestionData]); // Add dependencies to the hook
}; };

View File

@ -1,21 +0,0 @@
import { useEffect, useState } from "react";
const useSearchResults = (data: any[] | undefined, query: string | null) => {
const [results, setResults] = useState<any[]>([]);
useEffect(() => {
const filteredResults =
data?.filter((item: any) =>
item?.toLowerCase()?.includes(query?.toLowerCase()),
) ?? [];
setResults(filteredResults);
if (results?.length === 0 && query != null && query?.length > 1) {
}
}, [query]);
return results;
};
export default useSearchResults;

View File

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

View File

@ -1,7 +1,7 @@
import { AppRoutes, CrudRoutes } from "../Routes"; import { AppRoutes, CrudRoutes } from "../Routes";
import { PROJECT_NAME } from "../config/AppKey"; import { PROJECT_NAME } from "../config/AppKey";
export const usegetTitleFromRoute = (path: any) => { export const useGetTitleFromRoute = (path: any) => {
if (AppRoutes[path]) { if (AppRoutes[path]) {
return `${PROJECT_NAME} | ${AppRoutes[path]}`; return `${PROJECT_NAME} | ${AppRoutes[path]}`;
} else if (CrudRoutes[path]) { } else if (CrudRoutes[path]) {

View File

@ -30,7 +30,6 @@ const FormikFormModel: React.FC<FormikFormProps> = ({
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema} validationSchema={validationSchema}
onSubmit={handleSubmit} onSubmit={handleSubmit}
> >
{(formik) => { {(formik) => {
useEffect(() => { useEffect(() => {
@ -43,7 +42,6 @@ const FormikFormModel: React.FC<FormikFormProps> = ({
} }
}, [isOpen]); }, [isOpen]);
return <Form className="w-100">{children}</Form>; return <Form className="w-100">{children}</Form>;
}} }}
</Formik> </Formik>

View File

@ -6,13 +6,12 @@ import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities"; import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../../enums/abilities";
import { hasAbility } from "../../utils/hasAbility"; import { hasAbility } from "../../utils/hasAbility";
export { export {
SearchField, SearchField,
useModalHandler, useModalHandler,
ModalEnum, ModalEnum,
useTranslation, useTranslation,
ABILITIES_ENUM, ABILITIES_ENUM,
ABILITIES_VALUES_ENUM, ABILITIES_VALUES_ENUM,
hasAbility hasAbility,
}; };

View File

@ -1,5 +1,5 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { usegetTitleFromRoute } from "../../Hooks/usegetTitleFromRoute"; import { useGetTitleFromRoute } from "../../Hooks/useGetTitleFromRoute";
import { Helmet } from "react-helmet"; import { Helmet } from "react-helmet";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import NavBar from "./NavBar"; import NavBar from "./NavBar";
@ -18,7 +18,7 @@ const Layout = ({
return ( return (
<> <>
<Helmet> <Helmet>
<title>{usegetTitleFromRoute(location.pathname)}</title> <title>{useGetTitleFromRoute(location.pathname)}</title>
</Helmet> </Helmet>
<div className="Layout"> <div className="Layout">
<main className={`${className} Layout_Body`}> <main className={`${className} Layout_Body`}>

View File

@ -80,7 +80,8 @@ const SideBar = () => {
<div className="side_bar"> <div className="side_bar">
<h1> <h1>
{/* {t("sidebar.dashboard")} */} {/* {t("sidebar.dashboard")} */}
{branch_name} </h1> {branch_name}{" "}
</h1>
<Divider /> <Divider />
<div className="side_bar_links"> <div className="side_bar_links">
{menuItems.map((item, index) => { {menuItems.map((item, index) => {

View File

@ -20,13 +20,11 @@ type FormFieldType = {
}; };
const FormField = ({ isLoading }: FormFieldType) => { const FormField = ({ isLoading }: FormFieldType) => {
const [t] = useTranslation(); const [t] = useTranslation();
return ( return (
<Form className="AuthForm"> <Form className="AuthForm">
<Image src="../App/Logo.png" /> <Image src="../App/Logo.png" />
<div className="AuthInput"> <div className="AuthInput">
<label className="form-label" htmlFor="username"> <label className="form-label" htmlFor="username">
{t("input.Username")} {t("input.Username")}

View File

@ -13,7 +13,6 @@ const LoginForm = () => {
const { mutate, isLoading, isSuccess, data } = useLoginAdmin(); const { mutate, isLoading, isSuccess, data } = useLoginAdmin();
const [t] = useTranslation(); const [t] = useTranslation();
const handelSubmit = (values: FormValues) => { const handelSubmit = (values: FormValues) => {
mutate(values); mutate(values);
}; };

View File

@ -2,14 +2,14 @@ import React from "react";
import Image from "../../Components/Ui/Image"; import Image from "../../Components/Ui/Image";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../enums/abilities"; import { ABILITIES_ENUM } from "../../enums/abilities";
import useSetPage_title from "../../Hooks/useSetPageTitle"; import useSetPageTitle from "../../Hooks/useSetPageTitle";
const Dummy = () => { const Dummy = () => {
const [t] = useTranslation(); const [t] = useTranslation();
useSetPage_title(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`); useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
return ( return (
<div className="DammyHomePage"> <div className="DummyHomePage">
<Image src="/App/SyriaLogo.webp" /> <Image src="/App/SyriaLogo.webp" />
</div> </div>
); );

View File

@ -1,19 +0,0 @@
import ChartSection from "./Section/ChartSection";
import NoteSections from "./Section/NoteSections";
import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../enums/abilities";
// import useSetPage_title from "../../Hooks/useSetPageTitle";
const Page = () => {
const [t] = useTranslation();
// useSetPage_title(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
return (
<div className="HomePage">
<ChartSection />
<NoteSections />
</div>
);
};
export default Page;

View File

@ -1,26 +0,0 @@
import React from "react";
import CountSection from "../../../Components/Home/CountSection";
import ColumnChart from "../../../Components/Chart/ColumnChart";
import AreaChart from "../../../Components/Chart/AreaChart";
import StudentSubjects from "../../../Components/Home/StudentSubjects";
import CalendarSection from "../../../Components/Home/CalendarSection";
const ChartSection = () => {
return (
<div className="ChartSection">
<CountSection />
<div className="TowItem">
<ColumnChart />
<CalendarSection />
</div>
<AreaChart />
<div className="TowItem">
<StudentSubjects />
<ColumnChart />
</div>
</div>
);
};
export default ChartSection;

View File

@ -1,14 +0,0 @@
import React from "react";
import NoteSection from "../../../Components/Home/NoteSection";
import ActivitySection from "../../../Components/Home/ActivitySection";
const NoteSections = () => {
return (
<div className="NoteSections">
<NoteSection />
<ActivitySection />
</div>
);
};
export default NoteSections;

View File

@ -24,9 +24,7 @@ const Form = () => {
<ValidationField placeholder="name" label="name" name="name" /> <ValidationField placeholder="name" label="name" name="name" />
</Col> </Col>
<div> <div>
<DynamicTags/> <DynamicTags />
</div> </div>
</Row> </Row>
); );

View File

@ -23,9 +23,8 @@ const ModalForm: React.FC = () => {
}, [setIsOpen, isSuccess]); }, [setIsOpen, isSuccess]);
const handleSubmit = (values: any) => { const handleSubmit = (values: any) => {
mutate({ mutate({
...values ...values,
}); });
}; };

View File

@ -6,16 +6,13 @@ import { useEffect } from "react";
import DynamicTags from "../synonyms/DynamicTags"; import DynamicTags from "../synonyms/DynamicTags";
const Form = () => { const Form = () => {
return ( return (
<Row className="w-100"> <Row className="w-100">
<Col> <Col>
<ValidationField placeholder="name" label="name" name="name" /> <ValidationField placeholder="name" label="name" name="name" />
</Col> </Col>
<div> <div>
<DynamicTags/> <DynamicTags />
</div> </div>
</Row> </Row>
); );

View File

@ -12,9 +12,7 @@ import ModelButtons from "../../../Components/models/ModelButtons";
const ModalForm: React.FC = () => { const ModalForm: React.FC = () => {
const { isOpen, setIsOpen } = useModalState((state) => state); const { isOpen, setIsOpen } = useModalState((state) => state);
const { objectToEdit, setObjectToEdit } = useObjectToEdit( const { objectToEdit, setObjectToEdit } = useObjectToEdit((state) => state);
(state) => state,
);
const { mutate, isSuccess, isLoading } = useUpdateTag(); const { mutate, isSuccess, isLoading } = useUpdateTag();
// console.log(objectToEdit,"objectToEdit"); // console.log(objectToEdit,"objectToEdit");
const handleSubmit = (values: any) => { const handleSubmit = (values: any) => {
@ -22,7 +20,7 @@ const ModalForm: React.FC = () => {
// phone_number: values?.number // phone_number: values?.number
// }); // });
mutate({ mutate({
...values ...values,
}); });
}; };
const handleCancel = () => { const handleCancel = () => {
@ -58,7 +56,6 @@ const ModalForm: React.FC = () => {
<main className="main_modal w-100"> <main className="main_modal w-100">
<ModelBody /> <ModelBody />
<ModelButtons isLoading={isLoading} /> <ModelButtons isLoading={isLoading} />
</main> </main>
</FormikForm> </FormikForm>
)} )}

View File

@ -1,34 +1,35 @@
import { FaPlus } from "react-icons/fa"; import { FaPlus } from "react-icons/fa";
import useModalHandler from "../../utils/useModalHandler"; import useModalHandler from "../../utils/useModalHandler";
import { ModalEnum } from "../../enums/Model"; import { ModalEnum } from "../../enums/Model";
// import useSetPage_title from "../../Hooks/useSetPageTitle"; // import useSetPageTitle from "../../Hooks/useSetPageTitle";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { lazy, Suspense } from 'react'; import { lazy, Suspense } from "react";
import { Spin } from "antd"; import { Spin } from "antd";
import { canAddTags } from "../../utils/hasAbilityFn"; import { canAddTags } from "../../utils/hasAbilityFn";
import useSetPage_title from "../../Hooks/useSetPageTitle"; import useSetPageTitle from "../../Hooks/useSetPageTitle";
const Table = lazy(() => import('./Table')); const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import('./Model/AddModel')); const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import('./Model/EditModel')); const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(() => import('./Model/Delete')); const DeleteModalForm = lazy(() => import("./Model/Delete"));
const SearchField = lazy(() => import('../../Components/DataTable/SearchField')); const SearchField = lazy(
() => import("../../Components/DataTable/SearchField"),
);
const TableHeader = () => { const TableHeader = () => {
const { handel_open_model } = useModalHandler(); const { handel_open_model } = useModalHandler();
const [t] = useTranslation(); const [t] = useTranslation();
useSetPage_title( useSetPageTitle(t(`page_header.tags`));
t(`page_header.tags`),
);
return ( return (
<div className="TableWithHeader"> <div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<Suspense fallback={<Spin/>}>
<header className="d-flex justify-content-between"> <header className="d-flex justify-content-between">
<SearchField searchBy="name" placeholder={t("practical.search_here")} /> <SearchField
searchBy="name"
placeholder={t("practical.search_here")}
/>
{canAddTags && ( {canAddTags && (
<div className="Selects"> <div className="Selects">
@ -42,7 +43,6 @@ const TableHeader = () => {
)} )}
</header> </header>
<Table /> <Table />
<DeleteModalForm /> <DeleteModalForm />
<AddModalForm /> <AddModalForm />

View File

@ -13,5 +13,5 @@ export {
AddModalForm, AddModalForm,
EditModalForm, EditModalForm,
DeleteModalForm, DeleteModalForm,
FaPlus FaPlus,
}; };

View File

@ -1,14 +1,12 @@
import { useFormikContext } from 'formik' import { useFormikContext } from "formik";
import React from 'react' import React from "react";
import { useTranslation } from 'react-i18next' import { useTranslation } from "react-i18next";
import { FaCirclePlus } from 'react-icons/fa6' import { FaCirclePlus } from "react-icons/fa6";
import Tag from './Tag' import Tag from "./Tag";
const DynamicTags = () => { const DynamicTags = () => {
const formik = useFormikContext<any>();
const formik = useFormikContext<any>() const [t] = useTranslation();
const [t] = useTranslation()
console.log(formik?.values?.synonyms); console.log(formik?.values?.synonyms);
@ -16,55 +14,43 @@ const DynamicTags = () => {
const length = formik?.values?.synonyms.length; const length = formik?.values?.synonyms.length;
const lastElement = formik?.values?.synonyms[length - 1]; const lastElement = formik?.values?.synonyms[length - 1];
if(lastElement !== ""){ if (lastElement !== "") {
formik.setFieldValue('synonyms', [...(formik?.values as any)?.synonyms as any[],""]) formik.setFieldValue("synonyms", [
}else{ ...((formik?.values as any)?.synonyms as any[]),
"",
]);
} else {
} }
};
// console.log(formik?.values);
} // console.log(currentTag);
// console.log(formik?.values);
// console.log(currentTag);
return ( return (
<div className='DynamicTags'> <div className="DynamicTags">
{formik?.values?.synonyms?.length < 1 && {formik?.values?.synonyms?.length < 1 && (
<p className="add_new_button">
<p className="add_new_button" > <FaCirclePlus size={23} onClick={handleAddChoice} />{" "}
<FaCirclePlus size={23} onClick={handleAddChoice} /> {t("header.add_synonyms")} {t("header.add_synonyms")}
</p> </p>
} )}
<div className="tag_container"> <div className="tag_container">
<div className="tags"> <div className="tags">
{(((formik?.values as any)?.synonyms as any[]) || []).map(
{ (item: any, index: number) => {
(((formik?.values as any)?.synonyms as any[])||[]) .map((item:any,index:number)=>{ return <Tag key={index} index={index} data={item} />;
},
return ( )}
<Tag key={index} index={index} data={item}/>
)
}
)
}
</div> </div>
{formik?.values?.synonyms?.length > 0 && {formik?.values?.synonyms?.length > 0 && (
<p className="add_new_button">
<p className="add_new_button" >
<FaCirclePlus onClick={handleAddChoice} size={20} /> <FaCirclePlus onClick={handleAddChoice} size={20} />
</p> </p>
)}
}
</div> </div>
</div> </div>
) );
} };
export default DynamicTags export default DynamicTags;

View File

@ -1,12 +1,12 @@
import { useFormikContext } from 'formik'; import { useFormikContext } from "formik";
import React, { useRef, useEffect } from 'react'; import React, { useRef, useEffect } from "react";
import { useObjectToEdit } from '../../../zustand/ObjectToEditState'; import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { FaTrash } from 'react-icons/fa'; import { FaTrash } from "react-icons/fa";
const Tag = ({ data, index }: { data: any, index: number }) => { const Tag = ({ data, index }: { data: any; index: number }) => {
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
const { setTagsSearch ,setCurrentTag} = useObjectToEdit(); const { setTagsSearch, setCurrentTag } = useObjectToEdit();
useEffect(() => { useEffect(() => {
if (inputRef.current) { if (inputRef.current) {
@ -16,13 +16,11 @@ const Tag = ({ data, index }: { data: any, index: number }) => {
console.log(formik?.values?.synonyms); console.log(formik?.values?.synonyms);
console.log(index); console.log(index);
const handleEditInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleEditInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// console.log(e.target.value); // console.log(e.target.value);
formik.setFieldValue(`synonyms[${index}]`, e.target.value); formik.setFieldValue(`synonyms[${index}]`, e.target.value);
setTagsSearch(e.target.value) setTagsSearch(e.target.value);
setCurrentTag(index) setCurrentTag(index);
}; };
const handleInputBlur = () => { const handleInputBlur = () => {
@ -38,14 +36,14 @@ const Tag = ({ data, index }: { data: any, index: number }) => {
console.log(currentTags); // Log the updated tags array console.log(currentTags); // Log the updated tags array
// Update formik field value with the updated tags array // Update formik field value with the updated tags array
formik.setFieldValue('synonyms', currentTags); formik.setFieldValue("synonyms", currentTags);
// Reset search state if needed // Reset search state if needed
setTagsSearch(null); setTagsSearch(null);
}; };
return ( return (
<div className='tag'> <div className="tag">
<input <input
ref={inputRef} ref={inputRef}
className="tagInput" className="tagInput"
@ -53,14 +51,10 @@ const Tag = ({ data, index }: { data: any, index: number }) => {
value={formik?.values?.synonyms[index]} value={formik?.values?.synonyms[index]}
onChange={handleEditInputChange} onChange={handleEditInputChange}
onBlur={handleInputBlur} onBlur={handleInputBlur}
/> />
<FaTrash onClick={handleDeleteChoice}/> <FaTrash onClick={handleDeleteChoice} />
</div> </div>
); );
}; };
export default Tag; export default Tag;

View File

@ -19,8 +19,6 @@ export const useColumns = () => {
}; };
const [t] = useTranslation(); const [t] = useTranslation();
const columns: TableColumnsType<tags> = [ const columns: TableColumnsType<tags> = [
{ {
title: t("columns.id"), title: t("columns.id"),
@ -57,16 +55,10 @@ export const useColumns = () => {
placement="top" placement="top"
title={t("practical.edit")} title={t("practical.edit")}
color="#E0E0E0" color="#E0E0E0"
> >
<span onClick={() => handleEdit(record)}> <span onClick={() => handleEdit(record)}>
<MdOutlineEdit <MdOutlineEdit size={22} style={{ color: "#A098AE" }} />
size={22}
style={{ color: "#A098AE" }}
/>
</span> </span>
</Tooltip> </Tooltip>
)} )}

View File

@ -1,49 +1,42 @@
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { lazy, Suspense } from 'react'; import { lazy, Suspense } from "react";
import { Spin } from "antd"; import { Spin } from "antd";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { ParamsEnum } from "../../enums/params"; import { ParamsEnum } from "../../enums/params";
import { useGetAllSubject } from "../../api/subject"; import { useGetAllSubject } from "../../api/subject";
import useSetPage_title from "../../Hooks/useSetPageTitle"; import useSetPageTitle from "../../Hooks/useSetPageTitle";
const Table = lazy(() => import('./Table')); const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import('./Model/AddModel')); const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import('./Model/EditModel')); const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModels = lazy(() => import('./Model/Delete')); const DeleteModels = lazy(() => import("./Model/Delete"));
const TableHeader = () => { const TableHeader = () => {
const [t] = useTranslation(); const [t] = useTranslation();
const { subject_id} = useParams<ParamsEnum>(); const { subject_id } = useParams<ParamsEnum>();
const { data: Subject } = useGetAllSubject({ const { data: Subject } = useGetAllSubject({
show:subject_id show: subject_id,
}); });
const SubjectName = Subject?.data?.name ?? ""; const SubjectName = Subject?.data?.name ?? "";
useSetPage_title( useSetPageTitle(t(`page_header.subject`) + "/" + t(`${SubjectName}`));
t(`page_header.subject`) +
"/" +
t(`${SubjectName}`),
);
return ( return (
<div className="TableWithHeader"> <div className="TableWithHeader">
<Suspense fallback={<Spin/>}> <Suspense fallback={<Spin />}>
<header> <header>
<h6> <h6>
{t("models.units")} {SubjectName} {t("models.units")} {SubjectName}
</h6> </h6>
</header> </header>
<Table /> <Table />
<AddModalForm /> <AddModalForm />
<EditModalForm /> <EditModalForm />
<DeleteModels /> <DeleteModels />
</Suspense> </Suspense>
</div> </div>
); );
}; };

View File

@ -7,9 +7,9 @@ import { useParams } from "react-router-dom";
import { ParamsEnum } from "../../enums/params"; import { ParamsEnum } from "../../enums/params";
const App: React.FC = () => { const App: React.FC = () => {
const {subject_id} = useParams<ParamsEnum>() const { subject_id } = useParams<ParamsEnum>();
const response = useGetAllUnit({subject_id:subject_id, pagination: true}); const response = useGetAllUnit({ subject_id: subject_id, pagination: true });
console.log(response?.data?.data,"response?.data"); console.log(response?.data?.data, "response?.data");
return <DataTable response={response} useColumns={useColumns} />; return <DataTable response={response} useColumns={useColumns} />;
}; };

View File

@ -10,20 +10,23 @@ import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../enums/abilities"; import { ABILITIES_ENUM } from "../../enums/abilities";
import { BsEyeFill } from "react-icons/bs"; import { BsEyeFill } from "react-icons/bs";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { canAddUnit, canDeleteUnit, canEditUnit, canShowUnit } from "../../utils/hasAbilityFn"; import {
canAddUnit,
canDeleteUnit,
canEditUnit,
canShowUnit,
} from "../../utils/hasAbilityFn";
export const useColumns = () => { export const useColumns = () => {
const { handel_open_model } = useModalHandler(); const { handel_open_model } = useModalHandler();
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate() const navigate = useNavigate();
const handelShow = (record: any) => { const handelShow = (record: any) => {
navigate(`${ABILITIES_ENUM?.UNIT}/${record?.id}`); navigate(`${ABILITIES_ENUM?.UNIT}/${record?.id}`);
}; };
const handelDelete = (data: any) => { const handelDelete = (data: any) => {
setObjectToEdit(data); setObjectToEdit(data);
handel_open_model(ModalEnum?.UNIT_DELETE); handel_open_model(ModalEnum?.UNIT_DELETE);
@ -86,11 +89,7 @@ export const useColumns = () => {
color="#E0E0E0" color="#E0E0E0"
> >
<span onClick={() => handleEdit(record)}> <span onClick={() => handleEdit(record)}>
<MdOutlineEdit <MdOutlineEdit size={22} style={{ color: "#A098AE" }} />
size={22}
style={{ color: "#A098AE" }}
/>
</span> </span>
</Tooltip> </Tooltip>
)} )}
@ -102,15 +101,12 @@ export const useColumns = () => {
/> />
)} )}
{canShowUnit && ( {canShowUnit && (
<BsEyeFill <BsEyeFill
onClick={() => handelShow(record)} onClick={() => handelShow(record)}
size={22} size={22}
style={{ color: "green" }} style={{ color: "green" }}
/> />
)} )}
</Space> </Space>
); );
}, },

View File

@ -20,7 +20,6 @@ const Form = () => {
<Col> <Col>
<ValidationField name="name" label="name" /> <ValidationField name="name" label="name" />
</Col> </Col>
</Row> </Row>
); );
}; };

View File

@ -20,7 +20,7 @@ const ModalForm: React.FC = () => {
const { mutate, isSuccess, isLoading } = useAddLesson(); const { mutate, isSuccess, isLoading } = useAddLesson();
const {unit_id} = useParams<ParamsEnum>() const { unit_id } = useParams<ParamsEnum>();
useEffect(() => { useEffect(() => {
if (isSuccess) { if (isSuccess) {
setIsOpen(""); setIsOpen("");

View File

@ -12,7 +12,7 @@ const ModalForm: React.FC = () => {
const [inputValue, setInputValue] = useState(""); const [inputValue, setInputValue] = useState("");
const { mutate, isSuccess, isLoading } = useDeleteLesson(); const { mutate, isSuccess, isLoading } = useDeleteLesson();
const { objectToEdit,setObjectToEdit } = useObjectToEdit((state) => state); const { objectToEdit, setObjectToEdit } = useObjectToEdit((state) => state);
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [t] = useTranslation(); const [t] = useTranslation();
const handleSubmit = () => { const handleSubmit = () => {

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