Compare commits
5 Commits
7fc7258a24
...
3ff4e0f846
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff4e0f846 | ||
|
|
3525d8f667 | ||
|
|
862380b2b3 | ||
|
|
0d3856d725 | ||
|
|
80dffd913e |
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
|
@ -24,6 +24,7 @@
|
||||||
"toastify",
|
"toastify",
|
||||||
"Viewelement",
|
"Viewelement",
|
||||||
"webp",
|
"webp",
|
||||||
|
"Xmark",
|
||||||
"zustand",
|
"zustand",
|
||||||
"مطلوب"
|
"مطلوب"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
1444
package-lock.json
generated
1444
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
|
|
@ -3,53 +3,40 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^5.3.7",
|
"@ant-design/icons": "^5.5.1",
|
||||||
"@dnd-kit/core": "^6.1.0",
|
"@dnd-kit/core": "^6.1.0",
|
||||||
"@dnd-kit/modifiers": "^7.0.0",
|
"@dnd-kit/modifiers": "^7.0.0",
|
||||||
"@dnd-kit/sortable": "^8.0.0",
|
"@dnd-kit/sortable": "^8.0.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@types/katex": "^0.16.7",
|
"@types/katex": "^0.16.7",
|
||||||
"@uiw/react-markdown-preview": "^5.1.3",
|
"@uiw/react-markdown-preview": "^5.1.3",
|
||||||
"antd": "^5.17.4",
|
"antd": "^5.21.1",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.7",
|
||||||
"better-react-mathjax": "^2.0.3",
|
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.13",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"i18next": "^23.11.5",
|
"i18next": "^23.15.1",
|
||||||
"install": "^0.13.0",
|
|
||||||
"katex": "^0.16.11",
|
"katex": "^0.16.11",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"lottie-react": "^2.4.0",
|
"lottie-react": "^2.4.0",
|
||||||
"mathjax": "^3.2.2",
|
|
||||||
"mathjax-full": "^3.2.2",
|
|
||||||
"mathjs": "^13.1.1",
|
"mathjs": "^13.1.1",
|
||||||
"mathml-to-latex": "^1.4.1",
|
"mathml-to-latex": "^1.4.1",
|
||||||
"mathml2latex": "^1.1.3",
|
|
||||||
"mml2tex": "^0.0.2",
|
|
||||||
"npm": "^10.8.3",
|
"npm": "^10.8.3",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-i18next": "^13.5.0",
|
"react-i18next": "^13.5.0",
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-intersection-observer": "^9.13.1",
|
|
||||||
"react-katex": "^3.0.1",
|
"react-katex": "^3.0.1",
|
||||||
"react-latex": "^2.0.0",
|
|
||||||
"react-latex-next": "^3.0.0",
|
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
"react-mathjax": "^1.0.1",
|
|
||||||
"react-mathjax-preview": "^2.2.6",
|
|
||||||
"react-mathjax2": "^0.0.2",
|
|
||||||
"react-query": "^3.39.3",
|
"react-query": "^3.39.3",
|
||||||
"react-router-dom": "^6.23.1",
|
"react-router-dom": "^6.26.2",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
"react-window": "^1.8.10",
|
"react-window": "^1.8.10",
|
||||||
"react-window-dynamic": "^1.8.0-alpha.2",
|
"reactstrap": "^9.2.3",
|
||||||
"reactstrap": "^9.2.2",
|
"sass": "^1.79.4",
|
||||||
"sass": "^1.77.4",
|
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.4.0",
|
||||||
"zustand": "^4.5.2"
|
"zustand": "^4.5.5"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite --port=3000",
|
"start": "vite --port=3000",
|
||||||
|
|
@ -81,26 +68,26 @@
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/node": "^20.14.0",
|
"@types/node": "^20.16.10",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.10",
|
||||||
"@types/react-beautiful-dnd": "^13.1.8",
|
"@types/react-beautiful-dnd": "^13.1.8",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/react-helmet": "^6.1.11",
|
"@types/react-helmet": "^6.1.11",
|
||||||
"@types/react-katex": "^3.0.4",
|
"@types/react-katex": "^3.0.4",
|
||||||
"@types/react-latex": "^2.0.3",
|
"@types/react-latex": "^2.0.3",
|
||||||
"@types/react-window": "^1.8.8",
|
"@types/react-window": "^1.8.8",
|
||||||
"@vitejs/plugin-legacy": "^5.4.1",
|
"@vitejs/plugin-legacy": "^5.4.2",
|
||||||
"@vitejs/plugin-react": "^4.3.0",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jsdom": "^24.1.0",
|
"jsdom": "^24.1.3",
|
||||||
"prettier": "^3.3.0",
|
"prettier": "^3.3.3",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"ts-jest": "^29.1.4",
|
"ts-jest": "^29.2.5",
|
||||||
"ts-loader": "^9.5.1",
|
"ts-loader": "^9.5.1",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"vite": "^5.2.12",
|
"vite": "^5.4.8",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"webpack": "^5.93.0",
|
"webpack": "^5.95.0",
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4485
pnpm-lock.yaml
4485
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -2,16 +2,18 @@ import React from 'react';
|
||||||
import { BlockMath } from 'react-katex';
|
import { BlockMath } from 'react-katex';
|
||||||
import 'katex/dist/katex.min.css';
|
import 'katex/dist/katex.min.css';
|
||||||
|
|
||||||
const LatexPreview = ({ latex }: { latex: string }) => {
|
|
||||||
console.log(latex);
|
|
||||||
|
|
||||||
const sanitizedLatex = latex.replace(/\\_/g, '_');
|
const LatexPreview = ({ latex }: { latex: string }) => {
|
||||||
|
// console.log(latex);
|
||||||
|
|
||||||
|
// const sanitizedLatex = latex.replace(/\\_/g, '_');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
|
||||||
<BlockMath>
|
<BlockMath>
|
||||||
{sanitizedLatex}
|
{latex}
|
||||||
</BlockMath>
|
</BlockMath>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,15 @@ const SelectTagV2: React.FC = () => {
|
||||||
const NewShapeTags = CurrentTags?.map((item:any)=> {return item?.name ?? item })
|
const NewShapeTags = CurrentTags?.map((item:any)=> {return item?.name ?? item })
|
||||||
|
|
||||||
const handleChange = (_value: any[],option:any) => {
|
const handleChange = (_value: any[],option:any) => {
|
||||||
console.log(option,"option");
|
// console.log(option,"option");
|
||||||
const NewShapeOption = option?.map((item:any)=> {return ({name:item?.name,id:item?.id})})
|
console.log(_value);
|
||||||
console.log(NewShapeOption);
|
|
||||||
|
|
||||||
formik.setFieldValue("tags", NewShapeOption);
|
// const NewShapeOption = option?.map((item:any)=> {return ({name:item?.name,id:item?.id})})
|
||||||
setSearchValue("");
|
// console.log(NewShapeOption);
|
||||||
setFieldValue("");
|
|
||||||
|
// formik.setFieldValue("tags", NewShapeOption);
|
||||||
|
// setSearchValue("");
|
||||||
|
// setFieldValue("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = useDebounce((value: string) => {
|
const handleSearch = useDebounce((value: string) => {
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,10 @@ const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen,setCurren
|
||||||
setLatex("")
|
setLatex("")
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
}else{
|
}else{
|
||||||
|
setFieldValue(name, oldValue + " $$ " +Latex +" $$ ");
|
||||||
|
setCurrentValue(oldValue + " $$ " +Latex +" $$ ")
|
||||||
setLatex("")
|
setLatex("")
|
||||||
toast.error(t("validation.that_is_not_a_valid_mml"))
|
setIsModalOpen(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,7 @@ import { useModalState } from "./Modal";
|
||||||
import { useFilterState } from "./FilterState";
|
import { useFilterState } from "./FilterState";
|
||||||
import { ModalEnum } from "../../../enums/Model";
|
import { ModalEnum } from "../../../enums/Model";
|
||||||
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
import { QueryStatusEnum } from "../../../enums/QueryStatus";
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
|
||||||
import SpinContainer from "../../Layout/SpinContainer";
|
import SpinContainer from "../../Layout/SpinContainer";
|
||||||
import { TbFlagCancel } from "react-icons/tb";
|
|
||||||
import { XFilled } from "@ant-design/icons";
|
|
||||||
import { FaXmark } from "react-icons/fa6";
|
import { FaXmark } from "react-icons/fa6";
|
||||||
|
|
||||||
type OmitFormikProps = "children" | "initialValues" | "onSubmit";
|
type OmitFormikProps = "children" | "initialValues" | "onSubmit";
|
||||||
|
|
@ -158,8 +155,8 @@ const useFilter = () => {
|
||||||
return (
|
return (
|
||||||
<div className="filter-submit-buttons buttons">
|
<div className="filter-submit-buttons buttons">
|
||||||
<Button
|
<Button
|
||||||
|
type="primary"
|
||||||
className="back_button filter_modal_cancel_button"
|
className="back_button filter_modal_cancel_button"
|
||||||
type="default"
|
|
||||||
htmlType="reset"
|
htmlType="reset"
|
||||||
>
|
>
|
||||||
{t("practical.reset")}
|
{t("practical.reset")}
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ const Date = ({
|
||||||
label,
|
label,
|
||||||
picker = "date",
|
picker = "date",
|
||||||
isDisabled,
|
isDisabled,
|
||||||
props,
|
|
||||||
onChange,
|
onChange,
|
||||||
placeholder,
|
placeholder,
|
||||||
className,
|
className,
|
||||||
no_label,
|
no_label,
|
||||||
label_icon,
|
label_icon,
|
||||||
|
...props
|
||||||
}: any) => {
|
}: any) => {
|
||||||
const { errorMsg, isError, t, formik } = useFormField(name, props);
|
const { errorMsg, isError, t, formik } = useFormField(name, props);
|
||||||
|
|
||||||
|
|
@ -25,6 +25,7 @@ const Date = ({
|
||||||
const onCalendarChange = (value: any) => {
|
const onCalendarChange = (value: any) => {
|
||||||
formik.setFieldValue(name, value);
|
formik.setFieldValue(name, value);
|
||||||
};
|
};
|
||||||
|
console.log(props);
|
||||||
console.log(FormikValue);
|
console.log(FormikValue);
|
||||||
|
|
||||||
const Formatter = [DateEnum?.FORMATE];
|
const Formatter = [DateEnum?.FORMATE];
|
||||||
|
|
@ -49,8 +50,10 @@ const Date = ({
|
||||||
size="large"
|
size="large"
|
||||||
onChange={onChange || onCalendarChange}
|
onChange={onChange || onCalendarChange}
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
format={Formatter}
|
format={props?.Format ?? Formatter}
|
||||||
id={name}
|
id={name}
|
||||||
|
needConfirm={false}
|
||||||
|
{...props}
|
||||||
/>
|
/>
|
||||||
{/* <DatePicker onChange={onChange} /> */}
|
{/* <DatePicker onChange={onChange} /> */}
|
||||||
</ValidationFieldContainer>
|
</ValidationFieldContainer>
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,9 @@ export type SearchFieldProps = BaseFieldProps &
|
||||||
|
|
||||||
type DateFieldProps = BaseFieldProps & {
|
type DateFieldProps = BaseFieldProps & {
|
||||||
type: "DataRange" | "Date" | "Time";
|
type: "DataRange" | "Date" | "Time";
|
||||||
Format?: "YYYY/MM/DD" | "MM/DD" | "YYYY/MM" | "YYYY-MM-DD HH:mm:ss.SSS";
|
Format?: "YYYY/MM/DD" | "MM/DD" | "YYYY/MM" | "YYYY-MM-DD HH:mm:ss.SSS" | "YYYY-MM-DD HH:mm:ss";
|
||||||
picker?: "data" | "week" | "month" | "quarter" | "year";
|
picker?: "data" | "week" | "month" | "quarter" | "year";
|
||||||
|
showTime?:boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
type FileFieldProps = BaseFieldProps & {
|
type FileFieldProps = BaseFieldProps & {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const TableHeader = () => {
|
||||||
ModelAbility={ModalEnum?.CITY_ADD}
|
ModelAbility={ModalEnum?.CITY_ADD}
|
||||||
canAdd={canAddCity}
|
canAdd={canAddCity}
|
||||||
/>
|
/>
|
||||||
<FilterLayout sub_children={<FilterForm />} filterTitle="table.City" />
|
<FilterLayout sub_children={<FilterForm />} haveFilter={false} filterTitle="table.City" />
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
38
src/Pages/Admin/Coupon/Model/AddModel.tsx
Normal file
38
src/Pages/Admin/Coupon/Model/AddModel.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 { QueryStatusEnum } from "../../../../enums/QueryStatus";
|
||||||
|
import ModelForm from "./ModelForm";
|
||||||
|
import { useAddCoupon } from "../../../../api/Coupon";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
const AddModel: React.FC = () => {
|
||||||
|
const { mutate, status } = useAddCoupon();
|
||||||
|
|
||||||
|
const handleSubmit = (values: any) => {
|
||||||
|
console.log(values?.due_to,"values?.due_to");
|
||||||
|
const due_to = values?.due_to.format("YYYY-MM-DD HH:mm:ss")
|
||||||
|
console.log(due_to);
|
||||||
|
mutate({
|
||||||
|
...values,
|
||||||
|
due_to
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<LayoutModel
|
||||||
|
status={status as QueryStatusEnum}
|
||||||
|
ModelEnum={ModalEnum.COUPON_ADD}
|
||||||
|
modelTitle="Coupon"
|
||||||
|
handleSubmit={handleSubmit}
|
||||||
|
getInitialValues={getInitialValues({})}
|
||||||
|
getValidationSchema={getValidationSchema}
|
||||||
|
>
|
||||||
|
<ModelForm />
|
||||||
|
</LayoutModel>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddModel;
|
||||||
38
src/Pages/Admin/Coupon/Model/EditModel.tsx
Normal file
38
src/Pages/Admin/Coupon/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 { useUpdateCoupon } from "../../../../api/Coupon";
|
||||||
|
import { handelImageState } from "../../../../utils/DataToSendImageState";
|
||||||
|
|
||||||
|
const EditModel: React.FC = () => {
|
||||||
|
const { mutate, status } = useUpdateCoupon();
|
||||||
|
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||||
|
|
||||||
|
const handleSubmit = (values: any) => {
|
||||||
|
const due_to = typeof values?.due_to === "string" ? values?.due_to : values?.due_to.format("YYYY-MM-DD HH:mm:ss")
|
||||||
|
const Data_to_send = { ...values , due_to };
|
||||||
|
mutate(Data_to_send);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<LayoutModel
|
||||||
|
status={status as QueryStatusEnum}
|
||||||
|
ModelEnum={ModalEnum.COUPON_EDIT}
|
||||||
|
modelTitle="Coupon"
|
||||||
|
handleSubmit={handleSubmit}
|
||||||
|
getInitialValues={getInitialValues(objectToEdit)}
|
||||||
|
getValidationSchema={getValidationSchema}
|
||||||
|
isAddModal={false}
|
||||||
|
>
|
||||||
|
<ModelForm Hide={true} />
|
||||||
|
</LayoutModel>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditModel;
|
||||||
20
src/Pages/Admin/Coupon/Model/FilterForm.tsx
Normal file
20
src/Pages/Admin/Coupon/Model/FilterForm.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import React from "react";
|
||||||
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
|
import { Col, Row } from "reactstrap";
|
||||||
|
import { useFormikContext } from "formik";
|
||||||
|
|
||||||
|
const FilterForm = () => {
|
||||||
|
const formik = useFormikContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterForm;
|
||||||
62
src/Pages/Admin/Coupon/Model/ModelForm.tsx
Normal file
62
src/Pages/Admin/Coupon/Model/ModelForm.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { Col, Row } from "reactstrap";
|
||||||
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
|
import { useValidationValidationParamState } from "../../../../Components/ValidationField/state/ValidationValidationParamState";
|
||||||
|
import { useGetAllGrade } from "../../../../api/grade";
|
||||||
|
|
||||||
|
const Form = ({Hide = false}:{Hide?: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;
|
||||||
|
return (
|
||||||
|
<Row className="w-100">
|
||||||
|
<Col>
|
||||||
|
<ValidationField name="name" placeholder="name" label="name" />
|
||||||
|
<ValidationField name="amount" type="number" placeholder="amount" label="amount" />
|
||||||
|
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<ValidationField
|
||||||
|
name="due_to" type="Date"
|
||||||
|
Format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
placeholder="due_to" label="due_to"
|
||||||
|
showTime
|
||||||
|
|
||||||
|
/>
|
||||||
|
<ValidationField name="code" placeholder="code" label="code" />
|
||||||
|
{/*
|
||||||
|
grade_id
|
||||||
|
*/}
|
||||||
|
{!Hide &&
|
||||||
|
|
||||||
|
<ValidationField
|
||||||
|
searchBy="GradeName"
|
||||||
|
name="grade_id"
|
||||||
|
label="grade"
|
||||||
|
placeholder="grade"
|
||||||
|
type="Search"
|
||||||
|
option={GradeOption}
|
||||||
|
isLoading={isLoadingGrade}
|
||||||
|
canChangePage={canChangeGradePage}
|
||||||
|
PageName={"GradeCurrentPage"}
|
||||||
|
page={GradePage}
|
||||||
|
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Form;
|
||||||
27
src/Pages/Admin/Coupon/Model/formUtil.ts
Normal file
27
src/Pages/Admin/Coupon/Model/formUtil.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import { Coupon, CouponInitialValues } from "../../../../types/Coupon";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
export const getInitialValues = (
|
||||||
|
objectToEdit: Partial<Coupon>,
|
||||||
|
): CouponInitialValues => {
|
||||||
|
return {
|
||||||
|
id: objectToEdit?.id,
|
||||||
|
name: objectToEdit?.name ?? "",
|
||||||
|
amount: objectToEdit?.amount ?? "",
|
||||||
|
code: objectToEdit?.code ?? "",
|
||||||
|
due_to: objectToEdit?.due_to ? dayjs(objectToEdit?.due_to,"YYYY-MM-DD HH:mm:ss") : "",
|
||||||
|
grade_id: objectToEdit?.grade_id ?? "",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getValidationSchema = () => {
|
||||||
|
// validate input
|
||||||
|
return Yup.object().shape({
|
||||||
|
name: Yup.string().required("validation.required"),
|
||||||
|
due_to: Yup.string().required("validation.required"),
|
||||||
|
code: Yup.string().required("validation.required").min(6,"validation.must_be_at_least_6_characters_long").max(6,"validation.must_be_at_least_6_characters_long"),
|
||||||
|
amount: Yup.number().required("validation.required").typeError("validation.Must_be_a_number"),
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
49
src/Pages/Admin/Coupon/Page.tsx
Normal file
49
src/Pages/Admin/Coupon/Page.tsx
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
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 { useDeleteCoupon } from "../../../api/Coupon";
|
||||||
|
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
||||||
|
import FilterLayout from "../../../Layout/Dashboard/FilterLayout";
|
||||||
|
import FilterForm from "./Model/FilterForm";
|
||||||
|
import { canAddCoupon } from "../../../utils/hasAbilityFn";
|
||||||
|
|
||||||
|
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 = useDeleteCoupon();
|
||||||
|
|
||||||
|
useSetPageTitle([
|
||||||
|
{name:`${t(`page_header.home`)}`, path:"/"},
|
||||||
|
{name:`${t(`page_header.Coupon`)}`, path:"Coupon"}
|
||||||
|
]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="TableWithHeader">
|
||||||
|
<Suspense fallback={<Spin />}>
|
||||||
|
<PageHeader
|
||||||
|
pageTitle="Coupon"
|
||||||
|
ModelAbility={ModalEnum?.COUPON_ADD}
|
||||||
|
canAdd={canAddCoupon}
|
||||||
|
/>
|
||||||
|
<FilterLayout sub_children={<FilterForm />} haveFilter={false} filterTitle="table.Coupon" />
|
||||||
|
<Table />
|
||||||
|
<AddModalForm />
|
||||||
|
<EditModalForm />
|
||||||
|
<DeleteModalForm
|
||||||
|
deleteMutation={deleteMutation}
|
||||||
|
ModelEnum={ModalEnum?.COUPON_DELETE}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableHeader;
|
||||||
23
src/Pages/Admin/Coupon/Table.tsx
Normal file
23
src/Pages/Admin/Coupon/Table.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { useColumns } from "./useTableColumns";
|
||||||
|
import React from "react";
|
||||||
|
import DataTable from "../../../Layout/Dashboard/Table/DataTable";
|
||||||
|
import { useGetAllCoupon } from "../../../api/Coupon";
|
||||||
|
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
|
||||||
|
import { useFilterStateState } from "../../../zustand/Filter";
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const { filterState } = useFilterState();
|
||||||
|
const { Filter } = useFilterStateState();
|
||||||
|
const name = Filter?.name ;
|
||||||
|
const sort_by = Filter?.sort_by ;
|
||||||
|
const response = useGetAllCoupon({
|
||||||
|
pagination: true,
|
||||||
|
...filterState,
|
||||||
|
name,
|
||||||
|
sort_by
|
||||||
|
});
|
||||||
|
|
||||||
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
92
src/Pages/Admin/Coupon/useTableColumns.tsx
Normal file
92
src/Pages/Admin/Coupon/useTableColumns.tsx
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
import { TableColumnsType } from "antd";
|
||||||
|
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 {
|
||||||
|
canDeleteCoupon,
|
||||||
|
canEditCoupon,
|
||||||
|
canShowCoupon,
|
||||||
|
} from "../../../utils/hasAbilityFn";
|
||||||
|
import ActionButtons from "../../../Components/Table/ActionButtons";
|
||||||
|
import ColumnsImage from "../../../Components/Columns/ColumnsImage";
|
||||||
|
import { Coupon } from "../../../types/Coupon";
|
||||||
|
import { useFilterStateState } from "../../../zustand/Filter";
|
||||||
|
|
||||||
|
export const useColumns = () => {
|
||||||
|
const { handel_open_model } = useModalHandler();
|
||||||
|
|
||||||
|
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handelShow = (record: Coupon) => {
|
||||||
|
setFilter({})
|
||||||
|
navigate(`${record?.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handelDelete = (data: Coupon) => {
|
||||||
|
setObjectToEdit(data);
|
||||||
|
handel_open_model(ModalEnum?.COUPON_DELETE);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEdit = (record: Coupon) => {
|
||||||
|
setObjectToEdit(record);
|
||||||
|
handel_open_model(ModalEnum?.COUPON_EDIT);
|
||||||
|
};
|
||||||
|
const [t] = useTranslation();
|
||||||
|
|
||||||
|
const columns: TableColumnsType<Coupon> = [
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
ellipsis:true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t("columns.image"),
|
||||||
|
dataIndex: "image",
|
||||||
|
key: "image",
|
||||||
|
align: "center",
|
||||||
|
render: (_text: any, record: Coupon) => {
|
||||||
|
let str = record?.amount;
|
||||||
|
|
||||||
|
return <ColumnsImage src={str}/> ;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
|
||||||
|
title: t("columns.procedure"),
|
||||||
|
key: "actions",
|
||||||
|
align: "center",
|
||||||
|
width: "25vw",
|
||||||
|
render: (_text, record, index) => {
|
||||||
|
return (
|
||||||
|
<ActionButtons
|
||||||
|
canDelete={canDeleteCoupon}
|
||||||
|
canEdit={canEditCoupon}
|
||||||
|
canShow={canShowCoupon}
|
||||||
|
index={index}
|
||||||
|
onDelete={() => handelDelete(record)}
|
||||||
|
onEdit={() => handleEdit(record)}
|
||||||
|
onShow={() => handelShow(record)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return columns;
|
||||||
|
};
|
||||||
|
|
@ -7,6 +7,7 @@ import { useValidationValidationParamState } from "../../../../Components/Valida
|
||||||
import { useGetAllUnit } from "../../../../api/unit";
|
import { useGetAllUnit } from "../../../../api/unit";
|
||||||
import { useGetAllSubject } from "../../../../api/subject";
|
import { useGetAllSubject } from "../../../../api/subject";
|
||||||
import { useGetAllLesson } from "../../../../api/lesson";
|
import { useGetAllLesson } from "../../../../api/lesson";
|
||||||
|
import { useGetAllTag } from "../../../../api/tags";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
||||||
|
|
@ -15,7 +16,8 @@ const FilterForm = () => {
|
||||||
GradeName, GradeCurrentPage,
|
GradeName, GradeCurrentPage,
|
||||||
SubjectName, SubjectCurrentPage,
|
SubjectName, SubjectCurrentPage,
|
||||||
UnitName, UnitCurrentPage,
|
UnitName, UnitCurrentPage,
|
||||||
LessonName, LessonCurrentPage
|
LessonName, LessonCurrentPage,
|
||||||
|
TagName , TagCurrentPage
|
||||||
|
|
||||||
|
|
||||||
} = ValidationParamState;
|
} = ValidationParamState;
|
||||||
|
|
@ -58,6 +60,17 @@ const FilterForm = () => {
|
||||||
const canChangeLessonPage = !!Lesson?.links?.next;
|
const canChangeLessonPage = !!Lesson?.links?.next;
|
||||||
const LessonPage = Lesson?.meta?.currentPage;
|
const LessonPage = Lesson?.meta?.currentPage;
|
||||||
|
|
||||||
|
|
||||||
|
/// TagsIds
|
||||||
|
const { data: Tag, isLoading: isLoadingTag } = useGetAllTag({
|
||||||
|
name: TagName,
|
||||||
|
page: TagCurrentPage
|
||||||
|
});
|
||||||
|
const TagOption = Tag?.data ?? []
|
||||||
|
const canChangeTagPage = !!Tag?.links?.next;
|
||||||
|
const TagPage = Tag?.meta?.currentPage;
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
|
|
@ -97,7 +110,23 @@ const FilterForm = () => {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
{/*
|
||||||
|
TagsIds
|
||||||
|
*/}
|
||||||
|
|
||||||
|
<ValidationField
|
||||||
|
searchBy="TagName"
|
||||||
|
name="tagsIds"
|
||||||
|
label="tag"
|
||||||
|
type="Search"
|
||||||
|
option={TagOption}
|
||||||
|
isMulti
|
||||||
|
isLoading={isLoadingTag}
|
||||||
|
canChangePage={canChangeTagPage}
|
||||||
|
PageName={"TagCurrentPage"}
|
||||||
|
page={TagPage}
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
@ -137,6 +166,9 @@ const FilterForm = () => {
|
||||||
page={LessonPage}
|
page={LessonPage}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const TableHeader = () => {
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="QuestionBank"
|
pageTitle="QuestionBank"
|
||||||
ModelAbility={ModalEnum?.QUESTION_BANK_ADD}
|
ModelAbility={ModalEnum?.QUESTION_BANK_ADD}
|
||||||
canAdd={canAddQuestionBank}
|
canAdd={false}
|
||||||
/>
|
/>
|
||||||
<FilterLayout width="700px" search_by="content" sub_children={<FilterForm />} filterTitle="table.QuestionBank" />
|
<FilterLayout width="700px" search_by="content" sub_children={<FilterForm />} filterTitle="table.QuestionBank" />
|
||||||
<Table />
|
<Table />
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,8 @@ export const useColumns = () => {
|
||||||
key: "hint",
|
key: "hint",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>{record?.hint ?? "karim"}</>
|
<>{record?.hint ?? "_"}</>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ const PersonalDetailsForm = ({isEdit}:{isEdit?:boolean}) => {
|
||||||
placeholder={"_"}
|
placeholder={"_"}
|
||||||
label={"ID Number"}
|
label={"ID Number"}
|
||||||
/>
|
/>
|
||||||
<ValidationField
|
{/* <ValidationField
|
||||||
name={"location_lat"}
|
name={"location_lat"}
|
||||||
placeholder={"_"}
|
placeholder={"_"}
|
||||||
label={"lat"}
|
label={"lat"}
|
||||||
|
|
@ -63,7 +63,7 @@ const PersonalDetailsForm = ({isEdit}:{isEdit?:boolean}) => {
|
||||||
name={"location_lng"}
|
name={"location_lng"}
|
||||||
placeholder={"_"}
|
placeholder={"_"}
|
||||||
label={"lng"}
|
label={"lng"}
|
||||||
/>
|
/> */}
|
||||||
{/* <ValidationField
|
{/* <ValidationField
|
||||||
name={"id_number"}
|
name={"id_number"}
|
||||||
placeholder={"_"}
|
placeholder={"_"}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ const TableHeader = () => {
|
||||||
<FilterLayout
|
<FilterLayout
|
||||||
sub_children={<FilterForm />}
|
sub_children={<FilterForm />}
|
||||||
filterTitle="sidebar.tags"
|
filterTitle="sidebar.tags"
|
||||||
|
haveFilter={false}
|
||||||
/>
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<DeleteModalForm
|
<DeleteModalForm
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ const DrapableTable: React.FC = () => {
|
||||||
const sort_by = Filter?.sort_by ;
|
const sort_by = Filter?.sort_by ;
|
||||||
const response = useGetAllUnit({
|
const response = useGetAllUnit({
|
||||||
subject_id: subject_id,
|
subject_id: subject_id,
|
||||||
pagination: false,
|
isPaginated: false,
|
||||||
name,
|
name,
|
||||||
sort_by,
|
sort_by,
|
||||||
...filterState,
|
...filterState,
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ const DrapableTable: React.FC = () => {
|
||||||
|
|
||||||
const response = useGetAllLesson({
|
const response = useGetAllLesson({
|
||||||
unit_id: unit_id,
|
unit_id: unit_id,
|
||||||
pagination: false,
|
isPaginated: false,
|
||||||
name,
|
name,
|
||||||
sort_by,
|
sort_by,
|
||||||
...filterState,
|
...filterState,
|
||||||
|
|
|
||||||
|
|
@ -278,9 +278,13 @@ const EditPage: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log(location.pathname);
|
||||||
|
console.log(deletePathSegments(location.pathname, 2));
|
||||||
|
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
toast.success(t("validation.the_possess_done_successful"));
|
toast.success(t("validation.the_possess_done_successful"));
|
||||||
navigate(deletePathSegments(location.pathname, 2));
|
navigate(-1);
|
||||||
|
|
||||||
}
|
}
|
||||||
}, [isSuccess]);
|
}, [isSuccess]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { Choice } from "../../../../../../types/Item";
|
|
||||||
import { Field, useFormikContext } from "formik";
|
import { Field, useFormikContext } from "formik";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { getCharFromNumber } from "../../../../../../utils/getCharFromNumber";
|
|
||||||
import TextField from "./TextField";
|
|
||||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
||||||
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
|
|
||||||
import { GoTrash } from "react-icons/go";
|
import { GoTrash } from "react-icons/go";
|
||||||
import { Popconfirm } from "antd";
|
import { Popconfirm } from "antd";
|
||||||
import LaTeXInput from "../../../../../../Components/LatextInput/LaTeXInput";
|
|
||||||
import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo";
|
import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo";
|
||||||
import ImageBoxFieldMemo from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
import ImageBoxFieldMemo from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { FaCirclePlus } from "react-icons/fa6";
|
||||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
||||||
import MaltySelectTag from "../Tags/MaltySelectTag";
|
import MaltySelectTag from "../Tags/MaltySelectTag";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
import SelectTagV2 from "../../../../../../Components/CustomFields/SelectTagV2";
|
||||||
|
|
||||||
export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
||||||
const { values, setFieldValue, ShowHint, t } = data;
|
const { values, setFieldValue, ShowHint, t } = data;
|
||||||
|
|
@ -61,6 +62,7 @@ export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<MaltySelectTag parent_index={index} />
|
<MaltySelectTag parent_index={index} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ const Form = () => {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
<SelectTag />
|
<SelectTag />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,8 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import MathMLPreview from "./MathMLPreview";
|
|
||||||
import { Field, Form, Formik } from "formik";
|
|
||||||
import Test from "./Test";
|
|
||||||
import MarkdownPreview from '@uiw/react-markdown-preview';
|
|
||||||
import { BlockMath } from "react-katex";
|
|
||||||
|
|
||||||
const Dummy = () => {
|
const Dummy = () => {
|
||||||
const [t] = useTranslation();
|
|
||||||
const [markdown, setMarkdown] = useState<string>(' \nV_{sphere} = \\frac{4}{3}\\pi r^3\n');
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="DummyHomePage">
|
<div className="DummyHomePage">
|
||||||
|
karim is op
|
||||||
<MarkdownPreview style={{background:"transparent" ,color:"black"}} source={"This is an <u>underlined</u> text."} />
|
|
||||||
<BlockMath>
|
|
||||||
{markdown}
|
|
||||||
</BlockMath>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { TCrudRoute, TMenuItem } from "./types/App";
|
import { TCrudRoute, TMenuItem } from "./types/App";
|
||||||
import { FaCashRegister, FaCity, FaHome, FaMoneyBill, FaPaperclip, FaSellcast, FaTag, FaUser, FaUserShield } from "react-icons/fa";
|
import { FaCashRegister, FaCity, FaHome, FaMonero, FaMoneyBill, FaPaperclip, FaSellcast, FaTag, FaUser, FaUserShield } from "react-icons/fa";
|
||||||
import { GoDotFill } from "react-icons/go";
|
import { GoDotFill } from "react-icons/go";
|
||||||
import { MdOutlineSell } from "react-icons/md";
|
import { MdOutlineSell } from "react-icons/md";
|
||||||
import { CgProfile } from "react-icons/cg";
|
import { CgProfile } from "react-icons/cg";
|
||||||
|
|
@ -48,6 +48,8 @@ const Setting = React.lazy(() => import("./Pages/Admin/Setting/Page"));
|
||||||
|
|
||||||
const Permissions = React.lazy(() => import("./Pages/Admin/Roles/Permissions/Page"));
|
const Permissions = React.lazy(() => import("./Pages/Admin/Roles/Permissions/Page"));
|
||||||
const Roles = React.lazy(() => import("./Pages/Admin/Roles/Page"));
|
const Roles = React.lazy(() => import("./Pages/Admin/Roles/Page"));
|
||||||
|
const Coupon = React.lazy(() => import("./Pages/Admin/Coupon/Page"));
|
||||||
|
|
||||||
const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
|
const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
|
||||||
const Param = React.lazy(() => import("./Pages/Admin/Param/Page"));
|
const Param = React.lazy(() => import("./Pages/Admin/Param/Page"));
|
||||||
|
|
||||||
|
|
@ -66,6 +68,7 @@ import { ParamsEnum } from "./enums/params";
|
||||||
import { TbCategory } from "react-icons/tb";
|
import { TbCategory } from "react-icons/tb";
|
||||||
import { UserTypeEnum } from "./enums/UserType";
|
import { UserTypeEnum } from "./enums/UserType";
|
||||||
import { FaTags } from "react-icons/fa6";
|
import { FaTags } from "react-icons/fa6";
|
||||||
|
import { CiSquareQuestion } from "react-icons/ci";
|
||||||
|
|
||||||
export const menuItems: TMenuItem[] = [
|
export const menuItems: TMenuItem[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -175,16 +178,16 @@ export const menuItems: TMenuItem[] = [
|
||||||
// prevPath: 0,
|
// prevPath: 0,
|
||||||
// },
|
// },
|
||||||
|
|
||||||
// {
|
{
|
||||||
// header: "page_header.questionBank",
|
header: "page_header.questionBank",
|
||||||
// element: <QuestionBank />,
|
element: <QuestionBank />,
|
||||||
// icon: <CiSquareQuestion />,
|
icon: <CiSquareQuestion />,
|
||||||
// text: "sidebar.questionBank",
|
text: "sidebar.questionBank",
|
||||||
// path: `/${ABILITIES_ENUM?.QUESTION}`,
|
path: `/${ABILITIES_ENUM?.QUESTION}`,
|
||||||
// abilities: ABILITIES_ENUM?.QUESTION,
|
abilities: ABILITIES_ENUM?.QUESTION,
|
||||||
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||||
// prevPath: 0,
|
prevPath: 0,
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
header: "page_header.roles",
|
header: "page_header.roles",
|
||||||
element: <Roles />,
|
element: <Roles />,
|
||||||
|
|
@ -196,6 +199,17 @@ export const menuItems: TMenuItem[] = [
|
||||||
prevPath: 0,
|
prevPath: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
header: "page_header.coupon",
|
||||||
|
element: <Coupon />,
|
||||||
|
icon: <FaMoneyBill />,
|
||||||
|
text: "sidebar.coupon",
|
||||||
|
path: `/${ABILITIES_ENUM?.COUPON}`,
|
||||||
|
abilities: ABILITIES_ENUM?.COUPON,
|
||||||
|
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||||
|
prevPath: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
|
||||||
header: "page_header.financial_collection",
|
header: "page_header.financial_collection",
|
||||||
element: <FinancialCollection />,
|
element: <FinancialCollection />,
|
||||||
icon: <FaMoneyBill />,
|
icon: <FaMoneyBill />,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
padding: 20px 20px;
|
padding: 20px 20px;
|
||||||
border-radius: 10px 10px 0 0;
|
border-radius: 10px 10px 0 0;
|
||||||
box-shadow: 0px 0px 32px 2px #080F3414;
|
box-shadow: 0px 0px 32px 2px #080F3414;
|
||||||
|
// max-width: 85vw;
|
||||||
|
overflow-x: hidden;
|
||||||
|
min-height: fit-content;
|
||||||
>div {
|
>div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,14 @@
|
||||||
.PageTitle {
|
.PageTitle {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
margin-block: 10px;
|
margin-block: 10px;
|
||||||
|
|
||||||
.PageTitleItems {
|
.PageTitleItems {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--value);
|
color: var(--value);
|
||||||
|
max-width: 65vw;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,17 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
// &::after{
|
||||||
|
// position: absolute;
|
||||||
|
// content: "";
|
||||||
|
// top: 40%;
|
||||||
|
// left: 59%;
|
||||||
|
// transform: translate(-50%,-50%);
|
||||||
|
// width: 3px;
|
||||||
|
// height: 78%;
|
||||||
|
// background-color: red;
|
||||||
|
// z-index: 99999;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
.showPreviewInput{
|
.showPreviewInput{
|
||||||
background-color: var(--bg);
|
background-color: var(--bg);
|
||||||
|
|
@ -19,7 +29,7 @@
|
||||||
height: calc(100% - 44px);
|
height: calc(100% - 44px);
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 5px;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
@ -73,13 +83,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.katex .msupsub{
|
// .katex .msupsub{
|
||||||
text-align: end !important;
|
// text-align: end !important;
|
||||||
}
|
// }
|
||||||
.mtight{
|
// .mtight{
|
||||||
|
|
||||||
font-size: 10px !important;
|
// font-size: 10px !important;
|
||||||
}
|
// }
|
||||||
.katex .delimcenter, .katex .op-symbol{
|
// .katex .delimcenter, .katex .op-symbol{
|
||||||
display: none;
|
// display: none;
|
||||||
}
|
// }
|
||||||
20
src/api/Coupon.ts
Normal file
20
src/api/Coupon.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import useAddMutation from "./helper/useAddMutation";
|
||||||
|
import useDeleteMutation from "./helper/useDeleteMutation";
|
||||||
|
import useGetQuery from "./helper/useGetQuery";
|
||||||
|
import useUpdateMutation from "./helper/useUpdateMutation";
|
||||||
|
|
||||||
|
const API = {
|
||||||
|
GET: "/coupon",
|
||||||
|
ADD: "/coupon",
|
||||||
|
DELETE: "/coupon",
|
||||||
|
UPDATE: "/coupon",
|
||||||
|
};
|
||||||
|
|
||||||
|
const KEY = "Coupon";
|
||||||
|
|
||||||
|
export const useGetAllCoupon = (params?: any, options?: any) =>
|
||||||
|
useGetQuery(KEY, API.GET, params, options);
|
||||||
|
export const useAddCoupon = () => useAddMutation(KEY, API.ADD);
|
||||||
|
export const useUpdateCoupon = (params?: any) => useUpdateMutation(KEY, API.GET);
|
||||||
|
export const useDeleteCoupon = (params?: any) =>
|
||||||
|
useDeleteMutation(KEY, API.DELETE);
|
||||||
|
|
@ -74,6 +74,12 @@ export enum ModalEnum {
|
||||||
HOME_WORK_ADD = "homework.add",
|
HOME_WORK_ADD = "homework.add",
|
||||||
HOME_WORK_DELETE = "homework.delete",
|
HOME_WORK_DELETE = "homework.delete",
|
||||||
|
|
||||||
|
//// Coupon
|
||||||
|
|
||||||
|
COUPON_EDIT = "Coupon.edit",
|
||||||
|
COUPON_ADD = "Coupon.add",
|
||||||
|
COUPON_DELETE = "Coupon.delete",
|
||||||
|
|
||||||
///// note
|
///// note
|
||||||
|
|
||||||
NOTES_EDIT = "notes.edit",
|
NOTES_EDIT = "notes.edit",
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ export enum ABILITIES_ENUM {
|
||||||
SETTING = "setting",
|
SETTING = "setting",
|
||||||
Email = "email",
|
Email = "email",
|
||||||
Phone = "phone",
|
Phone = "phone",
|
||||||
|
COUPON = "coupon",
|
||||||
CITY = "city",
|
CITY = "city",
|
||||||
AREA = "area",
|
AREA = "area",
|
||||||
Financial_Collection = "financial_collection"
|
Financial_Collection = "financial_collection"
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
"Email_is_required": "البريد الإلكتروني مطلوب",
|
"Email_is_required": "البريد الإلكتروني مطلوب",
|
||||||
"Password_is_required": "كلمة المرور مطلوبة",
|
"Password_is_required": "كلمة المرور مطلوبة",
|
||||||
"Password_must_be_at_least_8_characters_long": "يجب أن تكون كلمة المرور مكونة من 8 أحرف على الأقل",
|
"Password_must_be_at_least_8_characters_long": "يجب أن تكون كلمة المرور مكونة من 8 أحرف على الأقل",
|
||||||
|
"must_be_at_least_6_characters_long": "يجب أن تكون مكونة من 6 أحرف على الأقل",
|
||||||
|
|
||||||
"Nationality_is_required": "الجنسية مطلوبة",
|
"Nationality_is_required": "الجنسية مطلوبة",
|
||||||
"Address_is_required": "العنوان مطلوب",
|
"Address_is_required": "العنوان مطلوب",
|
||||||
"Place_of_birth_is_required": "مكان الميلاد مطلوب",
|
"Place_of_birth_is_required": "مكان الميلاد مطلوب",
|
||||||
|
|
@ -409,6 +411,7 @@
|
||||||
"City":"مدينة",
|
"City":"مدينة",
|
||||||
"add_sales":"إضافة عملية بيع",
|
"add_sales":"إضافة عملية بيع",
|
||||||
"are_you_sure_about_sale":"هل أنت متأكد من عملية البيع ؟",
|
"are_you_sure_about_sale":"هل أنت متأكد من عملية البيع ؟",
|
||||||
|
"Coupon":"قسيمة",
|
||||||
"financial_collection":"التحصيلات",
|
"financial_collection":"التحصيلات",
|
||||||
"show_collection":"حصيلة"
|
"show_collection":"حصيلة"
|
||||||
},
|
},
|
||||||
|
|
@ -545,7 +548,10 @@
|
||||||
"lat":"الطول",
|
"lat":"الطول",
|
||||||
"lng":"العرض",
|
"lng":"العرض",
|
||||||
"choose":"حدد",
|
"choose":"حدد",
|
||||||
"amount":"مبلغ",
|
"tag":"كلمات مفتاحية",
|
||||||
|
"code":"رمز",
|
||||||
|
"amount":"كمية",
|
||||||
|
"due_to":"صالح الى",
|
||||||
"reseller":"البائعين",
|
"reseller":"البائعين",
|
||||||
"activation_date":"تاريخ التنشيط",
|
"activation_date":"تاريخ التنشيط",
|
||||||
"expiration_date":"تاريخ الالغاء"
|
"expiration_date":"تاريخ الالغاء"
|
||||||
|
|
@ -886,6 +892,7 @@
|
||||||
"collections": "التحصيلات",
|
"collections": "التحصيلات",
|
||||||
"Area":"المنطقة",
|
"Area":"المنطقة",
|
||||||
"city":"مدينة",
|
"city":"مدينة",
|
||||||
|
"coupon":"قسيمة",
|
||||||
"financial_collection":"التحصيلات"
|
"financial_collection":"التحصيلات"
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
|
|
@ -936,6 +943,7 @@
|
||||||
"Area":"المنطقة",
|
"Area":"المنطقة",
|
||||||
"setting":"الإعدادات",
|
"setting":"الإعدادات",
|
||||||
"edit_reseller":"تعديل البائع",
|
"edit_reseller":"تعديل البائع",
|
||||||
|
"Coupon":"قسيمة",
|
||||||
"financial_collection":"التحصيلات",
|
"financial_collection":"التحصيلات",
|
||||||
"show_collection":"حصيلة"
|
"show_collection":"حصيلة"
|
||||||
},
|
},
|
||||||
|
|
@ -987,6 +995,7 @@
|
||||||
"setting":"الإعدادات",
|
"setting":"الإعدادات",
|
||||||
"City":"مدينة",
|
"City":"مدينة",
|
||||||
"Area":"المنطقة",
|
"Area":"المنطقة",
|
||||||
|
"Coupon":"قسيمة",
|
||||||
"financial_collection":"التحصيلات",
|
"financial_collection":"التحصيلات",
|
||||||
"show_collection":"حصيلة"
|
"show_collection":"حصيلة"
|
||||||
},
|
},
|
||||||
|
|
@ -1005,6 +1014,7 @@
|
||||||
"security_setting":"إعدادات الأمان",
|
"security_setting":"إعدادات الأمان",
|
||||||
"Area":"المنطقة",
|
"Area":"المنطقة",
|
||||||
"City":"مدينة",
|
"City":"مدينة",
|
||||||
|
"Coupon":"قسيمة",
|
||||||
"notification":"الاشعارات",
|
"notification":"الاشعارات",
|
||||||
"upload_your_photo_and_personal_data_here":"قم بتحميل صورتك وبياناتك الشخصية هنا",
|
"upload_your_photo_and_personal_data_here":"قم بتحميل صورتك وبياناتك الشخصية هنا",
|
||||||
"get_notified_of_whats_happening_now_you_can_turn_it_off_at_any_time":"احصل على إشعار بما يحدث الآن ، يمكنك إيقاف تشغيله في أي وقت",
|
"get_notified_of_whats_happening_now_you_can_turn_it_off_at_any_time":"احصل على إشعار بما يحدث الآن ، يمكنك إيقاف تشغيله في أي وقت",
|
||||||
|
|
|
||||||
21
src/types/Coupon.ts
Normal file
21
src/types/Coupon.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Nullable } from "./App";
|
||||||
|
|
||||||
|
// Define the Teacher interface
|
||||||
|
|
||||||
|
export interface InitialValues {
|
||||||
|
id: number; // Unique identifier for the user
|
||||||
|
name: string; // Name of the user
|
||||||
|
amount: string; // URL of the user's amount
|
||||||
|
due_to: any; // URL of the user's amount
|
||||||
|
code: string; // URL of the user's amount
|
||||||
|
grade_id: string; // URL of the user's amount
|
||||||
|
}
|
||||||
|
export type Coupon = {
|
||||||
|
id: number; // Unique identifier for the user
|
||||||
|
name: string; // Name of the user
|
||||||
|
amount: string; // URL of the user's amount
|
||||||
|
due_to: string; // URL of the user's amount
|
||||||
|
code: string; // URL of the user's amount
|
||||||
|
grade_id: string; // URL of the user's amount
|
||||||
|
};
|
||||||
|
export type CouponInitialValues = Partial<Nullable<InitialValues>>;
|
||||||
|
|
@ -24,6 +24,31 @@ export const canIndexEduClass = hasAbility(
|
||||||
ABILITIES_VALUES_ENUM.INDEX,
|
ABILITIES_VALUES_ENUM.INDEX,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
///// Coupon
|
||||||
|
|
||||||
|
export const canAddCoupon = hasAbility(
|
||||||
|
ABILITIES_ENUM.EDUCATION_CLASS,
|
||||||
|
ABILITIES_VALUES_ENUM.STORE,
|
||||||
|
);
|
||||||
|
export const canEditCoupon = hasAbility(
|
||||||
|
ABILITIES_ENUM.EDUCATION_CLASS,
|
||||||
|
ABILITIES_VALUES_ENUM.UPDATE,
|
||||||
|
);
|
||||||
|
export const canDeleteCoupon = hasAbility(
|
||||||
|
ABILITIES_ENUM.EDUCATION_CLASS,
|
||||||
|
ABILITIES_VALUES_ENUM.DELETE,
|
||||||
|
);
|
||||||
|
export const canShowCoupon = hasAbility(
|
||||||
|
ABILITIES_ENUM.EDUCATION_CLASS,
|
||||||
|
ABILITIES_VALUES_ENUM.SHOW,
|
||||||
|
);
|
||||||
|
export const canIndexCoupon = hasAbility(
|
||||||
|
ABILITIES_ENUM.EDUCATION_CLASS,
|
||||||
|
ABILITIES_VALUES_ENUM.INDEX,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///// City
|
///// City
|
||||||
|
|
||||||
export const canAddCity = hasAbility(
|
export const canAddCity = hasAbility(
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,13 @@ export default defineConfig(() => {
|
||||||
return {
|
return {
|
||||||
build: {
|
build: {
|
||||||
outDir: "build",
|
outDir: "build",
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
entryFileNames: '[name].[hash].js',
|
||||||
|
chunkFileNames: '[name].[hash].js',
|
||||||
|
assetFileNames: '[name].[hash][extname]',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user