This commit is contained in:
karimaldeen 2024-09-23 15:12:24 +03:00
parent 999573fa0c
commit d603736a16
22 changed files with 4372 additions and 93 deletions

View File

@ -8,16 +8,10 @@
<link rel="icon" type="image/png" sizes="32x32" href="/App/Logo.svg" />
<link rel="icon" type="image/png" sizes="16x16" href="/App/Logo.svg" />
<link rel="manifest" href="/site.webmanifest" />
<link
href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.css"
rel="stylesheet"
/>
<meta
name="description"
content="social networking platform with automated content moderation and context-based authentication system"
/>
<script type="module" src="/src/index.tsx"></script>
<title>NERD DASHBOARD</title>

4104
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,13 +16,16 @@
"dayjs": "^1.11.11",
"formik": "^2.4.6",
"i18next": "^23.11.5",
"install": "^0.13.0",
"katex": "^0.16.11",
"lottie-react": "^2.4.0",
"mathjax": "^3.2.2",
"mathjax-full": "^3.2.2",
"mathjs": "^13.1.1",
"mathml-to-latex": "^1.4.1",
"mathml2latex": "^1.1.3",
"mml2tex": "^0.0.2",
"npm": "^10.8.3",
"react": "^18.3.1",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.3.1",
@ -32,6 +35,9 @@
"react-katex": "^3.0.1",
"react-latex": "^2.0.0",
"react-latex-next": "^3.0.0",
"react-mathjax": "^1.0.1",
"react-mathjax-preview": "^2.2.6",
"react-mathjax2": "^0.0.2",
"react-query": "^3.39.3",
"react-router-dom": "^6.23.1",
"react-toastify": "^9.1.3",

View File

