Compare commits
2 Commits
8f993912fc
...
a5f54f1794
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5f54f1794 | ||
|
|
ee5a3b7b14 |
|
|
@ -5,11 +5,13 @@ import { Spin } from "antd";
|
|||
import { hasAbility } from "./utils/hasAbility";
|
||||
import { renderRoutesRecursively } from "./Components/Routes/RenderRoutesRecursively";
|
||||
import { RenderRouteElement } from "./Components/Routes/RenderRouteElement";
|
||||
import { UserTypeEnum } from "./enums/UserType";
|
||||
import { RoleByType } from "./utils/RoleByType";
|
||||
|
||||
const Page404 = lazy(() => import("./Layout/Ui/NotFoundPage"));
|
||||
const Auth = lazy(() => import("./Pages/Auth/Page"));
|
||||
|
||||
const App = () => {
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
|
|
@ -31,10 +33,14 @@ const App = () => {
|
|||
}
|
||||
/>
|
||||
|
||||
|
||||
{renderRoutesRecursively(menuItems)}
|
||||
|
||||
{CrudRoute.map((route) => {
|
||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||
if(!RoleByType(route)){
|
||||
return false ;
|
||||
}
|
||||
if (!useAbility) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,17 @@ import { TMenuItem } from "../../types/App";
|
|||
import { hasAbility } from "../../utils/hasAbility";
|
||||
import { Route } from "react-router-dom";
|
||||
import { RenderRouteElement } from "./RenderRouteElement";
|
||||
import { UserTypeEnum } from "../../enums/UserType";
|
||||
import Item from "antd/es/list/Item";
|
||||
import { RoleByType } from "../../utils/RoleByType";
|
||||
|
||||
export const renderRoutesRecursively = (routes: TMenuItem[]) =>
|
||||
routes.map((route: TMenuItem) => {
|
||||
const useAbility = hasAbility(route.abilities, route.abilities_value);
|
||||
if(!RoleByType(route)){
|
||||
return false ;
|
||||
}
|
||||
|
||||
if (!useAbility) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const Date = ({
|
|||
formik.setFieldValue(name, value);
|
||||
};
|
||||
|
||||
const Formatter = [DateEnum?.FORMATE, DateEnum?.FORMATE2];
|
||||
const Formatter = [DateEnum?.FORMATE];
|
||||
return (
|
||||
<div className="ValidationField w-100 ">
|
||||
<ValidationFieldLabel
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import { useTranslation } from "react-i18next";
|
|||
import { getLocalStorage } from "../../utils/LocalStorage";
|
||||
import { BRANCH_OBJECT_KEY } from "../../config/AppKey";
|
||||
import { MenuItem } from "../../Components/Layout/SideBar/MenuItem";
|
||||
import { UserTypeEnum } from "../../enums/UserType";
|
||||
import { RoleByType } from "../../utils/RoleByType";
|
||||
|
||||
const SideBar = () => {
|
||||
const location = useLocation();
|
||||
|
|
@ -17,7 +19,6 @@ const SideBar = () => {
|
|||
const { logout } = useAuthState();
|
||||
const [t] = useTranslation();
|
||||
const branch_name = getLocalStorage(BRANCH_OBJECT_KEY)?.name;
|
||||
|
||||
return (
|
||||
<div className="side_bar">
|
||||
<h1>
|
||||
|
|
@ -31,6 +32,11 @@ const SideBar = () => {
|
|||
if (!useAbility) {
|
||||
return <React.Fragment key={index}></React.Fragment>;
|
||||
}
|
||||
if(!RoleByType(item)){
|
||||
|
||||
return <React.Fragment key={index}></React.Fragment> ;
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
key={index}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { Formik } from "formik";
|
||||
import useAuthState from "../../zustand/AuthState";
|
||||
import useNavigateOnSuccess from "../../Hooks/useNavigateOnSuccess";
|
||||
|
|
@ -8,6 +8,9 @@ import { initialValues } from "./formutils";
|
|||
import { FormValues } from "../../types/Auth";
|
||||
import { toast } from "react-toastify";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { getLocalStorage } from "../../utils/LocalStorage";
|
||||
import { USER_KEY } from "../../config/AppKey";
|
||||
|
||||
const LoginForm = () => {
|
||||
const { mutate, isLoading, isSuccess, data } = useLoginAdmin();
|
||||
|
|
@ -16,11 +19,27 @@ const LoginForm = () => {
|
|||
mutate(values);
|
||||
};
|
||||
|
||||
const { login } = useAuthState();
|
||||
const { login,isAuthenticated} = useAuthState();
|
||||
const LoginData = {
|
||||
...data,
|
||||
|
||||
} as any;
|
||||
useNavigateOnSuccess(isSuccess, "/", () => login(LoginData?.data as any));
|
||||
const navigate = useNavigate()
|
||||
const LocalType = getLocalStorage(USER_KEY)?.type ?? false ;
|
||||
useEffect(() => {
|
||||
|
||||
if(isSuccess){
|
||||
login(LoginData?.data as any)
|
||||
|
||||
}
|
||||
}, [isSuccess])
|
||||
|
||||
useEffect(() => {
|
||||
if(LocalType ){
|
||||
window.location.href = ("/")
|
||||
}
|
||||
}, [LocalType])
|
||||
|
||||
|
||||
return (
|
||||
<div className="LoginForm">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
|
|
@ -14,7 +14,7 @@ import { PackageInitialValues } from "../../../types/Package";
|
|||
import { arrayToObject } from "../../../utils/arrayToObject";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
const { mutate, status ,isLoading} = useAddPackage();
|
||||
const { mutate, status ,isLoading,isSuccess} = useAddPackage();
|
||||
const [t] = useTranslation();
|
||||
const navigate = useNavigate()
|
||||
const handleSubmit = (values: PackageInitialValues) => {
|
||||
|
|
@ -29,6 +29,11 @@ const AddModel: React.FC = () => {
|
|||
...values,
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if(isSuccess){
|
||||
navigate("/package")
|
||||
}
|
||||
}, [isSuccess])
|
||||
|
||||
useSetPageTitle(t(`page_header.package`));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
||||
import ModelForm from "./ModelForm";
|
||||
import FormikForm from "../../../Layout/Dashboard/FormikForm";
|
||||
|
|
@ -14,7 +14,7 @@ import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|||
import SpinContainer from "../../../Components/Layout/SpinContainer";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status ,isLoading} = useUpdatePackage();
|
||||
const { mutate, status ,isLoading,isSuccess} = useUpdatePackage();
|
||||
const [t] = useTranslation();
|
||||
const {package_id} = useParams<ParamsEnum>();
|
||||
const {objectToEdit} = useObjectToEdit();
|
||||
|
|
@ -34,6 +34,12 @@ const EditModel: React.FC = () => {
|
|||
...values,
|
||||
});
|
||||
};
|
||||
const navigate = useNavigate()
|
||||
useEffect(() => {
|
||||
if(isSuccess){
|
||||
navigate("/package")
|
||||
}
|
||||
}, [isSuccess])
|
||||
|
||||
useSetPageTitle(t(`page_header.package`));
|
||||
if(isLoadingData){
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ const Form = () => {
|
|||
<ValidationField placeholder="name" label="name" name="name" />
|
||||
<ValidationField placeholder="price" label="price" name="price" type="number" />
|
||||
<FieldGroup array_name='configuration' title='configuration' />
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import * as Yup from "yup";
|
|||
import { Package, PackageInitialValues } from "../../../../types/Package";
|
||||
import { arrayToObject } from "../../../../utils/arrayToObject";
|
||||
import { objectToArray } from "../../../../utils/objectToArray";
|
||||
export const getInitialValues = (objectToEdit: Partial<Package>): PackageInitialValues => {
|
||||
export const getInitialValues = (objectToEdit: Partial<Package>): any => {
|
||||
console.log(objectToEdit,"objectToEdit");
|
||||
|
||||
const configuration = Array.isArray(objectToEdit?.configuration) ? objectToEdit?.configuration : objectToArray(objectToEdit?.configuration)
|
||||
|
|
@ -16,6 +16,7 @@ export const getInitialValues = (objectToEdit: Partial<Package>): PackageInitial
|
|||
subjects_ids: objectToEdit?.subjects_ids ?? [],
|
||||
units_ids: objectToEdit?.units_ids ?? [],
|
||||
configuration: configuration ?? [{key:"",value:""}],
|
||||
moiaed: [{key:"",value:""}],
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const TableHeader = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteReSeller();
|
||||
|
||||
useSetPageTitle(t(`page_header.ReSeller`));
|
||||
useSetPageTitle(t(`page_header.reSeller`));
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
|
|
|
|||
33
src/Pages/Student/Model/AddModel.tsx
Normal file
33
src/Pages/Student/Model/AddModel.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import React from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import ModelForm from "./ModelForm";
|
||||
import { useAddStudent } from "../../../api/student";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
const { mutate, status } = useAddStudent();
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
mutate({
|
||||
...values,
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.STUDENT_ADD}
|
||||
modelTitle="student"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues({})}
|
||||
getValidationSchema={getValidationSchema}
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddModel;
|
||||
37
src/Pages/Student/Model/EditModel.tsx
Normal file
37
src/Pages/Student/Model/EditModel.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import React from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
import ModelForm from "./ModelForm";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
import { useUpdateStudent } from "../../../api/student";
|
||||
import { handelImageState } from "../../../utils/DataToSendImageState";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status } = useUpdateStudent();
|
||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
const Data_to_send = { ...values };
|
||||
mutate(Data_to_send);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.STUDENT_EDIT}
|
||||
modelTitle="student"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues(objectToEdit)}
|
||||
getValidationSchema={getValidationSchema}
|
||||
isAddModal={false}
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditModel;
|
||||
58
src/Pages/Student/Model/ModelForm.tsx
Normal file
58
src/Pages/Student/Model/ModelForm.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { Col, Row } from "reactstrap";
|
||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||
import { useGetAllGrade } from "../../../api/grade";
|
||||
import { useValidationValidationParamState } from "../../../Components/ValidationField/state/ValidationValidationParamState";
|
||||
|
||||
const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
|
||||
const { ValidationParamState } = useValidationValidationParamState();
|
||||
const {
|
||||
GradeName, GradeCurrentPage,
|
||||
} = ValidationParamState;
|
||||
|
||||
|
||||
const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({
|
||||
name: GradeName,
|
||||
page: GradeCurrentPage
|
||||
});
|
||||
const GradeOption = Grade?.data ?? []
|
||||
const canChangeGradePage = !!Grade?.links?.next;
|
||||
const GradePage = Grade?.meta?.currentPage;
|
||||
|
||||
const sex = [
|
||||
{name:"male" , id :"male"},
|
||||
{name:"female" , id :"female"}
|
||||
]
|
||||
return (
|
||||
<Row className="w-100">
|
||||
<Col>
|
||||
<ValidationField name="first_name" placeholder="first_name" label="first_name" />
|
||||
<ValidationField name="last_name" placeholder="last_name" label="last_name" />
|
||||
<ValidationField name="username" placeholder="username" label="username" />
|
||||
{!isEdit &&
|
||||
<ValidationField name="password" placeholder="password" label="password" />
|
||||
}
|
||||
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="phone_number" placeholder="contact_number1" label="contact_number1" />
|
||||
<ValidationField
|
||||
searchBy="GradeName"
|
||||
name="grade_id"
|
||||
label="grade"
|
||||
type="Search"
|
||||
option={GradeOption}
|
||||
isLoading={isLoadingGrade}
|
||||
canChangePage={canChangeGradePage}
|
||||
PageName={"GradeCurrentPage"}
|
||||
page={GradePage}
|
||||
|
||||
/>
|
||||
<ValidationField type="Select" name="sex" option={sex} />
|
||||
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export default Form;
|
||||
27
src/Pages/Student/Model/formUtil.ts
Normal file
27
src/Pages/Student/Model/formUtil.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import * as Yup from "yup";
|
||||
import { Student, StudentInitialValues } from "../../../types/Student";
|
||||
|
||||
export const getInitialValues = (
|
||||
objectToEdit: Partial<Student>,
|
||||
): StudentInitialValues => {
|
||||
return {
|
||||
id: objectToEdit?.user_id,
|
||||
first_name: objectToEdit?.first_name ?? "",
|
||||
last_name: objectToEdit?.last_name ?? "",
|
||||
// address: objectToEdit?.address ?? "",
|
||||
// birthday: objectToEdit?.birthday ?? "",
|
||||
// city: objectToEdit?.city ?? "",
|
||||
grade_id: objectToEdit?.grade_id ,
|
||||
// image: objectToEdit?.image ?? "",
|
||||
sex: objectToEdit?.sex ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = () => {
|
||||
// validate input
|
||||
return Yup.object().shape({
|
||||
first_name: Yup.string().required("validation.required"),
|
||||
last_name: Yup.string().required("validation.required"),
|
||||
});
|
||||
};
|
||||
39
src/Pages/Student/Page.tsx
Normal file
39
src/Pages/Student/Page.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { lazy, Suspense } from "react";
|
||||
import { Spin } from "antd";
|
||||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useDeleteStudent } from "../../api/student";
|
||||
|
||||
const Table = lazy(() => import("./Table"));
|
||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||
const DeleteModalForm = lazy(
|
||||
() => import("../../Layout/Dashboard/DeleteModels"),
|
||||
);
|
||||
|
||||
const TableHeader = () => {
|
||||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteStudent();
|
||||
|
||||
useSetPageTitle(t(`page_header.student`));
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<header>
|
||||
<h6>{t("models.student")}</h6>
|
||||
</header>
|
||||
<Table />
|
||||
<AddModalForm />
|
||||
<EditModalForm />
|
||||
<DeleteModalForm
|
||||
deleteMutation={deleteMutation}
|
||||
ModelEnum={ModalEnum?.STUDENT_DELETE}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableHeader;
|
||||
13
src/Pages/Student/Table.tsx
Normal file
13
src/Pages/Student/Table.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { useColumns } from "./useTableColumns";
|
||||
import React from "react";
|
||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
||||
import { useGetAllStudent } from "../../api/student";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const response = useGetAllStudent({ pagination: true });
|
||||
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
101
src/Pages/Student/useTableColumns.tsx
Normal file
101
src/Pages/Student/useTableColumns.tsx
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import { TableColumnsType } from "antd";
|
||||
import { Student } from "../../types/Student";
|
||||
import { FaPlus } from "react-icons/fa";
|
||||
import useModalHandler from "../../utils/useModalHandler";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
canAddStudent,
|
||||
canDeleteStudent,
|
||||
canEditStudent,
|
||||
canShowStudent,
|
||||
} from "../../utils/hasAbilityFn";
|
||||
import ActionButtons from "../../Components/Table/ActionButtons";
|
||||
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handelShow = (record: Student) => {
|
||||
navigate(`${record?.user_id}`);
|
||||
};
|
||||
|
||||
const handelDelete = (data: Student) => {
|
||||
setObjectToEdit(data);
|
||||
handel_open_model(ModalEnum?.STUDENT_DELETE);
|
||||
};
|
||||
|
||||
const handleEdit = (record: Student) => {
|
||||
setObjectToEdit(record);
|
||||
handel_open_model(ModalEnum?.STUDENT_EDIT);
|
||||
};
|
||||
const [t] = useTranslation();
|
||||
|
||||
const columns: TableColumnsType<Student> = [
|
||||
{
|
||||
title: t("columns.id"),
|
||||
dataIndex: "id",
|
||||
key: "id",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.user_id,
|
||||
},
|
||||
{
|
||||
title: `${t("columns.first_name")}`,
|
||||
dataIndex: "first_name",
|
||||
key: "first_name",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.first_name,
|
||||
},
|
||||
{
|
||||
title: `${t("columns.last_name")}`,
|
||||
dataIndex: "last_name",
|
||||
key: "last_name",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.last_name,
|
||||
},
|
||||
{
|
||||
title: `${t("columns.sex")}`,
|
||||
dataIndex: "sex",
|
||||
key: "sex",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.sex,
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
title: canAddStudent ? (
|
||||
<button
|
||||
onClick={() => handel_open_model(ModalEnum?.STUDENT_ADD)}
|
||||
className="add_button"
|
||||
>
|
||||
{t("practical.add")} {t("models.student")} <FaPlus />
|
||||
</button>
|
||||
) : (
|
||||
""
|
||||
),
|
||||
|
||||
key: "actions",
|
||||
align: "end",
|
||||
width: "25vw",
|
||||
render: (_text, record, index) => {
|
||||
return (
|
||||
<ActionButtons
|
||||
canDelete={canDeleteStudent}
|
||||
canEdit={canEditStudent}
|
||||
canShow={canShowStudent}
|
||||
index={index}
|
||||
onDelete={() => handelDelete(record)}
|
||||
onEdit={() => handleEdit(record)}
|
||||
onShow={() => handelShow(record)}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return columns;
|
||||
};
|
||||
|
|
@ -12,10 +12,13 @@ import {
|
|||
} from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { Button, Table } from "antd";
|
||||
import type { TableColumnsType } from "antd";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../enums/params";
|
||||
import { useGetAllUnit } from "../../api/unit";
|
||||
import { useGetAllUnit, useUpdateUnitOrder } from "../../api/unit";
|
||||
import Loading from "../../Components/DataState/Loading";
|
||||
import EmptyData from "../../Components/DataState/EmptyData";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useColumns } from "./useTableColumns";
|
||||
|
||||
interface DataType {
|
||||
id: string; // Unique identifier for each row
|
||||
|
|
@ -32,7 +35,7 @@ interface RowContextProps {
|
|||
|
||||
const RowContext = React.createContext<RowContextProps>({});
|
||||
|
||||
const DragHandle: React.FC = () => {
|
||||
export const DragHandleUnit: React.FC = () => {
|
||||
const { setActivatorNodeRef, listeners } = useContext(RowContext);
|
||||
return (
|
||||
<Button
|
||||
|
|
@ -46,12 +49,6 @@ const DragHandle: React.FC = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const columns: TableColumnsType<DataType> = [
|
||||
{ key: "sort", align: "center", width: 80, render: () => <DragHandle /> },
|
||||
{ title: "Name", dataIndex: "name" },
|
||||
{ title: "Age", dataIndex: "age" },
|
||||
{ title: "Address", dataIndex: "address" },
|
||||
];
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
"data-row-key": string;
|
||||
|
|
@ -96,13 +93,10 @@ const DrapableTable: React.FC = () => {
|
|||
response?.data?.data?.map((item: any, index: number) => ({
|
||||
id: item.id, // Ensure this is a unique identifier
|
||||
order: index + 1, // Assign order based on index
|
||||
name: item.name,
|
||||
age: item.age,
|
||||
address: item.address,
|
||||
...item
|
||||
})) ?? [];
|
||||
|
||||
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
||||
console.log(dataSource, "dataSource");
|
||||
|
||||
useEffect(() => {
|
||||
// Update dataSource when the fetched data changes
|
||||
|
|
@ -110,28 +104,51 @@ const DrapableTable: React.FC = () => {
|
|||
setDataSource(sortedData);
|
||||
}, [response?.data?.data]);
|
||||
|
||||
const {mutate:orderUnit} = useUpdateUnitOrder({},{
|
||||
retry:false
|
||||
})
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
setDataSource((prevState) => {
|
||||
const activeIndex = prevState.findIndex(
|
||||
(record) => record.id === active.id,
|
||||
);
|
||||
|
||||
const overIndex = prevState.findIndex(
|
||||
//@ts-ignore
|
||||
(record) => record.id === over.id,
|
||||
);
|
||||
|
||||
// Move the items in the array
|
||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||
|
||||
// Update the order based on the new positions
|
||||
return newState.map((item, index) => ({
|
||||
const orderedNewState = newState.map((item, index) => ({
|
||||
...item,
|
||||
order: index + 1, // Update the order based on the new index
|
||||
}));
|
||||
// Update the order based on the new positions
|
||||
const orderedNewStateWithNewChape = orderedNewState?.map((item:any)=>{
|
||||
return {
|
||||
"unit_id":item?.id,
|
||||
"order":item?.order
|
||||
}
|
||||
})
|
||||
orderUnit({units: orderedNewStateWithNewChape, _method:"PUT"})
|
||||
return orderedNewState
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const getRowClassName = (record: any, index: number): string => {
|
||||
return index % 2 === 0 ? "even-row" : "odd-row";
|
||||
};
|
||||
const isRefetching = response?.isRefetching;
|
||||
const [t] = useTranslation()
|
||||
const columns = useColumns();
|
||||
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order) ;
|
||||
console.log(sortedDataSource,"sortedDataSource");
|
||||
|
||||
return (
|
||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||
<SortableContext
|
||||
|
|
@ -141,9 +158,26 @@ const DrapableTable: React.FC = () => {
|
|||
<Table
|
||||
rowKey="id"
|
||||
components={{ body: { row: Row } }}
|
||||
//@ts-ignore
|
||||
columns={columns}
|
||||
dataSource={dataSource.sort((a, b) => a.order - b.order)} // Sort by order for rendering
|
||||
dataSource={sortedDataSource}
|
||||
pagination={false}
|
||||
rowClassName={(record, index) => getRowClassName(record, index)}
|
||||
className="DataTable"
|
||||
loading={{
|
||||
spinning: response?.isLoading || isRefetching,
|
||||
indicator: <Loading />,
|
||||
size: "large",
|
||||
}}
|
||||
locale={{
|
||||
emptyText: (
|
||||
<EmptyData
|
||||
loading={response?.isLoading}
|
||||
header={t("Table.header")}
|
||||
info={t("Table.info")}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const Form = () => {
|
|||
placeholder="term"
|
||||
label="term"
|
||||
option={termsArray}
|
||||
fieldNames={{label:"label",value:"value"}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ const TableHeader = () => {
|
|||
<header>
|
||||
<h6>{t("models.units")}</h6>
|
||||
</header>
|
||||
<Table />
|
||||
<DrapableTable />
|
||||
<AddModalForm />
|
||||
<EditModalForm />
|
||||
<DeleteModalForm
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from "../../utils/hasAbilityFn";
|
||||
import ActionButtons from "../../Components/Table/ActionButtons";
|
||||
import { Unit } from "../../types/Unit";
|
||||
|
||||
import { DragHandleUnit } from "./DrapableTable";
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
||||
|
|
@ -40,6 +40,7 @@ export const useColumns = () => {
|
|||
const [t] = useTranslation();
|
||||
|
||||
const columns: TableColumnsType<Unit> = [
|
||||
{ key: "sort", align: "center", width: 80, render: () => <DragHandleUnit /> },
|
||||
{
|
||||
title: t("columns.id"),
|
||||
dataIndex: "id",
|
||||
|
|
@ -60,7 +61,13 @@ export const useColumns = () => {
|
|||
dataIndex: "term",
|
||||
key: "term",
|
||||
align: "center",
|
||||
render: (text, record) => record?.term,
|
||||
render: (text, record) => {
|
||||
console.log(record);
|
||||
|
||||
return (
|
||||
record?.term
|
||||
)
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
|||
185
src/Pages/lesson/DrapableTable.tsx
Normal file
185
src/Pages/lesson/DrapableTable.tsx
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
import React, { useContext, useEffect, useMemo } from "react";
|
||||
import { HolderOutlined } from "@ant-design/icons";
|
||||
import type { DragEndEvent } from "@dnd-kit/core";
|
||||
import { DndContext } from "@dnd-kit/core";
|
||||
import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities";
|
||||
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
||||
import {
|
||||
arrayMove,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
verticalListSortingStrategy,
|
||||
} from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { Button, Table } from "antd";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { ParamsEnum } from "../../enums/params";
|
||||
import { useGetAllLesson, useUpdateLessonOrder } from "../../api/lesson";
|
||||
import Loading from "../../Components/DataState/Loading";
|
||||
import EmptyData from "../../Components/DataState/EmptyData";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useColumns } from "./useTableColumns";
|
||||
|
||||
interface DataType {
|
||||
id: string; // Unique identifier for each row
|
||||
order: number;
|
||||
name: string;
|
||||
age: number;
|
||||
address: string;
|
||||
}
|
||||
|
||||
interface RowContextProps {
|
||||
setActivatorNodeRef?: (element: HTMLElement | null) => void;
|
||||
listeners?: SyntheticListenerMap;
|
||||
}
|
||||
|
||||
const RowContext = React.createContext<RowContextProps>({});
|
||||
|
||||
export const DragHandleLesson: React.FC = () => {
|
||||
const { setActivatorNodeRef, listeners } = useContext(RowContext);
|
||||
return (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<HolderOutlined />}
|
||||
style={{ cursor: "move" }}
|
||||
ref={setActivatorNodeRef}
|
||||
{...listeners}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||
"data-row-key": string;
|
||||
}
|
||||
|
||||
const Row: React.FC<RowProps> = (props) => {
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
setActivatorNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
isDragging,
|
||||
} = useSortable({ id: props["data-row-key"] });
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
...props.style,
|
||||
transform: CSS.Translate.toString(transform),
|
||||
transition,
|
||||
...(isDragging ? { position: "relative", zIndex: 9999 } : {}),
|
||||
};
|
||||
|
||||
const contextValue = useMemo<RowContextProps>(
|
||||
() => ({ setActivatorNodeRef, listeners }),
|
||||
[setActivatorNodeRef, listeners],
|
||||
);
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={contextValue}>
|
||||
<tr {...props} ref={setNodeRef} style={style} {...attributes} />
|
||||
</RowContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const DrapableTable: React.FC = () => {
|
||||
const { subject_id } = useParams<ParamsEnum>();
|
||||
const response = useGetAllLesson({ subject_id: subject_id, pagination: false });
|
||||
|
||||
// Assuming the response contains a unique id for each item
|
||||
const data =
|
||||
response?.data?.data?.map((item: any, index: number) => ({
|
||||
id: item.id, // Ensure this is a unique identifier
|
||||
order: index + 1, // Assign order based on index
|
||||
...item
|
||||
})) ?? [];
|
||||
|
||||
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
||||
|
||||
useEffect(() => {
|
||||
// Update dataSource when the fetched data changes
|
||||
const sortedData = data.sort((a: any, b: any) => a.order - b.order);
|
||||
setDataSource(sortedData);
|
||||
}, [response?.data?.data]);
|
||||
|
||||
const {mutate:orderLesson} = useUpdateLessonOrder()
|
||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (active.id !== over?.id) {
|
||||
setDataSource((prevState) => {
|
||||
const activeIndex = prevState.findIndex(
|
||||
(record) => record.id === active.id,
|
||||
);
|
||||
|
||||
const overIndex = prevState.findIndex(
|
||||
//@ts-ignore
|
||||
(record) => record.id === over.id,
|
||||
);
|
||||
|
||||
// Move the items in the array
|
||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||
const orderedNewState = newState.map((item, index) => ({
|
||||
...item,
|
||||
order: index + 1, // Update the order based on the new index
|
||||
}));
|
||||
// Update the order based on the new positions
|
||||
const orderedNewStateWithNewChape = orderedNewState?.map((item:any)=>{
|
||||
return {
|
||||
"lesson_id":item?.id,
|
||||
"order":item?.order
|
||||
}
|
||||
})
|
||||
orderLesson({lessons: orderedNewStateWithNewChape, _method:"PUT"})
|
||||
return orderedNewState
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const getRowClassName = (record: any, index: number): string => {
|
||||
return index % 2 === 0 ? "even-row" : "odd-row";
|
||||
};
|
||||
const isRefetching = response?.isRefetching;
|
||||
const [t] = useTranslation()
|
||||
const columns = useColumns();
|
||||
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order) ;
|
||||
console.log(sortedDataSource,"sortedDataSource");
|
||||
|
||||
return (
|
||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||
<SortableContext
|
||||
items={dataSource.map((i) => i.id)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
<Table
|
||||
rowKey="id"
|
||||
components={{ body: { row: Row } }}
|
||||
//@ts-ignore
|
||||
columns={columns}
|
||||
dataSource={sortedDataSource}
|
||||
pagination={false}
|
||||
rowClassName={(record, index) => getRowClassName(record, index)}
|
||||
className="DataTable"
|
||||
loading={{
|
||||
spinning: response?.isLoading || isRefetching,
|
||||
indicator: <Loading />,
|
||||
size: "large",
|
||||
}}
|
||||
locale={{
|
||||
emptyText: (
|
||||
<EmptyData
|
||||
loading={response?.isLoading}
|
||||
header={t("Table.header")}
|
||||
info={t("Table.info")}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default DrapableTable;
|
||||
|
|
@ -12,14 +12,14 @@ import { useModalState } from "../../../zustand/Modal";
|
|||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
||||
const { setIsOpen } = useModalState((state) => state);
|
||||
const queryClient = useQueryClient();
|
||||
const { mutate, isSuccess, status } = useAddLesson();
|
||||
const { OldObjectToEdit } = useObjectToEdit();
|
||||
const { unit_id } = useParams<ParamsEnum>();
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
setIsOpen("");
|
||||
setIsOpen("isSuccess");
|
||||
queryClient.invalidateQueries(["Lesson"]);
|
||||
}
|
||||
}, [setIsOpen, isSuccess, queryClient]);
|
||||
|
|
@ -40,8 +40,9 @@ const AddModel: React.FC = () => {
|
|||
ModelEnum={ModalEnum.LESSON_ADD}
|
||||
modelTitle="lesson"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues({})}
|
||||
getInitialValues={getInitialValues({name:null})}
|
||||
getValidationSchema={getValidationSchema}
|
||||
width="40vw"
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const ModalForm: React.FC = () => {
|
|||
const { isOpen, setIsOpen } = useModalState((state) => state);
|
||||
|
||||
const { mutate, isSuccess, status } = useUpdateLesson();
|
||||
const { objectToEdit, setObjectToEdit } = useObjectToEdit();
|
||||
const { objectToEdit } = useObjectToEdit();
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
|
@ -43,6 +43,7 @@ const ModalForm: React.FC = () => {
|
|||
getInitialValues={getInitialValues(objectToEdit)}
|
||||
getValidationSchema={getValidationSchema}
|
||||
isAddModal={false}
|
||||
width="40vw"
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import * as Yup from "yup";
|
||||
|
||||
export const getInitialValues = (objectToEdit: any): any => {
|
||||
console.log(objectToEdit,"objectToEdit");
|
||||
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
name: objectToEdit?.name ?? "",
|
||||
name: objectToEdit?.name ?? null,
|
||||
unit_id: objectToEdit?.term ?? null,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { useGetAllGrade } from "../../api/grade";
|
|||
import { useGetAllCurriculum } from "../../api/curriculum";
|
||||
import { useGetAllSubject } from "../../api/subject";
|
||||
|
||||
const Table = lazy(() => import("./Table"));
|
||||
const Table = lazy(() => import("./DrapableTable"));
|
||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||
const DeleteModelsForm = lazy(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
canShowLesson,
|
||||
} from "../../utils/hasAbilityFn";
|
||||
import ActionButtons from "../../Components/Table/ActionButtons";
|
||||
import { DragHandleLesson } from "./DrapableTable";
|
||||
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
|
@ -37,6 +38,7 @@ export const useColumns = () => {
|
|||
const [t] = useTranslation();
|
||||
|
||||
const columns: TableColumnsType<Lesson> = [
|
||||
{ key: "sort", align: "center", width: 80, render: () => <DragHandleLesson /> },
|
||||
{
|
||||
title: t("columns.id"),
|
||||
dataIndex: "id",
|
||||
|
|
|
|||
33
src/Pages/studentPackage/Model/AddModel.tsx
Normal file
33
src/Pages/studentPackage/Model/AddModel.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import React from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import ModelForm from "./ModelForm";
|
||||
import { useAddStudentPackage } from "../../../api/StudentPackage";
|
||||
|
||||
const AddModel: React.FC = () => {
|
||||
const { mutate, status } = useAddStudentPackage();
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
mutate({
|
||||
...values,
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.STUDENT_PACKAGE_ADD}
|
||||
modelTitle="StudentPackage"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues({})}
|
||||
getValidationSchema={getValidationSchema}
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddModel;
|
||||
38
src/Pages/studentPackage/Model/EditModel.tsx
Normal file
38
src/Pages/studentPackage/Model/EditModel.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import React from "react";
|
||||
import { getInitialValues, getValidationSchema } from "./formUtil";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import LayoutModel from "../../../Layout/Dashboard/LayoutModel";
|
||||
import ModelForm from "./ModelForm";
|
||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||
import { useUpdateStudentPackage } from "../../../api/StudentPackage";
|
||||
import { handelImageState } from "../../../utils/DataToSendImageState";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status } = useUpdateStudentPackage();
|
||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
const Data_to_send = { ...values };
|
||||
const handelImage = handelImageState(Data_to_send, "icon");
|
||||
mutate(handelImage);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.STUDENT_PACKAGE_EDIT}
|
||||
modelTitle="StudentPackage"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValues(objectToEdit)}
|
||||
getValidationSchema={getValidationSchema}
|
||||
isAddModal={false}
|
||||
>
|
||||
<ModelForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditModel;
|
||||
71
src/Pages/studentPackage/Model/ModelForm.tsx
Normal file
71
src/Pages/studentPackage/Model/ModelForm.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import { Col, Row } from "reactstrap";
|
||||
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||
import { useGetAllPackage } from "../../../api/package";
|
||||
import { useValidationValidationParamState } from "../../../Components/ValidationField/state/ValidationValidationParamState";
|
||||
import { useGetAllStudent } from "../../../api/student";
|
||||
|
||||
const Form = () => {
|
||||
|
||||
const { ValidationParamState } = useValidationValidationParamState();
|
||||
const {
|
||||
PackageName, PackageCurrentPage,
|
||||
StudentName, StudentCurrentPage,
|
||||
} = ValidationParamState;
|
||||
|
||||
|
||||
/// Package_id
|
||||
const { data: Package, isLoading: isLoadingPackage } = useGetAllPackage({
|
||||
name: PackageName,
|
||||
page: PackageCurrentPage
|
||||
});
|
||||
const PackageOption = Package?.data ?? []
|
||||
const canChangePackagePage = !!Package?.links?.next;
|
||||
const PackagePage = Package?.meta?.currentPage;
|
||||
|
||||
|
||||
/// Student_id
|
||||
const { data: Student, isLoading: isLoadingStudent } = useGetAllStudent({
|
||||
name: StudentName,
|
||||
page: StudentCurrentPage
|
||||
});
|
||||
const StudentOption = Student?.data ?? []
|
||||
const canChangeStudentPage = !!Student?.links?.next;
|
||||
const StudentPage = Student?.meta?.currentPage;
|
||||
|
||||
return (
|
||||
<Row className="w-100">
|
||||
<Col>
|
||||
<ValidationField
|
||||
searchBy="StudentName"
|
||||
name="student_id"
|
||||
label="Student"
|
||||
type="Search"
|
||||
option={StudentOption}
|
||||
isLoading={isLoadingStudent}
|
||||
canChangePage={canChangeStudentPage}
|
||||
PageName={"StudentCurrentPage"}
|
||||
page={StudentPage}
|
||||
|
||||
/>
|
||||
<ValidationField
|
||||
searchBy="PackageName"
|
||||
name="package_id"
|
||||
label="Package"
|
||||
type="Search"
|
||||
option={PackageOption}
|
||||
isLoading={isLoadingPackage}
|
||||
canChangePage={canChangePackagePage}
|
||||
PageName={"PackageCurrentPage"}
|
||||
page={PackagePage}
|
||||
|
||||
/>
|
||||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="activation_date" type="Date" />
|
||||
<ValidationField name="expiration_date" type="Date" />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export default Form;
|
||||
23
src/Pages/studentPackage/Model/formUtil.ts
Normal file
23
src/Pages/studentPackage/Model/formUtil.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import * as Yup from "yup";
|
||||
import { StudentPackage, StudentPackageInitialValues } from "../../../types/studentPackage";
|
||||
import { formateDateInitialValue } from "../../../utils/formateDateInitialValue";
|
||||
|
||||
export const getInitialValues = (
|
||||
objectToEdit: Partial<StudentPackage>,
|
||||
): StudentPackageInitialValues => {
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
package_id: objectToEdit?.package?.id ?? null,
|
||||
student_id: objectToEdit?.student?.user_id ?? null,
|
||||
activation_date: formateDateInitialValue(objectToEdit?.activation_date) ,
|
||||
expiration_date: formateDateInitialValue(objectToEdit?.expiration_date) ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = () => {
|
||||
// validate input
|
||||
return Yup.object().shape({
|
||||
name: Yup.string().required("validation.required"),
|
||||
});
|
||||
};
|
||||
39
src/Pages/studentPackage/Page.tsx
Normal file
39
src/Pages/studentPackage/Page.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { lazy, Suspense } from "react";
|
||||
import { Spin } from "antd";
|
||||
import useSetPageTitle from "../../Hooks/useSetPageTitle";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useDeleteStudentPackage } from "../../api/StudentPackage";
|
||||
|
||||
const Table = lazy(() => import("./Table"));
|
||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||
const DeleteModalForm = lazy(
|
||||
() => import("../../Layout/Dashboard/DeleteModels"),
|
||||
);
|
||||
|
||||
const TableHeader = () => {
|
||||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteStudentPackage();
|
||||
|
||||
useSetPageTitle(t(`page_header.studentPackage`));
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<header>
|
||||
<h6>{t("models.StudentPackage")}</h6>
|
||||
</header>
|
||||
<Table />
|
||||
<AddModalForm />
|
||||
<EditModalForm />
|
||||
<DeleteModalForm
|
||||
deleteMutation={deleteMutation}
|
||||
ModelEnum={ModalEnum?.STUDENT_PACKAGE_DELETE}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableHeader;
|
||||
12
src/Pages/studentPackage/Table.tsx
Normal file
12
src/Pages/studentPackage/Table.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { useColumns } from "./useTableColumns";
|
||||
import React from "react";
|
||||
import DataTable from "../../Layout/Dashboard/Table/DataTable";
|
||||
import { useGetAllStudentPackage } from "../../api/StudentPackage";
|
||||
|
||||
const App: React.FC = () => {
|
||||
const response = useGetAllStudentPackage({ pagination: true });
|
||||
|
||||
return <DataTable response={response} useColumns={useColumns} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
87
src/Pages/studentPackage/useTableColumns.tsx
Normal file
87
src/Pages/studentPackage/useTableColumns.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import { TableColumnsType } from "antd";
|
||||
import { StudentPackage } from "../../types/studentPackage";
|
||||
import { FaPlus } from "react-icons/fa";
|
||||
import useModalHandler from "../../utils/useModalHandler";
|
||||
import { ModalEnum } from "../../enums/Model";
|
||||
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ABILITIES_ENUM } from "../../enums/abilities";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
canAddStudentPackage,
|
||||
canDeleteStudentPackage,
|
||||
canEditStudentPackage,
|
||||
canShowStudentPackage,
|
||||
} from "../../utils/hasAbilityFn";
|
||||
import ActionButtons from "../../Components/Table/ActionButtons";
|
||||
import ColumnsImage from "../../Components/Columns/ColumnsImage";
|
||||
|
||||
export const useColumns = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handelShow = (record: StudentPackage) => {
|
||||
navigate(`${record?.id}`);
|
||||
};
|
||||
|
||||
const handelDelete = (data: StudentPackage) => {
|
||||
setObjectToEdit(data);
|
||||
handel_open_model(ModalEnum?.STUDENT_PACKAGE_DELETE);
|
||||
};
|
||||
|
||||
const handleEdit = (record: StudentPackage) => {
|
||||
setObjectToEdit(record);
|
||||
handel_open_model(ModalEnum?.STUDENT_PACKAGE_EDIT);
|
||||
};
|
||||
const [t] = useTranslation();
|
||||
|
||||
const columns: TableColumnsType<StudentPackage> = [
|
||||
{
|
||||
title: t("columns.id"),
|
||||
dataIndex: "id",
|
||||
key: "id",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.id,
|
||||
},
|
||||
{
|
||||
title: `${t("columns.name")}`,
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
align: "center",
|
||||
render: (_text, record) => record?.name,
|
||||
},
|
||||
{
|
||||
title: canAddStudentPackage ? (
|
||||
<button
|
||||
onClick={() => handel_open_model(ModalEnum?.STUDENT_PACKAGE_ADD)}
|
||||
className="add_button"
|
||||
>
|
||||
{t("practical.add")} {t("models.StudentPackage")} <FaPlus />
|
||||
</button>
|
||||
) : (
|
||||
""
|
||||
),
|
||||
|
||||
key: "actions",
|
||||
align: "end",
|
||||
width: "25vw",
|
||||
render: (_text, record, index) => {
|
||||
return (
|
||||
<ActionButtons
|
||||
canDelete={canDeleteStudentPackage}
|
||||
canEdit={canEditStudentPackage}
|
||||
canShow={canShowStudentPackage}
|
||||
index={index}
|
||||
onDelete={() => handelDelete(record)}
|
||||
onEdit={() => handleEdit(record)}
|
||||
onShow={() => handelShow(record)}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return columns;
|
||||
};
|
||||
|
|
@ -12,6 +12,8 @@ const Package = React.lazy(() => import("./Pages/Package/Page"));
|
|||
const Curriculum = React.lazy(() => import("./Pages/Curriculum/Page"));
|
||||
const PackageItemPage = React.lazy(() => import("./Pages/Package/PackageItem/Page"));
|
||||
const ReSeller = React.lazy(() => import("./Pages/ReSeller/Page"));
|
||||
const StudentPackage = React.lazy(() => import("./Pages/studentPackage/Page"));
|
||||
const Student = React.lazy(() => import("./Pages/Student/Page"));
|
||||
|
||||
const Unit = React.lazy(() => import("./Pages/Unit/Page"));
|
||||
const Lesson = React.lazy(() => import("./Pages/lesson/Page"));
|
||||
|
|
@ -28,6 +30,8 @@ const EditPackageItemPage = React.lazy(() => import("./Pages/Package/PackageItem
|
|||
import { hasAbility } from "./utils/hasAbility";
|
||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "./enums/abilities";
|
||||
import { ParamsEnum } from "./enums/params";
|
||||
import { BsPeople } from "react-icons/bs";
|
||||
import { UserTypeEnum } from "./enums/UserType";
|
||||
|
||||
export const menuItems: TMenuItem[] = [
|
||||
{
|
||||
|
|
@ -39,6 +43,7 @@ export const menuItems: TMenuItem[] = [
|
|||
abilities: ABILITIES_ENUM?.PASS,
|
||||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
type:UserTypeEnum?.PASS
|
||||
|
||||
},
|
||||
{
|
||||
|
|
@ -91,6 +96,28 @@ export const menuItems: TMenuItem[] = [
|
|||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
},
|
||||
|
||||
{
|
||||
header: "page_header.student",
|
||||
element: <Student />,
|
||||
icon: <FaSellcast />,
|
||||
text: "sidebar.student",
|
||||
path: `/${ABILITIES_ENUM?.STUDENT}`,
|
||||
abilities: ABILITIES_ENUM?.STUDENT,
|
||||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
},
|
||||
{
|
||||
header: "page_header.studentPackage",
|
||||
element: <StudentPackage />,
|
||||
icon: <BsPeople />,
|
||||
text: "sidebar.studentPackage",
|
||||
path: `/${ABILITIES_ENUM?.STUDENT_PACKAGE}`,
|
||||
abilities: ABILITIES_ENUM?.STUDENT_PACKAGE,
|
||||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
type:UserTypeEnum.RE_SELLER
|
||||
},
|
||||
];
|
||||
|
||||
export const CrudRoute: TCrudRoute[] = [
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
.exercise_add_main {
|
||||
background: var(--bg);
|
||||
padding: 2vw;
|
||||
}
|
||||
};
|
||||
.exercise_add_buttons {
|
||||
display: flex;
|
||||
gap: 2%;
|
||||
|
|
@ -59,6 +59,7 @@
|
|||
|
||||
.add_new_button {
|
||||
margin-bottom: 0;
|
||||
color: var(--primary) !important;
|
||||
}
|
||||
}
|
||||
.tags {
|
||||
|
|
@ -125,3 +126,11 @@
|
|||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
|
||||
.add_new_button{
|
||||
margin-bottom: 20px;
|
||||
svg{
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
21
src/api/StudentPackage.ts
Normal file
21
src/api/StudentPackage.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import useAddMutation from "./helper/useAddMutation";
|
||||
import useDeleteMutation from "./helper/useDeleteMutation";
|
||||
import useGetQuery from "./helper/useGetQuery";
|
||||
import useUpdateMutation from "./helper/useUpdateMutation";
|
||||
|
||||
const API = {
|
||||
GET: "/resellers/studentPackage",
|
||||
ADD: "/resellers/studentPackage",
|
||||
DELETE: "/resellers/studentPackage",
|
||||
UPDATE: "/resellers/studentPackage",
|
||||
};
|
||||
|
||||
const KEY = "StudentPackage";
|
||||
|
||||
export const useGetAllStudentPackage = (params?: any, options?: any) =>
|
||||
useGetQuery(KEY, API.GET, params, options);
|
||||
export const useAddStudentPackage = () => useAddMutation(KEY, API.ADD);
|
||||
export const useUpdateStudentPackage = (params?: any) =>
|
||||
useUpdateMutation(KEY, API.GET);
|
||||
export const useDeleteStudentPackage = (params?: any) =>
|
||||
useDeleteMutation(KEY, API.DELETE);
|
||||
|
|
@ -8,6 +8,8 @@ function useAddMutation(
|
|||
key: string,
|
||||
url: string,
|
||||
toast: boolean = true,
|
||||
params: any = {},
|
||||
options: any = {},
|
||||
): UseMutationResult<AxiosResponse, unknown, any, unknown> {
|
||||
const axios = useAxios();
|
||||
return useMutation<AxiosResponse, unknown, any, unknown>(
|
||||
|
|
@ -20,9 +22,12 @@ function useAddMutation(
|
|||
["X-Custom-Message"]: toast,
|
||||
[HEADER_KEY]: key,
|
||||
},
|
||||
|
||||
});
|
||||
return data;
|
||||
},
|
||||
options,
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const API = {
|
|||
ADD: "/lesson",
|
||||
DELETE: "/lesson",
|
||||
UPDATE: "/lesson",
|
||||
ORDER: "/lesson/order",
|
||||
};
|
||||
|
||||
const KEY = "lesson";
|
||||
|
|
@ -19,3 +20,5 @@ export const useUpdateLesson = (params?: any) =>
|
|||
useUpdateMutation(KEY, API.GET);
|
||||
export const useDeleteLesson = (params?: any) =>
|
||||
useDeleteMutation(KEY, API.DELETE);
|
||||
|
||||
export const useUpdateLessonOrder = (params?: any) => useAddMutation("karim", API.ORDER);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const API = {
|
|||
ADD: "/unit",
|
||||
DELETE: "/unit",
|
||||
UPDATE: "/unit",
|
||||
ORDER: "/unit/order",
|
||||
};
|
||||
|
||||
const KEY = "unit";
|
||||
|
|
@ -15,5 +16,6 @@ export const useGetAllUnit = (params?: any, options?: any) =>
|
|||
useGetQuery(KEY, API.GET, params, options);
|
||||
export const useAddUnit = () => useAddMutation(KEY, API.ADD);
|
||||
export const useUpdateUnit = (params?: any) => useUpdateMutation(KEY, API.GET);
|
||||
export const useUpdateUnitOrder = (params?: any,option?: any,) => useAddMutation("karim", API.ORDER,true,params,option);
|
||||
export const useDeleteUnit = (params?: any) =>
|
||||
useDeleteMutation(KEY, API.DELETE);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export enum DateEnum {
|
||||
FORMATE = "YYYY-MM-DD",
|
||||
SEND_DATE_FORMAT = "YYYY-MM-DD",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,4 +163,9 @@ export enum ModalEnum {
|
|||
RE_SELLER_EDIT = "ReSeller.edit",
|
||||
RE_SELLER_ADD = "ReSeller.add",
|
||||
RE_SELLER_DELETE = "ReSeller.delete",
|
||||
|
||||
/// studentPackage
|
||||
STUDENT_PACKAGE_EDIT = "studentPackage.edit",
|
||||
STUDENT_PACKAGE_ADD = "studentPackage.add",
|
||||
STUDENT_PACKAGE_DELETE = "studentPackage.delete",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export enum UserTypeEnum {
|
||||
ADMIN = "ADMIN",
|
||||
RE_SELLER = "RE_SELLER",
|
||||
ADMIN = "admin",
|
||||
RE_SELLER = "reseller",
|
||||
PASS="pass"
|
||||
}
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ export enum ABILITIES_ENUM {
|
|||
EARLY_DEPARTURE = "earlyDeparture",
|
||||
EDUCATION_CLASS = "eduClass",
|
||||
GRADE = "grade",
|
||||
Package = "package",
|
||||
Package = "packages",
|
||||
HOMEWORK_ATTACHMENT = "homeworkAttachment",
|
||||
HOMEWORK = "homework",
|
||||
LATE_ARRIVAL = "lateArrival",
|
||||
|
|
@ -44,7 +44,8 @@ export enum ABILITIES_ENUM {
|
|||
ADMIN = "admin",
|
||||
CURRICULUM = "curriculum",
|
||||
PACKAGE_ITEM = "package_item",
|
||||
RE_SELLER = "ReSeller"
|
||||
RE_SELLER = "ReSeller",
|
||||
STUDENT_PACKAGE='studentPackage'
|
||||
////
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -279,7 +279,8 @@
|
|||
"package":"حزمة",
|
||||
"package_details":"تفاصيل الحزمة",
|
||||
"add_package":"اضافة حزمة",
|
||||
"ReSeller":"بائع"
|
||||
"ReSeller":"بائع",
|
||||
"StudentPackage":"حزمة الطالب "
|
||||
},
|
||||
"education_class_actions": {
|
||||
"Student_Records": "سجلات الطلاب",
|
||||
|
|
@ -694,7 +695,9 @@
|
|||
"grade": "الدرجات",
|
||||
"curriculum": "مقرر",
|
||||
"package":"حزمة",
|
||||
"reSeller":"البائع"
|
||||
"reSeller":"البائع",
|
||||
"studentPackage":"حزمة الطالب ",
|
||||
"student":"الطالب"
|
||||
},
|
||||
"message": {
|
||||
"some_thing_went_wrong": "حدث خطأ ما",
|
||||
|
|
@ -719,7 +722,10 @@
|
|||
"lesson": "الدرس",
|
||||
"curriculum": "مقرر",
|
||||
"subject": "المادة",
|
||||
"question": "السؤال"
|
||||
"question": "السؤال",
|
||||
"studentPackage":"حزمة الطالب "
|
||||
|
||||
|
||||
},
|
||||
"page_header": {
|
||||
"dashboard": "لوحة القيادة / الصفحة الرئيسية",
|
||||
|
|
@ -752,6 +758,8 @@
|
|||
"grade": "لوحة القيادة /الدرجات ",
|
||||
"curriculum": "لوحة القيادة / تعديل مقرر ",
|
||||
"package":"لوحة القيادة / الحزم ",
|
||||
"ReSeller":"لوحة القيادة / البائع "
|
||||
"reSeller":"لوحة القيادة / البائع ",
|
||||
"studentPackage":"لوحة القيادة / حزمة الطالب ",
|
||||
"student":"لوحة القيادة / الطالب "
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { ReactElement, LazyExoticComponent, ReactNode } from "react";
|
|||
import { Mark_State, Payment_type, term_type } from "./Item";
|
||||
import { ABILITIES_ENUM, ABILITIES_VALUES_ENUM } from "../enums/abilities";
|
||||
import { UserTypeEnum } from "../enums/UserType";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export type ChildrenType = {
|
||||
children: ReactNode;
|
||||
|
|
@ -39,7 +40,7 @@ export type TCrudRoute = {
|
|||
element: ReactElement | LazyExoticComponent<any>;
|
||||
abilities: ABILITIES_ENUM;
|
||||
abilities_value: ABILITIES_VALUES_ENUM;
|
||||
type?:ABILITIES_ENUM
|
||||
type?:UserTypeEnum
|
||||
prevPath: number;
|
||||
};
|
||||
|
||||
|
|
@ -408,3 +409,4 @@ export interface showAdmin {
|
|||
}
|
||||
|
||||
export type Nullable<T> = { [K in keyof T]: T[K] | null };
|
||||
export type DateType = string | dayjs.Dayjs | null | undefined;
|
||||
|
|
|
|||
34
src/types/Student.ts
Normal file
34
src/types/Student.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { DateType, Nullable } from "./App";
|
||||
|
||||
// Define the Teacher interface
|
||||
|
||||
|
||||
|
||||
export interface Student {
|
||||
first_name: string; // The first name of the user
|
||||
last_name: string; // The last name of the user
|
||||
city: string | null; // The city of the user, can be null
|
||||
sex: string; // The sex of the user, using a union type for possible values
|
||||
image: string | null; // The URL of the user's image, can be null
|
||||
address: string | null; // The address of the user, can be null
|
||||
card: string | null; // The card information, can be null
|
||||
birthday: DateType; // The birthday of the user, can be null
|
||||
grade_id: number | string; // The ID of the user's grade
|
||||
user_id: number; // The unique ID of the user
|
||||
}
|
||||
|
||||
export interface InitialValues {
|
||||
id: number;
|
||||
first_name: string; // The first name of the user
|
||||
last_name: string; // The last name of the user
|
||||
city: string | null; // The city of the user, can be null
|
||||
sex: string; // The sex of the user, using a union type for possible values
|
||||
image: string | null; // The URL of the user's image, can be null
|
||||
address: string | null; // The address of the user, can be null
|
||||
card: string | null; // The card information, can be null
|
||||
birthday: DateType; // The birthday of the user, can be null
|
||||
grade_id: number | string; // The ID of the user's grade
|
||||
user_id: number; // The unique ID of the user
|
||||
}
|
||||
|
||||
export type StudentInitialValues = Partial<Nullable<InitialValues>>;
|
||||
54
src/types/studentPackage.ts
Normal file
54
src/types/studentPackage.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { TermEnum } from "../enums/Term";
|
||||
import { DateType, Nullable } from "./App";
|
||||
|
||||
// Define the type for the object
|
||||
|
||||
interface StudentPackageStudent {
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
city: string | null;
|
||||
sex: string | null;
|
||||
image: string | null;
|
||||
address: string | null;
|
||||
card: string | null;
|
||||
birthday: string | null;
|
||||
grade_id: number;
|
||||
user_id: number;
|
||||
}
|
||||
|
||||
interface StudentPackagePackageConfiguration {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface StudentPackagePackage {
|
||||
id: number;
|
||||
name: string;
|
||||
configuration: StudentPackagePackageConfiguration[];
|
||||
price: number;
|
||||
grade_id: number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface StudentPackage {
|
||||
id: number;
|
||||
activation_date: string;
|
||||
expiration_date: string;
|
||||
student: StudentPackageStudent;
|
||||
package: StudentPackagePackage;
|
||||
}
|
||||
|
||||
export interface InitialValues {
|
||||
|
||||
id: number;
|
||||
activation_date: DateType;
|
||||
expiration_date: DateType;
|
||||
student: StudentPackageStudent;
|
||||
package: StudentPackagePackage;
|
||||
|
||||
student_id: number | string;
|
||||
package_id: number | string;
|
||||
}
|
||||
|
||||
export type StudentPackageInitialValues = Partial<Nullable<InitialValues>>;
|
||||
28
src/utils/RoleByType.ts
Normal file
28
src/utils/RoleByType.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { USER_KEY } from "../config/AppKey";
|
||||
import { UserTypeEnum } from "../enums/UserType";
|
||||
import { getLocalStorage } from "./LocalStorage";
|
||||
|
||||
export const RoleByType = (item: { type?: string }):boolean=>{
|
||||
const type = item?.type ?? UserTypeEnum.ADMIN;
|
||||
const LocalType = getLocalStorage(USER_KEY)?.type ?? undefined ;
|
||||
const isAdmin = LocalType === UserTypeEnum.ADMIN ;
|
||||
const isReSeller = LocalType === UserTypeEnum.RE_SELLER;
|
||||
const isAdminRoute = type === UserTypeEnum.ADMIN ;
|
||||
const isReSellerRoute = type === UserTypeEnum.RE_SELLER;
|
||||
console.log(LocalType);
|
||||
|
||||
if(!LocalType){
|
||||
return false
|
||||
}
|
||||
if(type === UserTypeEnum.PASS) { return true } ;
|
||||
|
||||
if(isAdmin && isReSellerRoute ){
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(isReSeller && !isReSellerRoute ){
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
10
src/utils/formateDateInitialValue.ts
Normal file
10
src/utils/formateDateInitialValue.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import dayjs from "dayjs";
|
||||
import { DateType } from "../types/App";
|
||||
import { DateEnum } from "../enums/Date";
|
||||
|
||||
export const formateDateInitialValue = (date: DateType) => {
|
||||
if (date) {
|
||||
return dayjs(date, DateEnum.SEND_DATE_FORMAT);
|
||||
}
|
||||
return dayjs(Date());
|
||||
};
|
||||
|
|
@ -604,3 +604,24 @@ export const canShowReSeller = hasAbility(
|
|||
ABILITIES_ENUM.RE_SELLER,
|
||||
ABILITIES_VALUES_ENUM.SHOW,
|
||||
);
|
||||
|
||||
|
||||
/// StudentPackage
|
||||
|
||||
export const canAddStudentPackage = hasAbility(
|
||||
ABILITIES_ENUM.RE_SELLER,
|
||||
ABILITIES_VALUES_ENUM.STORE,
|
||||
);
|
||||
|
||||
export const canEditStudentPackage = hasAbility(
|
||||
ABILITIES_ENUM.RE_SELLER,
|
||||
ABILITIES_VALUES_ENUM.UPDATE,
|
||||
);
|
||||
export const canDeleteStudentPackage = hasAbility(
|
||||
ABILITIES_ENUM.RE_SELLER,
|
||||
ABILITIES_VALUES_ENUM.DELETE,
|
||||
);
|
||||
export const canShowStudentPackage = hasAbility(
|
||||
ABILITIES_ENUM.RE_SELLER,
|
||||
ABILITIES_VALUES_ENUM.SHOW,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { create } from "zustand";
|
||||
import { ABILITIES_KEY, TOKEN_KEY, USER_KEY } from "../config/AppKey";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { RoleByType } from "../utils/RoleByType";
|
||||
import { getLocalStorage } from "../utils/LocalStorage";
|
||||
interface AuthStore {
|
||||
token: string | null | undefined;
|
||||
abilities: any;
|
||||
isAuthenticated: boolean;
|
||||
|
||||
login: (Data: any) => Promise<void>;
|
||||
logout: () => Promise<void>;
|
||||
}
|
||||
|
|
@ -14,9 +13,11 @@ interface AuthStore {
|
|||
const useAuthState = create<AuthStore>((set) => {
|
||||
const storedToken = localStorage.getItem(TOKEN_KEY);
|
||||
const storedAbilities = localStorage.getItem(ABILITIES_KEY);
|
||||
const storedType = getLocalStorage(USER_KEY) ;
|
||||
console.log(RoleByType(storedType));
|
||||
|
||||
return {
|
||||
isAuthenticated: true,
|
||||
isAuthenticated: !!storedToken,
|
||||
token: storedToken,
|
||||
abilities: storedAbilities,
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user