@ -1,14 +1,22 @@
import React from 'react';
import { BlockMath } from 'react-katex';
import 'katex/dist/katex.min.css';
import { BlockMath } from 'react-katex';
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
const LatexPreview = ({Latex}:{Latex:string}) => {
const LatexPreview = ({ latex }: { latex: string }) => {
console.log(latex);
return(
<BlockMath math={Latex} />
)
const sanitizedLatex = latex.replace(/\\_/g, '_');
return (
<div>
<BlockMath>
{sanitizedLatex}
</BlockMath>
</div>
);
};
export default LatexPreview;
export default LatexPreview;

View File

@ -100,10 +100,12 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
<div className='showPreviewInput'>
{Preview?.map((item: any, index: number) => {
if (item?.isLatex) {
console.log(item?.text);
return (
<div dir='ltr' key={index} onClick={() => handleEditModal(item)} className='LatexPreview'>
<LatexPreview Latex={item?.text} />
</div>
<span dir='ltr' key={index} onClick={() => handleEditModal(item)} className='LatexPreview'>
<LatexPreview latex={item?.text} />
</span>
);
}
return <div key={index}>{item?.text}</div>;

View File

@ -0,0 +1,25 @@
import React from 'react'
import DataTable from '../../../../Layout/Dashboard/Table/DataTable'
import { useColumns } from './useTableColumns'
import { useFormikContext } from 'formik'
const FormTable = ({response}:{response:any}) => {
const {values} = useFormikContext<any>()
return (
<div>
<DataTable
response={response}
useColumns={useColumns}
dataSource={values}
pagination={false}
loading={false}
/>
</div>
)
}
export default FormTable

View File

@ -1,25 +1,73 @@
import React from "react";
import React, { useEffect, useMemo } from "react";
import DataTable from "../../../../Layout/Dashboard/Table/DataTable";
import { useColumns } from "./useTableColumns";
import { useFilterState } from "../../../../Components/Utils/Filter/FilterState";
import { useFilterStateState } from "../../../../zustand/Filter";
import { useGetAllRole } from "../../../../api/role";
import { useGetAllTag } from "../../../../api/tags";
const App: React.FC = () => {
import { useGetAllPermissions } from "../../../../api/Permissions";
import { useParams } from "react-router-dom";
import { ParamsEnum } from "../../../../enums/params";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { Form, Formik } from "formik";
import FormTable from "./FormTable";
const App: React.FC = () => {
const { role_id } = useParams<ParamsEnum>();
const { filterState } = useFilterState();
const { Filter } = useFilterStateState();
const name = Filter?.name ;
const sort_by = Filter?.sort_by ;
const name = Filter?.name;
const sort_by = Filter?.sort_by;
const response = useGetAllTag({
const Data = [
"absence::delete",
"absence::index",
"absence::show",
"absence::store",
"absence::update",
"admin::delete",
"admin::index",
"admin::show",
"admin::update",
];
/// time complexity O(n) -_-
const newArray: Array<{ name: any; [key: string]: boolean }> = [];
const hashMap = new Map<string, number>();
for (let i = 0; i < Data.length; i++) {
const [permission, value] = Data[i].split("::");
const existingIndex = hashMap.get(permission);
if (existingIndex !== undefined) {
newArray[existingIndex][value] = true;
if(newArray[existingIndex]["index"] && newArray[existingIndex]["show"] && newArray[existingIndex]["store"] && newArray[existingIndex]["update"] && newArray[existingIndex]["delete"]){
newArray[existingIndex]["ALL"] = true;
}
} else {
const newObject = { name: permission, [value]: true } as any;
newArray.push(newObject);
hashMap.set(permission, newArray.length - 1);
}
}
console.log(newArray);
const response = useGetAllPermissions({
pagination: true,
role_id,
name,
sort_by,
...filterState,
});
return <DataTable response={response} useColumns={useColumns} />;
return (
<Formik initialValues={newArray} onSubmit={()=>{}}>
<Form>
<FormTable response={response} />
<button>submit</button>
</Form>
</Formik>
);
};
export default App;

View File

@ -1,33 +1,49 @@
import { TableColumnsType } from "antd";
import { Checkbox, TableColumnsType } from "antd";
import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { useModalState } from "../../../../zustand/Modal";
import { useTranslation } from "react-i18next";
import { Role } from "../../../../types/App";
import { ModalEnum } from "../../../../enums/Model";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { CheckboxProps } from "antd/lib";
import { ABILITIES_VALUES_ENUM } from "../../../../enums/abilities";
import { useFormikContext } from "formik";
export const useColumns = () => {
const [t] = useTranslation();
const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.ROLE_EDIT);
const {values,setFieldValue} = useFormikContext<any>()
console.log(values,"values");
const onChange: CheckboxProps['onChange'] = (e) => {
console.log(`checked = ${e.target.checked}`);
};
const columns: TableColumnsType<Role> = [
// {
// title: <ValidationField name="empty" type="Checkbox"/>,
// dataIndex: "id",
// key: "id",
// align: "center",
// render: (_text) => {
// return (
// <ValidationField name="empty" type="Checkbox"/>
// );
// },
// },
const onChangeAll: CheckboxProps['onChange'] = (e) => {
console.log(`checked = ${e.target.checked}`);
};
const CheckBoxFieldALL = ({record}:{record:any})=>{
const isChecked = record?.ALL ;
return <Checkbox onChange={onChangeAll} checked={isChecked} />;
}
const CheckBoxField = ({record,type}:{record:any,type:string})=>{
const name = record?.name ;
console.log(record,"record");
console.log(type,"type");
const isChecked = record?.[type] ;
return <Checkbox onChange={onChange} checked={isChecked} />;
}
const columns: TableColumnsType<any> = [
{
title: t("columns.units"),
dataIndex: "name",
@ -39,9 +55,13 @@ export const useColumns = () => {
dataIndex: "id",
key: "id",
align: "center",
render: (_text) => {
render: (_text,record,index) => {
console.log(record);
console.log(index);
return (
<ValidationField name="empty" type="Checkbox"/>
<CheckBoxField record={record} type={ABILITIES_VALUES_ENUM.INDEX} />
);
},
},
@ -50,9 +70,9 @@ export const useColumns = () => {
dataIndex: "id",
key: "id",
align: "center",
render: (_text) => {
render: (_text,record) => {
return (
<ValidationField name="empty" type="Checkbox"/>
<CheckBoxField record={record} type={ABILITIES_VALUES_ENUM.SHOW} />
);
},
},
@ -61,9 +81,9 @@ export const useColumns = () => {
dataIndex: "id",
key: "id",
align: "center",
render: (_text) => {
render: (_text,record) => {
return (
<ValidationField name="empty" type="Checkbox"/>
<CheckBoxField record={record} type={ABILITIES_VALUES_ENUM.STORE} />
);
},
},
@ -72,23 +92,36 @@ export const useColumns = () => {
dataIndex: "id",
key: "id",
align: "center",
render: (_text) => {
render: (_text,record) => {
return (
<ValidationField name="empty" type="Checkbox"/>
<CheckBoxField record={record} type={ABILITIES_VALUES_ENUM.DELETE} />
);
},
},
{
title: t("columns.show"),
dataIndex: "id",
key: "id",
align: "center",
render: (_text,record) => {
return (
<CheckBoxField record={record} type={ABILITIES_VALUES_ENUM.UPDATE} />
);
},
},
{
title: t("columns.allow_everyone"),
dataIndex: "id",
key: "id",
align: "center",
render: (_text) => {
render: (_text,record) => {
return (
<ValidationField name="empty" type="Checkbox"/>
<CheckBoxFieldALL record={record} />
);
},
},
];
return columns;

View File

@ -11,7 +11,9 @@ const App: React.FC = () => {
const { Filter } = useFilterStateState();
const name = Filter?.name ;
const sort_by = Filter?.sort_by ;
const Data = [
{name:"name",id:1}
]
const response = useGetAllRole({
pagination: true,
name,
@ -19,7 +21,7 @@ const App: React.FC = () => {
...filterState,
});
return <DataTable response={response} useColumns={useColumns} />;
return <DataTable response={response} useColumns={useColumns} dataSource={Data} />;
};
export default App;

View File

@ -3,7 +3,7 @@ import { ModalEnum } from "../../../enums/Model";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useModalState } from "../../../zustand/Modal";
import { useTranslation } from "react-i18next";
import { canDeleteRole,canEditRole } from "../../../utils/hasAbilityFn";
import { canDeleteRole,canEditRole, canShowRole } from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons";
import { Role } from "../../../types/App";
import { useNavigate } from "react-router-dom";
@ -18,7 +18,7 @@ export const useColumns = () => {
const navigate = useNavigate();
const handelShow = (record: Role) => {
navigate(`/${record?.id}`);
navigate(`${record?.id}/${ABILITIES_ENUM?.PERMISSIONS}`);
};
const handelDelete = (record: any) => {
@ -61,9 +61,11 @@ export const useColumns = () => {
<ActionButtons
canDelete={canEditRole}
canEdit={canDeleteRole}
canShow={canShowRole}
index={index}
onDelete={() => handelDelete(record)}
onEdit={() => handleEdit(record)}
onShow={()=>handelShow(record)}
/>
);
},

View File

@ -1,12 +1,16 @@
import { Formik,Form, Field } from "formik";
import React from "react";
import { useTranslation } from "react-i18next";
import LaTeXInputMemo from "./LaTeXInputMemo";
import MathMLPreview from "./MathMLPreview";
const Dummy = () => {
const [t] = useTranslation();
return (
<div className="DummyHomePage">
<MathMLPreview/>
</div>
);
};

View File

@ -0,0 +1,31 @@
import React, { useState, useEffect } from 'react';
import { MathJax, MathJaxContext } from 'better-react-mathjax';
const MathMLPreview = () => {
const [mathML, setMathML] = useState('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi><mo>=</mo><mn>5</mn></math>');
useEffect(() => {
// Any logic to handle input updates and preview refresh can be added here
}, [mathML]);
return (
<div>
<textarea
value={mathML}
onChange={(e) => setMathML(e.target.value)}
rows={5}
style={{ width: '100%' }}
/>
<MathJaxContext>
<div>
<h3>Preview:</h3>
<MathJax dynamic>
<div dangerouslySetInnerHTML={{ __html: mathML }} />
</MathJax>
</div>
</MathJaxContext>
</div>
);
};
export default MathMLPreview;

View File

@ -166,16 +166,16 @@ export const menuItems: TMenuItem[] = [
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
// {
// header: "page_header.roles",
// element: <Roles />,
// icon: <FaUserShield />,
// text: "sidebar.role",
// path: `/${ABILITIES_ENUM?.ROLE}`,
// abilities: ABILITIES_ENUM?.ROLE,
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
// prevPath: 0,
// },
{
header: "page_header.roles",
element: <Roles />,
icon: <FaUserShield />,
text: "sidebar.role",
path: `/${ABILITIES_ENUM?.ROLE}`,
abilities: ABILITIES_ENUM?.ROLE,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
},
/// RESELLER /////
@ -310,8 +310,8 @@ export const CrudRoute: TCrudRoute[] = [
{
header: "page_header.permissions",
element: <Permissions />,
path: `/${ABILITIES_ENUM?.PERMISSIONS}`,
abilities: ABILITIES_ENUM?.PERMISSIONS,
path: `/${ABILITIES_ENUM?.ROLE}/:${ParamsEnum?.ROLE_ID}/${ABILITIES_ENUM?.PERMISSIONS}`,
abilities: ABILITIES_ENUM?.ROLE,
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
prevPath: 0,
},

View File

@ -364,7 +364,7 @@
.LaTeXInput{
.text{
display: flex !important;
// display: flex !important;
align-items: center;
gap: 10px;
.error_message{

View File

@ -58,7 +58,7 @@
.LatexPreview{
height: 40px;
display: flex;
align-items: center;
align-items: center;
}
.LaTeXInputOptions{
display: flex;
@ -71,4 +71,15 @@
> span {
color: transparent;
}
}
.katex .msupsub{
text-align: end !important;
}
.mtight{
font-size: 10px !important;
}
.katex .delimcenter, .katex .op-symbol{
display: none;
}

21
src/api/Permissions.ts Normal file
View 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: "/permissions",
ADD: "/permissions",
DELETE: "/permissions",
UPDATE: "/permissions",
};
const KEY = "Permissions";
export const useGetAllPermissions = (params?: any, options?: any) =>
useGetQuery(KEY, API.GET, params, options);
export const useAddPermissions = () => useAddMutation(KEY, API.ADD);
export const useUpdatePermissions = (params?: any) =>
useUpdateMutation(KEY, API.GET);
export const useDeletePermissions = (params?: any) =>
useDeleteMutation(KEY, API.DELETE);

View File

@ -27,3 +27,6 @@ function useAddMutation(
}
export default useAddMutation;

View File

@ -68,10 +68,6 @@ export enum ABILITIES_VALUES_ENUM {
UPDATE = "update",
DELETE = "delete",
SHOW = "show",
ME = "me",
IMPORT_STUDENT_DATA = "importStudentData",
MOVE_STUDENTS = "moveStudents",
IMPORT_STUDENTS = "importStudents",
OVERVIEW = "overview",
PRESENCE = "presence",
PASS = "PASS"
}

View File

@ -232,7 +232,8 @@
"edit":"تعديل",
"delete":"حذف",
"read":"قراءة",
"managers":"مدراء"
"managers":"مدراء",
"show":"عرض"
},
"practical": {
"to_confirm_deletion_please_re_enter": "لتأكيد الحذف، يرجى إعادة الإدخال",

View File

@ -16,7 +16,7 @@ export interface Response {
isLoading: boolean;
}
export interface DataTableProps {
export interface DataTableProps extends TableProps {
response: any;
useColumns: any;
dataSource?: any;

View File

@ -1,5 +1,9 @@
import { MathMLToLaTeX } from 'mathml-to-latex';
export function convertMathMLToLaTeX(mathml: string): string {
console.log(MathMLToLaTeX.convert(mathml));
console.log(mathml);
return MathMLToLaTeX.convert(mathml);
}

View File

@ -132,6 +132,10 @@ export const canDeleteRole = hasAbility(
ABILITIES_VALUES_ENUM.DELETE,
);
export const canShowRole = hasAbility(
ABILITIES_ENUM.ROLE,
ABILITIES_VALUES_ENUM.SHOW,
);
/// Payment
export const canIndexPayment = hasAbility(