format
This commit is contained in:
parent
1a78474120
commit
398d1e8f07
8739
pnpm-lock.yaml
8739
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,42 +1,37 @@
|
||||||
.ImageBoxField{
|
.ImageBoxField {
|
||||||
|
.ImageBox {
|
||||||
.ImageBox{
|
width: 120px;
|
||||||
width: 120px;
|
height: 120px;
|
||||||
height: 120px;
|
display: flex;
|
||||||
display: flex;
|
align-items: center;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
justify-content: center;
|
border: max(1.5px, 0.1vw) dashed #a9c3f1;
|
||||||
border: max(1.5px,.1vw) dashed #a9c3f1;
|
margin-block: 10px;
|
||||||
margin-block: 10px;
|
border-radius: 5px;
|
||||||
border-radius: 5px;
|
.ImageBoxIcon {
|
||||||
.ImageBoxIcon{
|
cursor: pointer;
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.imagePreview{
|
|
||||||
max-width: 99%;
|
|
||||||
height: auto;
|
|
||||||
max-height: 99%;
|
|
||||||
object-fit: contain;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
.ImageHeader{
|
.imagePreview {
|
||||||
display: flex;
|
max-width: 99%;
|
||||||
align-items: center;
|
height: auto;
|
||||||
justify-content: flex-end;
|
max-height: 99%;
|
||||||
gap: 10px;
|
object-fit: contain;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.ImageHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.ImageCancelIcon{
|
.ImageCancelIcon {
|
||||||
width: 16px !important;
|
width: 16px !important;
|
||||||
height: 16px !important;
|
height: 16px !important;
|
||||||
}
|
}
|
||||||
.ImageBoxIcon{
|
.ImageBoxIcon {
|
||||||
width: 20px !important;
|
width: 20px !important;
|
||||||
height: 20px !important;
|
height: 20px !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useFormikContext } from "formik";
|
import { useFormikContext } from "formik";
|
||||||
import { useState, useRef, useEffect } from "react";
|
import { useState, useRef, useEffect } from "react";
|
||||||
import './ImageBoxField.scss';
|
import "./ImageBoxField.scss";
|
||||||
import ImageIcon from "./ImageIcon";
|
import ImageIcon from "./ImageIcon";
|
||||||
import ImageCancelIcon from "./ImageCancelIcon";
|
import ImageCancelIcon from "./ImageCancelIcon";
|
||||||
import { getNestedValue } from "../../../utils/getNestedValue";
|
import { getNestedValue } from "../../../utils/getNestedValue";
|
||||||
|
|
@ -8,21 +8,20 @@ import { generateImagePreview } from "./generateImagePreview";
|
||||||
|
|
||||||
// Helper function to generate image preview from a File
|
// Helper function to generate image preview from a File
|
||||||
|
|
||||||
|
|
||||||
const ImageBoxField = ({ name }: any) => {
|
const ImageBoxField = ({ name }: any) => {
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const value = getNestedValue(formik.values, name);
|
const value = getNestedValue(formik.values, name);
|
||||||
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||||
console.log(formik.values);
|
console.log(formik.values);
|
||||||
|
|
||||||
console.log(value,name);
|
console.log(value, name);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value instanceof File) {
|
if (value instanceof File) {
|
||||||
generateImagePreview(value, setImagePreview);
|
generateImagePreview(value, setImagePreview);
|
||||||
} else if (typeof value === 'string') {
|
} else if (typeof value === "string") {
|
||||||
setImagePreview(value);
|
setImagePreview(value);
|
||||||
} else {
|
} else {
|
||||||
setImagePreview(null);
|
setImagePreview(null);
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +30,7 @@ const ImageBoxField = ({ name }: any) => {
|
||||||
const handleFileChange = (event: any) => {
|
const handleFileChange = (event: any) => {
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
generateImagePreview(file, setImagePreview);
|
generateImagePreview(file, setImagePreview);
|
||||||
formik.setFieldValue(name, file);
|
formik.setFieldValue(name, file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -46,7 +45,7 @@ const ImageBoxField = ({ name }: any) => {
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setImagePreview("");
|
setImagePreview("");
|
||||||
formik.setFieldValue(name, "");
|
formik.setFieldValue(name, "");
|
||||||
|
|
||||||
if (fileInputRef.current) {
|
if (fileInputRef.current) {
|
||||||
fileInputRef.current.value = "";
|
fileInputRef.current.value = "";
|
||||||
}
|
}
|
||||||
|
|
@ -57,13 +56,14 @@ const ImageBoxField = ({ name }: any) => {
|
||||||
<div className="ImageHeader">
|
<div className="ImageHeader">
|
||||||
{imagePreview ? (
|
{imagePreview ? (
|
||||||
<>
|
<>
|
||||||
<ImageCancelIcon onClick={handleCancel} className="ImageCancelIcon" />
|
<ImageCancelIcon
|
||||||
|
onClick={handleCancel}
|
||||||
|
className="ImageCancelIcon"
|
||||||
|
/>
|
||||||
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="VisibleHidden">
|
<div className="VisibleHidden">hidden</div>
|
||||||
hidden
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="ImageBox">
|
<div className="ImageBox">
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,18 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
interface ImageCancelIconProps extends React.HTMLAttributes<HTMLDivElement> {
|
interface ImageCancelIconProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||||
}
|
|
||||||
|
|
||||||
const ImageCancelIcon: React.FC<ImageCancelIconProps> = (props) => {
|
const ImageCancelIcon: React.FC<ImageCancelIconProps> = (props) => {
|
||||||
return (
|
return (
|
||||||
<div {...props}>
|
<div {...props}>
|
||||||
<svg
|
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
viewBox="0 0 14 14"
|
<path
|
||||||
fill="none"
|
d="M7 5.44469L12.4447 0L14 1.55531L8.55531 7L14 12.4447L12.4436 14L6.9989 8.55531L1.55531 14L0 12.4436L5.44469 6.9989L0 1.55421L1.55531 0.00109986L7 5.44469Z"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
fill="#515B73"
|
||||||
>
|
/>
|
||||||
<path
|
</svg>
|
||||||
d="M7 5.44469L12.4447 0L14 1.55531L8.55531 7L14 12.4447L12.4436 14L6.9989 8.55531L1.55531 14L0 12.4436L5.44469 6.9989L0 1.55421L1.55531 0.00109986L7 5.44469Z"
|
</div>
|
||||||
fill="#515B73"
|
);
|
||||||
/>
|
};
|
||||||
</svg>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ImageCancelIcon;
|
export default ImageCancelIcon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,18 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
interface ImageIconProps extends React.HTMLAttributes<HTMLDivElement> {
|
interface ImageIconProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||||
}
|
|
||||||
|
|
||||||
const ImageIcon: React.FC<ImageIconProps> = (props) => {
|
const ImageIcon: React.FC<ImageIconProps> = (props) => {
|
||||||
return (
|
return (
|
||||||
<div {...props}>
|
<div {...props}>
|
||||||
<svg
|
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
viewBox="0 0 20 20"
|
d="M11.25 5.625C11.25 7.11684 10.6574 8.54758 9.60248 9.60248C8.54758 10.6574 7.11684 11.25 5.625 11.25C4.13316 11.25 2.70242 10.6574 1.64752 9.60248C0.592632 8.54758 0 7.11684 0 5.625C0 4.13316 0.592632 2.70242 1.64752 1.64752C2.70242 0.592632 4.13316 0 5.625 0C7.11684 0 8.54758 0.592632 9.60248 1.64752C10.6574 2.70242 11.25 4.13316 11.25 5.625ZM6.25 3.125C6.25 2.95924 6.18415 2.80027 6.06694 2.68306C5.94973 2.56585 5.79076 2.5 5.625 2.5C5.45924 2.5 5.30027 2.56585 5.18306 2.68306C5.06585 2.80027 5 2.95924 5 3.125V5H3.125C2.95924 5 2.80027 5.06585 2.68306 5.18306C2.56585 5.30027 2.5 5.45924 2.5 5.625C2.5 5.79076 2.56585 5.94973 2.68306 6.06694C2.80027 6.18415 2.95924 6.25 3.125 6.25H5V8.125C5 8.29076 5.06585 8.44973 5.18306 8.56694C5.30027 8.68415 5.45924 8.75 5.625 8.75C5.79076 8.75 5.94973 8.68415 6.06694 8.56694C6.18415 8.44973 6.25 8.29076 6.25 8.125V6.25H8.125C8.29076 6.25 8.44973 6.18415 8.56694 6.06694C8.68415 5.94973 8.75 5.79076 8.75 5.625C8.75 5.45924 8.68415 5.30027 8.56694 5.18306C8.44973 5.06585 8.29076 5 8.125 5H6.25V3.125ZM16.25 3.75H12.2413C12.1187 3.3183 11.9542 2.89964 11.75 2.5H16.25C17.2446 2.5 18.1984 2.89509 18.9017 3.59835C19.6049 4.30161 20 5.25544 20 6.25V16.25C20 17.2446 19.6049 18.1984 18.9017 18.9017C18.1984 19.6049 17.2446 20 16.25 20H6.25C5.25544 20 4.30161 19.6049 3.59835 18.9017C2.89509 18.1984 2.5 17.2446 2.5 16.25V11.75C2.89667 11.9533 3.31333 12.1171 3.75 12.2413V16.25C3.75 16.7162 3.8775 17.1525 4.1 17.525L9.93625 11.79C10.2869 11.4457 10.7586 11.2528 11.25 11.2528C11.7414 11.2528 12.2131 11.4457 12.5637 11.79L18.4012 17.525C18.6298 17.139 18.7502 16.6986 18.75 16.25V6.25C18.75 5.58696 18.4866 4.95107 18.0178 4.48223C17.5489 4.01339 16.913 3.75 16.25 3.75ZM16.25 8.125C16.25 8.37123 16.2015 8.61505 16.1073 8.84253C16.013 9.07002 15.8749 9.27672 15.7008 9.45083C15.5267 9.62494 15.32 9.76305 15.0925 9.85727C14.865 9.9515 14.6212 10 14.375 10C14.1288 10 13.885 9.9515 13.6575 9.85727C13.43 9.76305 13.2233 9.62494 13.0492 9.45083C12.8751 9.27672 12.737 9.07002 12.6427 8.84253C12.5485 8.61505 12.5 8.37123 12.5 8.125C12.5 7.62772 12.6975 7.15081 13.0492 6.79917C13.4008 6.44754 13.8777 6.25 14.375 6.25C14.8723 6.25 15.3492 6.44754 15.7008 6.79917C16.0525 7.15081 16.25 7.62772 16.25 8.125ZM15 8.125C15 7.95924 14.9342 7.80027 14.8169 7.68306C14.6997 7.56585 14.5408 7.5 14.375 7.5C14.2092 7.5 14.0503 7.56585 13.9331 7.68306C13.8158 7.80027 13.75 7.95924 13.75 8.125C13.75 8.29076 13.8158 8.44973 13.9331 8.56694C14.0503 8.68415 14.2092 8.75 14.375 8.75C14.5408 8.75 14.6997 8.68415 14.8169 8.56694C14.9342 8.44973 15 8.29076 15 8.125ZM4.985 18.4075C5.36871 18.6321 5.80538 18.7504 6.25 18.75H16.25C16.7125 18.75 17.1437 18.625 17.515 18.4075L11.6875 12.6825C11.5707 12.568 11.4136 12.5038 11.25 12.5038C11.0864 12.5038 10.9293 12.568 10.8125 12.6825L4.985 18.4075Z"
|
||||||
fill="none"
|
fill="#515B73"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
/>
|
||||||
>
|
</svg>
|
||||||
<path
|
</div>
|
||||||
d="M11.25 5.625C11.25 7.11684 10.6574 8.54758 9.60248 9.60248C8.54758 10.6574 7.11684 11.25 5.625 11.25C4.13316 11.25 2.70242 10.6574 1.64752 9.60248C0.592632 8.54758 0 7.11684 0 5.625C0 4.13316 0.592632 2.70242 1.64752 1.64752C2.70242 0.592632 4.13316 0 5.625 0C7.11684 0 8.54758 0.592632 9.60248 1.64752C10.6574 2.70242 11.25 4.13316 11.25 5.625ZM6.25 3.125C6.25 2.95924 6.18415 2.80027 6.06694 2.68306C5.94973 2.56585 5.79076 2.5 5.625 2.5C5.45924 2.5 5.30027 2.56585 5.18306 2.68306C5.06585 2.80027 5 2.95924 5 3.125V5H3.125C2.95924 5 2.80027 5.06585 2.68306 5.18306C2.56585 5.30027 2.5 5.45924 2.5 5.625C2.5 5.79076 2.56585 5.94973 2.68306 6.06694C2.80027 6.18415 2.95924 6.25 3.125 6.25H5V8.125C5 8.29076 5.06585 8.44973 5.18306 8.56694C5.30027 8.68415 5.45924 8.75 5.625 8.75C5.79076 8.75 5.94973 8.68415 6.06694 8.56694C6.18415 8.44973 6.25 8.29076 6.25 8.125V6.25H8.125C8.29076 6.25 8.44973 6.18415 8.56694 6.06694C8.68415 5.94973 8.75 5.79076 8.75 5.625C8.75 5.45924 8.68415 5.30027 8.56694 5.18306C8.44973 5.06585 8.29076 5 8.125 5H6.25V3.125ZM16.25 3.75H12.2413C12.1187 3.3183 11.9542 2.89964 11.75 2.5H16.25C17.2446 2.5 18.1984 2.89509 18.9017 3.59835C19.6049 4.30161 20 5.25544 20 6.25V16.25C20 17.2446 19.6049 18.1984 18.9017 18.9017C18.1984 19.6049 17.2446 20 16.25 20H6.25C5.25544 20 4.30161 19.6049 3.59835 18.9017C2.89509 18.1984 2.5 17.2446 2.5 16.25V11.75C2.89667 11.9533 3.31333 12.1171 3.75 12.2413V16.25C3.75 16.7162 3.8775 17.1525 4.1 17.525L9.93625 11.79C10.2869 11.4457 10.7586 11.2528 11.25 11.2528C11.7414 11.2528 12.2131 11.4457 12.5637 11.79L18.4012 17.525C18.6298 17.139 18.7502 16.6986 18.75 16.25V6.25C18.75 5.58696 18.4866 4.95107 18.0178 4.48223C17.5489 4.01339 16.913 3.75 16.25 3.75ZM16.25 8.125C16.25 8.37123 16.2015 8.61505 16.1073 8.84253C16.013 9.07002 15.8749 9.27672 15.7008 9.45083C15.5267 9.62494 15.32 9.76305 15.0925 9.85727C14.865 9.9515 14.6212 10 14.375 10C14.1288 10 13.885 9.9515 13.6575 9.85727C13.43 9.76305 13.2233 9.62494 13.0492 9.45083C12.8751 9.27672 12.737 9.07002 12.6427 8.84253C12.5485 8.61505 12.5 8.37123 12.5 8.125C12.5 7.62772 12.6975 7.15081 13.0492 6.79917C13.4008 6.44754 13.8777 6.25 14.375 6.25C14.8723 6.25 15.3492 6.44754 15.7008 6.79917C16.0525 7.15081 16.25 7.62772 16.25 8.125ZM15 8.125C15 7.95924 14.9342 7.80027 14.8169 7.68306C14.6997 7.56585 14.5408 7.5 14.375 7.5C14.2092 7.5 14.0503 7.56585 13.9331 7.68306C13.8158 7.80027 13.75 7.95924 13.75 8.125C13.75 8.29076 13.8158 8.44973 13.9331 8.56694C14.0503 8.68415 14.2092 8.75 14.375 8.75C14.5408 8.75 14.6997 8.68415 14.8169 8.56694C14.9342 8.44973 15 8.29076 15 8.125ZM4.985 18.4075C5.36871 18.6321 5.80538 18.7504 6.25 18.75H16.25C16.7125 18.75 17.1437 18.625 17.515 18.4075L11.6875 12.6825C11.5707 12.568 11.4136 12.5038 11.25 12.5038C11.0864 12.5038 10.9293 12.568 10.8125 12.6825L4.985 18.4075Z"
|
);
|
||||||
fill="#515B73"
|
};
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ImageIcon;
|
export default ImageIcon;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
export const generateImagePreview = (file: File, setImagePreview: (result: string) => void) => {
|
export const generateImagePreview = (
|
||||||
const reader = new FileReader();
|
file: File,
|
||||||
reader.onloadend = () => {
|
setImagePreview: (result: string) => void,
|
||||||
setImagePreview(reader.result as string);
|
) => {
|
||||||
};
|
const reader = new FileReader();
|
||||||
reader.readAsDataURL(file);
|
reader.onloadend = () => {
|
||||||
};
|
setImagePreview(reader.result as string);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,33 @@
|
||||||
import React, { useState, useMemo } from 'react';
|
import React, { useState, useMemo } from "react";
|
||||||
import { Select, Spin } from 'antd';
|
import { Select, Spin } from "antd";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { useDebounce } from '../../utils/useDebounce';
|
import { useDebounce } from "../../utils/useDebounce";
|
||||||
import { useGetAllTag } from '../../api/tags';
|
import { useGetAllTag } from "../../api/tags";
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from "formik";
|
||||||
|
|
||||||
const SelectTag: React.FC = () => {
|
const SelectTag: React.FC = () => {
|
||||||
const [searchValue, setSearchValue] = useState<string>('');
|
const [searchValue, setSearchValue] = useState<string>("");
|
||||||
const [fieldValue, setFieldValue] = useState<string>('');
|
const [fieldValue, setFieldValue] = useState<string>("");
|
||||||
const formik = useFormikContext<any>()
|
const formik = useFormikContext<any>();
|
||||||
const handleChange = (value: string[]) => {
|
const handleChange = (value: string[]) => {
|
||||||
console.log(value);
|
console.log(value);
|
||||||
|
|
||||||
formik.setFieldValue("tags",value)
|
|
||||||
setSearchValue('');
|
|
||||||
setFieldValue('');
|
|
||||||
|
|
||||||
|
formik.setFieldValue("tags", value);
|
||||||
|
setSearchValue("");
|
||||||
|
setFieldValue("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = useDebounce((value: string) => {
|
const handleSearch = useDebounce((value: string) => {
|
||||||
setSearchValue(value);
|
setSearchValue(value);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleFieldChange = (value: string) => {
|
const handleFieldChange = (value: string) => {
|
||||||
setFieldValue(value);
|
setFieldValue(value);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
setSearchValue('');
|
setSearchValue("");
|
||||||
setFieldValue('');
|
setFieldValue("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data, isLoading } = useGetAllTag({
|
const { data, isLoading } = useGetAllTag({
|
||||||
|
|
@ -39,38 +36,38 @@ const SelectTag: React.FC = () => {
|
||||||
|
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
const options = data?.data ?? []
|
const options = data?.data ?? [];
|
||||||
const additionalData = options?.length < 1 && searchValue.length > 1 && !isLoading ? [{id:`${searchValue}`,name:searchValue}] :[];
|
const additionalData =
|
||||||
|
options?.length < 1 && searchValue.length > 1 && !isLoading
|
||||||
|
? [{ id: `${searchValue}`, name: searchValue }]
|
||||||
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='SelectTag'>
|
<div className="SelectTag">
|
||||||
|
<label htmlFor="">{t("models.tag")}</label>
|
||||||
<label htmlFor="">
|
<Select
|
||||||
{t("models.tag")}
|
mode="multiple"
|
||||||
</label>
|
allowClear
|
||||||
<Select
|
style={{ width: "100%", height: "40px" }}
|
||||||
mode="multiple"
|
placeholder=""
|
||||||
allowClear
|
fieldNames={{ label: "name", value: "id" }}
|
||||||
style={{ width: '100%' ,height:"40px"}}
|
onChange={handleChange}
|
||||||
placeholder=""
|
options={[...options, ...additionalData]}
|
||||||
fieldNames={{ label: 'name', value: 'id' }}
|
filterOption={false}
|
||||||
onChange={handleChange}
|
loading={isLoading}
|
||||||
options={[...options,...additionalData]}
|
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
|
||||||
filterOption={false}
|
onSearch={(value) => {
|
||||||
loading={isLoading}
|
handleSearch(value);
|
||||||
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
|
handleFieldChange(value);
|
||||||
onSearch={(value) => {
|
}}
|
||||||
handleSearch(value);
|
searchValue={fieldValue}
|
||||||
handleFieldChange(value);
|
onDropdownVisibleChange={(open) => {
|
||||||
}}
|
if (!open) {
|
||||||
searchValue={fieldValue}
|
handleBlur();
|
||||||
onDropdownVisibleChange={(open) => {
|
}
|
||||||
if (!open) {
|
}}
|
||||||
handleBlur();
|
value={formik?.values?.tags ?? []}
|
||||||
}
|
/>
|
||||||
}}
|
|
||||||
value={formik?.values?.tags ?? []}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ interface Props {
|
||||||
options: Option[];
|
options: Option[];
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
onSelect?: (option: Option) => void;
|
onSelect?: (option: Option) => void;
|
||||||
withIcon?:boolean
|
withIcon?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SearchFieldWithSelect: React.FC<Props> = ({
|
const SearchFieldWithSelect: React.FC<Props> = ({
|
||||||
options,
|
options,
|
||||||
placeholder,
|
placeholder,
|
||||||
onSelect,
|
onSelect,
|
||||||
withIcon=false
|
withIcon = false,
|
||||||
}) => {
|
}) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
|
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
|
||||||
|
|
@ -60,8 +60,8 @@ const SearchFieldWithSelect: React.FC<Props> = ({
|
||||||
return (
|
return (
|
||||||
<div ref={node} className={`search-field ${isOpen ? "open" : ""}`}>
|
<div ref={node} className={`search-field ${isOpen ? "open" : ""}`}>
|
||||||
<div className="search-header" onClick={toggleDropdown}>
|
<div className="search-header" onClick={toggleDropdown}>
|
||||||
{withIcon && <IoSearch className="search__icon" />}
|
{withIcon && <IoSearch className="search__icon" />}
|
||||||
|
|
||||||
{/* <p className="search__input_text">{placeholder}</p> */}
|
{/* <p className="search__input_text">{placeholder}</p> */}
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,58 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import { Divider, Select } from 'antd';
|
import { Divider, Select } from "antd";
|
||||||
import SearchFieldWithSelect from '../../Components/DataTable/SearchFieldWithSelect';
|
import SearchFieldWithSelect from "../../Components/DataTable/SearchFieldWithSelect";
|
||||||
import { translateOptions } from '../../utils/translatedOptions';
|
import { translateOptions } from "../../utils/translatedOptions";
|
||||||
import { search_array } from '../../Routes';
|
import { search_array } from "../../Routes";
|
||||||
import { useFilterStateState } from '../../zustand/Filter';
|
import { useFilterStateState } from "../../zustand/Filter";
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from "react-router-dom";
|
||||||
import { TbReorder } from "react-icons/tb";
|
import { TbReorder } from "react-icons/tb";
|
||||||
|
|
||||||
const OrderBySelect = () => {
|
const OrderBySelect = () => {
|
||||||
const {t} = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { Filter, setFilter } = useFilterStateState();
|
const { Filter, setFilter } = useFilterStateState();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
const type_param = searchParams.get('type');
|
|
||||||
const [type, setType] = useState(type_param);
|
|
||||||
const translateArray = translateOptions(search_array, t);
|
|
||||||
const handleChange = (value: string) => {
|
|
||||||
const newArray = Filter?.filter((item: any) => item.select !== true);
|
|
||||||
setFilter([
|
|
||||||
...newArray,
|
|
||||||
{ name: value, index: Filter.length, select: true },
|
|
||||||
]);
|
|
||||||
if (type_param) {
|
|
||||||
searchParams.delete('type');
|
|
||||||
setSearchParams(searchParams);
|
|
||||||
}
|
|
||||||
setType(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// send this with api request
|
const type_param = searchParams.get("type");
|
||||||
// type: type,
|
const [type, setType] = useState(type_param);
|
||||||
// page: currentPage,
|
const translateArray = translateOptions(search_array, t);
|
||||||
|
const handleChange = (value: string) => {
|
||||||
|
const newArray = Filter?.filter((item: any) => item.select !== true);
|
||||||
|
setFilter([
|
||||||
|
...newArray,
|
||||||
|
{ name: value, index: Filter.length, select: true },
|
||||||
|
]);
|
||||||
|
if (type_param) {
|
||||||
|
searchParams.delete("type");
|
||||||
|
setSearchParams(searchParams);
|
||||||
|
}
|
||||||
|
setType(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// send this with api request
|
||||||
|
// type: type,
|
||||||
|
// page: currentPage,
|
||||||
return (
|
return (
|
||||||
<div className='order_by_filter'>
|
<div className="order_by_filter">
|
||||||
<Select
|
<Select
|
||||||
className='order_by_select'
|
className="order_by_select"
|
||||||
style={{ width: 200 }}
|
style={{ width: 200 }}
|
||||||
size="large"
|
size="large"
|
||||||
placeholder={<div><TbReorder className='addition_select_icon'/> {t("ترتيب حسب")} </div>}
|
placeholder={
|
||||||
onChange={handleChange}
|
<div>
|
||||||
options={[
|
<TbReorder className="addition_select_icon" /> {t("ترتيب حسب")}{" "}
|
||||||
{ value: "تصاعديا", label: t("تصاعديا") },
|
</div>
|
||||||
{ value: "تنازليا", label: t("تنازليا") },
|
}
|
||||||
{ value: "شوهدت مؤخرا", label: t("شوهدت مؤخرا") },
|
onChange={handleChange}
|
||||||
{ value: "وصلت مؤخرا", label: t("وصلت مؤخرا") },
|
options={[
|
||||||
]}
|
{ value: "تصاعديا", label: t("تصاعديا") },
|
||||||
/>
|
{ value: "تنازليا", label: t("تنازليا") },
|
||||||
|
{ value: "شوهدت مؤخرا", label: t("شوهدت مؤخرا") },
|
||||||
|
{ value: "وصلت مؤخرا", label: t("وصلت مؤخرا") },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default OrderBySelect
|
export default OrderBySelect;
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,54 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import { Divider, Select } from 'antd';
|
import { Divider, Select } from "antd";
|
||||||
import SearchFieldWithSelect from '../../Components/DataTable/SearchFieldWithSelect';
|
import SearchFieldWithSelect from "../../Components/DataTable/SearchFieldWithSelect";
|
||||||
import { translateOptions } from '../../utils/translatedOptions';
|
import { translateOptions } from "../../utils/translatedOptions";
|
||||||
import { search_array } from '../../Routes';
|
import { search_array } from "../../Routes";
|
||||||
import { useFilterStateState } from '../../zustand/Filter';
|
import { useFilterStateState } from "../../zustand/Filter";
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
const PaginationColumn = () => {
|
const PaginationColumn = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { Filter, setFilter } = useFilterStateState();
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
const {t} = useTranslation();
|
const type_param = searchParams.get("type");
|
||||||
const { Filter, setFilter } = useFilterStateState();
|
const [type, setType] = useState(type_param);
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const translateArray = translateOptions(search_array, t);
|
||||||
|
const handleChange = (value: string) => {
|
||||||
const type_param = searchParams.get('type');
|
const newArray = Filter?.filter((item: any) => item.select !== true);
|
||||||
const [type, setType] = useState(type_param);
|
setFilter([
|
||||||
const translateArray = translateOptions(search_array, t);
|
...newArray,
|
||||||
const handleChange = (value: string) => {
|
{ name: value, index: Filter.length, select: true },
|
||||||
const newArray = Filter?.filter((item: any) => item.select !== true);
|
]);
|
||||||
setFilter([
|
if (type_param) {
|
||||||
...newArray,
|
searchParams.delete("type");
|
||||||
{ name: value, index: Filter.length, select: true },
|
setSearchParams(searchParams);
|
||||||
]);
|
}
|
||||||
if (type_param) {
|
setType(value);
|
||||||
searchParams.delete('type');
|
};
|
||||||
setSearchParams(searchParams);
|
|
||||||
}
|
|
||||||
setType(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// send this with api request
|
// send this with api request
|
||||||
// type: type,
|
// type: type,
|
||||||
// page: currentPage,
|
// page: currentPage,
|
||||||
return (
|
return (
|
||||||
<div className='pagination_column'>
|
<div className="pagination_column">
|
||||||
<Select
|
<Select
|
||||||
className='pagination_select'
|
className="pagination_select"
|
||||||
style={{ width: 70 }}
|
style={{ width: 70 }}
|
||||||
size="large"
|
size="large"
|
||||||
defaultValue={"10"}
|
defaultValue={"10"}
|
||||||
placeholder={"10"}
|
placeholder={"10"}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
options={[
|
options={[
|
||||||
{ value: "10", label: t("10") },
|
{ value: "10", label: t("10") },
|
||||||
{ value: "20", label: t("20") },
|
{ value: "20", label: t("20") },
|
||||||
{ value: "50", label: t("50") },
|
{ value: "50", label: t("50") },
|
||||||
{ value: "100", label: t("100") },
|
{ value: "100", label: t("100") },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default PaginationColumn
|
export default PaginationColumn;
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,28 @@ const NavBarRightSide = () => {
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<article>
|
<article>
|
||||||
|
|
||||||
<span className="header_icons">
|
<span className="header_icons">
|
||||||
<TooltipComp note="change_language" color="#E0E0E0" icon={<TbWorld size={25}/>}/>
|
<TooltipComp
|
||||||
<TooltipComp note="add" color="#E0E0E0" icon={<CiCirclePlus size={25}/>}/>
|
note="change_language"
|
||||||
<TooltipComp className="NotificationsIcon" note="notification" color="#E0E0E0" icon={< > <IoIosNotificationsOutline size={25} /> </>}/>
|
color="#E0E0E0"
|
||||||
|
icon={<TbWorld size={25} />}
|
||||||
|
/>
|
||||||
|
<TooltipComp
|
||||||
|
note="add"
|
||||||
|
color="#E0E0E0"
|
||||||
|
icon={<CiCirclePlus size={25} />}
|
||||||
|
/>
|
||||||
|
<TooltipComp
|
||||||
|
className="NotificationsIcon"
|
||||||
|
note="notification"
|
||||||
|
color="#E0E0E0"
|
||||||
|
icon={
|
||||||
|
<>
|
||||||
|
{" "}
|
||||||
|
<IoIosNotificationsOutline size={25} />{" "}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<div className="header_profile">
|
<div className="header_profile">
|
||||||
{/* <span>
|
{/* <span>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,21 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import { Tooltip } from "antd";
|
import { Tooltip } from "antd";
|
||||||
import { ModalEnum } from '../../../enums/Model';
|
import { ModalEnum } from "../../../enums/Model";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { CiCirclePlus } from 'react-icons/ci';
|
import { CiCirclePlus } from "react-icons/ci";
|
||||||
import useModalHandler from '../../../utils/useModalHandler';
|
import useModalHandler from "../../../utils/useModalHandler";
|
||||||
|
|
||||||
const TooltipComp = ({note,color,icon,className=""}:{note:string,color:string,icon:any,className?:string}) => {
|
|
||||||
|
|
||||||
|
const TooltipComp = ({
|
||||||
|
note,
|
||||||
|
color,
|
||||||
|
icon,
|
||||||
|
className = "",
|
||||||
|
}: {
|
||||||
|
note: string;
|
||||||
|
color: string;
|
||||||
|
icon: any;
|
||||||
|
className?: string;
|
||||||
|
}) => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
|
|
||||||
|
|
@ -15,21 +24,15 @@ const TooltipComp = ({note,color,icon,className=""}:{note:string,color:string,ic
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
placement="top"
|
placement="top"
|
||||||
title={
|
title={<div onClick={handleEdit}>{t(`header.${note}`)}</div>}
|
||||||
<div onClick={handleEdit}>
|
color={color}
|
||||||
{t(`header.${note}`)}
|
>
|
||||||
</div>
|
<div className={`gear `}>{icon}</div>
|
||||||
}
|
</Tooltip>
|
||||||
color={color}
|
|
||||||
>
|
|
||||||
<div className={`gear `}>
|
|
||||||
{icon}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default TooltipComp
|
export default TooltipComp;
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,23 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
|
||||||
>
|
>
|
||||||
<i>{item.icon}</i>
|
<i>{item.icon}</i>
|
||||||
{/* Conditionally render the text based on sidebar width */}
|
{/* Conditionally render the text based on sidebar width */}
|
||||||
<span style={{ display: isOpen === false ? 'none' : 'inline' }}>
|
<span style={{ display: isOpen === false ? "none" : "inline" }}>
|
||||||
{t(item.text)}
|
{t(item.text)}
|
||||||
</span>
|
</span>
|
||||||
{item?.children && (
|
{item?.children && (
|
||||||
<>
|
<>
|
||||||
{isDropdownOpen ? (
|
{isDropdownOpen ? (
|
||||||
<div className="DropDownIcon" onClick={() => handleDropdown(index)}>
|
<div
|
||||||
|
className="DropDownIcon"
|
||||||
|
onClick={() => handleDropdown(index)}
|
||||||
|
>
|
||||||
<MdExpandLess />
|
<MdExpandLess />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="DropDownIcon" onClick={() => handleDropdown(index)}>
|
<div
|
||||||
|
className="DropDownIcon"
|
||||||
|
onClick={() => handleDropdown(index)}
|
||||||
|
>
|
||||||
<MdExpandMore />
|
<MdExpandMore />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -47,11 +53,11 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
|
||||||
item={childItem}
|
item={childItem}
|
||||||
location={location}
|
location={location}
|
||||||
index={childIndex}
|
index={childIndex}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,11 +1,15 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import Lottie from 'lottie-react'; // Default import
|
import Lottie from "lottie-react"; // Default import
|
||||||
import animationData from './Loading.json'; // Import your Lottie JSON animation
|
import animationData from "./Loading.json"; // Import your Lottie JSON animation
|
||||||
|
|
||||||
const LoadingLottie = () => {
|
const LoadingLottie = () => {
|
||||||
return (
|
return (
|
||||||
<div className="cc">
|
<div className="cc">
|
||||||
<Lottie animationData={animationData} loop={true} style={{ width: 300, height: 300 }} />
|
<Lottie
|
||||||
|
animationData={animationData}
|
||||||
|
loop={true}
|
||||||
|
style={{ width: 300, height: 300 }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,11 +1,15 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import Lottie from 'lottie-react'; // Default import
|
import Lottie from "lottie-react"; // Default import
|
||||||
import animationData from './NotFound.json'; // Import your Lottie JSON animation
|
import animationData from "./NotFound.json"; // Import your Lottie JSON animation
|
||||||
|
|
||||||
const NotFoundLottie = () => {
|
const NotFoundLottie = () => {
|
||||||
return (
|
return (
|
||||||
<div className="cc">
|
<div className="cc">
|
||||||
<Lottie animationData={animationData} loop={true} style={{ width: 300, height: 300 }} />
|
<Lottie
|
||||||
|
animationData={animationData}
|
||||||
|
loop={true}
|
||||||
|
style={{ width: 300, height: 300 }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,7 @@ const ActionButtons: React.FC<ActionButtonsProps> = ({
|
||||||
|
|
||||||
{canDelete && (
|
{canDelete && (
|
||||||
// <Tooltip placement="top" title={t(deleteTooltipTitle)} color="#E0E0E0">
|
// <Tooltip placement="top" title={t(deleteTooltipTitle)} color="#E0E0E0">
|
||||||
<GoTrash
|
<GoTrash onClick={onDelete} size={22} style={{ color: "#A098AE" }} />
|
||||||
onClick={onDelete}
|
|
||||||
size={22}
|
|
||||||
style={{ color: "#A098AE" }}
|
|
||||||
/>
|
|
||||||
// </Tooltip>
|
// </Tooltip>
|
||||||
)}
|
)}
|
||||||
{canShow && (
|
{canShow && (
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,7 @@ const SearchField = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(AllPagesOption);
|
console.log(AllPagesOption);
|
||||||
console.log(option,"option");
|
console.log(option, "option");
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ValidationField w-100">
|
<div className="ValidationField w-100">
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ const SelectField = ({
|
||||||
onChange={onChange || SelectableChange}
|
onChange={onChange || SelectableChange}
|
||||||
showSearch={false}
|
showSearch={false}
|
||||||
id={name}
|
id={name}
|
||||||
fieldNames={{label:"name",value:"id"}}
|
fieldNames={{ label: "name", value: "id" }}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</ValidationFieldContainer>
|
</ValidationFieldContainer>
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// upload
|
//// upload
|
||||||
.ant-upload-select {
|
.ant-upload-select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-btn-default{
|
.ant-btn-default {
|
||||||
padding: 7px 11px;
|
padding: 7px 11px;
|
||||||
height: var(--fieldHeight);
|
height: var(--fieldHeight);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -35,39 +34,34 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// number input
|
//// number input
|
||||||
///
|
///
|
||||||
.ant-input-number-affix-wrapper-lg{
|
.ant-input-number-affix-wrapper-lg {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.ValidationFieldCheckbox{
|
.ValidationFieldCheckbox {
|
||||||
// background-color: red;
|
// background-color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// input hight
|
/// input hight
|
||||||
.ant-form-item-control-input-content{
|
.ant-form-item-control-input-content {
|
||||||
height: var(--fieldHeight);
|
height: var(--fieldHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// date picker
|
//// date picker
|
||||||
.ant-picker-large{
|
.ant-picker-large {
|
||||||
height: var(--fieldHeight);
|
height: var(--fieldHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// text area
|
||||||
|
///
|
||||||
|
|
||||||
/// text area
|
.ValidationFieldTextArea {
|
||||||
///
|
.ant-form-item-control-input-content {
|
||||||
|
|
||||||
.ValidationFieldTextArea{
|
|
||||||
.ant-form-item-control-input-content{
|
|
||||||
min-height: 120px;
|
min-height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-input-textarea-affix-wrapper.ant-input-affix-wrapper {
|
.ant-input-textarea-affix-wrapper.ant-input-affix-wrapper {
|
||||||
|
height: 120px;
|
||||||
height: 120px;
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ const Header = () => {
|
||||||
return (
|
return (
|
||||||
<header className="exercise_add_header mb-4">
|
<header className="exercise_add_header mb-4">
|
||||||
<article>
|
<article>
|
||||||
<img src="/Icon/QuestionIcon.svg" alt="" />
|
<img src="/Icon/QuestionIcon.svg" alt="" />
|
||||||
<div>
|
<div>
|
||||||
{t("practical.add")} {t("models.exercise")}{" "}
|
{t("practical.add")} {t("models.exercise")}{" "}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<div>
|
<div>
|
||||||
<GoArrowSwitch onClick={handleChange} className="m-2" />
|
<GoArrowSwitch onClick={handleChange} className="m-2" />
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,9 @@ const DeleteModels: React.FC<ModalFormProps> = ({
|
||||||
open={isOpen === ModelEnum}
|
open={isOpen === ModelEnum}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
>
|
>
|
||||||
<header>{t("practical.delete_this_item")}
|
<header>
|
||||||
<MdCancel onClick={handleCancel}/>
|
{t("practical.delete_this_item")}
|
||||||
|
<MdCancel onClick={handleCancel} />
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main className="main_modal">
|
<main className="main_modal">
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,70 @@
|
||||||
import { useState } from 'react'
|
import { useState } from "react";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import { Divider } from 'antd';
|
import { Divider } from "antd";
|
||||||
import SearchFieldWithSelect from '../../Components/DataTable/SearchFieldWithSelect';
|
import SearchFieldWithSelect from "../../Components/DataTable/SearchFieldWithSelect";
|
||||||
import { translateOptions } from '../../utils/translatedOptions';
|
import { translateOptions } from "../../utils/translatedOptions";
|
||||||
import { search_array } from '../../Routes';
|
import { search_array } from "../../Routes";
|
||||||
import PaginationColumn from '../../Components/Filter/PaginationColumn';
|
import PaginationColumn from "../../Components/Filter/PaginationColumn";
|
||||||
import OrderBySelect from '../../Components/Filter/OrderBySelect';
|
import OrderBySelect from "../../Components/Filter/OrderBySelect";
|
||||||
import LayoutFilterModal from './LayoutFilterModal';
|
import LayoutFilterModal from "./LayoutFilterModal";
|
||||||
import { BiFilterAlt } from 'react-icons/bi';
|
import { BiFilterAlt } from "react-icons/bi";
|
||||||
import { MdKeyboardArrowDown } from "react-icons/md";
|
import { MdKeyboardArrowDown } from "react-icons/md";
|
||||||
import SearchField from '../../Components/DataTable/SearchField';
|
import SearchField from "../../Components/DataTable/SearchField";
|
||||||
|
|
||||||
const FilterLayout = ({filterTitle, sub_children}:{filterTitle:string,sub_children:any}) => {
|
const FilterLayout = ({
|
||||||
const {t} = useTranslation();
|
filterTitle,
|
||||||
|
sub_children,
|
||||||
|
}: {
|
||||||
|
filterTitle: string;
|
||||||
|
sub_children: any;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const translateArray = translateOptions(search_array, t);
|
const translateArray = translateOptions(search_array, t);
|
||||||
const [isOpen, setIsOpen ] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
// send this with api request
|
// send this with api request
|
||||||
// type: type,
|
// type: type,
|
||||||
// page: currentPage,
|
// page: currentPage,
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='filter_header'>
|
|
||||||
<div className='filter_header_top'>
|
|
||||||
<h4>{t(filterTitle)}</h4>
|
|
||||||
<div className='filter_and_order_by'>
|
|
||||||
<span>
|
|
||||||
<LayoutFilterModal
|
|
||||||
ModelClassName='filter_model_direction'
|
|
||||||
children={<div className='model_sub_children'>{sub_children}</div>}
|
|
||||||
isOpen={isOpen} setIsOpen={setIsOpen}
|
|
||||||
/>
|
|
||||||
<div className='filter_button' onClick={()=> setIsOpen(true)}>
|
|
||||||
<span>
|
|
||||||
<BiFilterAlt className='addition_select_icon'/>
|
|
||||||
{t("ترتيب حسب")}
|
|
||||||
</span>
|
|
||||||
<MdKeyboardArrowDown/>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<span><OrderBySelect/></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Divider/>
|
|
||||||
<div className="filter_header_bottom">
|
|
||||||
<span>
|
|
||||||
<p>{t("صف لكل صفحة")}</p>
|
|
||||||
<PaginationColumn/>
|
|
||||||
<p>{t("ادخالات")}</p>
|
|
||||||
</span>
|
|
||||||
<div className="header_search">
|
|
||||||
<SearchField
|
|
||||||
searchBy=''
|
|
||||||
placeholder={t("practical.search_here")}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FilterLayout
|
return (
|
||||||
|
<div className="filter_header">
|
||||||
|
<div className="filter_header_top">
|
||||||
|
<h4>{t(filterTitle)}</h4>
|
||||||
|
<div className="filter_and_order_by">
|
||||||
|
<span>
|
||||||
|
<LayoutFilterModal
|
||||||
|
ModelClassName="filter_model_direction"
|
||||||
|
children={
|
||||||
|
<div className="model_sub_children">{sub_children}</div>
|
||||||
|
}
|
||||||
|
isOpen={isOpen}
|
||||||
|
setIsOpen={setIsOpen}
|
||||||
|
/>
|
||||||
|
<div className="filter_button" onClick={() => setIsOpen(true)}>
|
||||||
|
<span>
|
||||||
|
<BiFilterAlt className="addition_select_icon" />
|
||||||
|
{t("ترتيب حسب")}
|
||||||
|
</span>
|
||||||
|
<MdKeyboardArrowDown />
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<OrderBySelect />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Divider />
|
||||||
|
<div className="filter_header_bottom">
|
||||||
|
<span>
|
||||||
|
<p>{t("صف لكل صفحة")}</p>
|
||||||
|
<PaginationColumn />
|
||||||
|
<p>{t("ادخالات")}</p>
|
||||||
|
</span>
|
||||||
|
<div className="header_search">
|
||||||
|
<SearchField searchBy="" placeholder={t("practical.search_here")} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterLayout;
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ interface LayoutFilterModalProps {
|
||||||
ModelClassName?: string;
|
ModelClassName?: string;
|
||||||
width?: string;
|
width?: string;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
isOpen:any,
|
isOpen: any;
|
||||||
setIsOpen:any
|
setIsOpen: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LayoutFilterModal = ({
|
const LayoutFilterModal = ({
|
||||||
|
|
@ -30,7 +30,7 @@ const LayoutFilterModal = ({
|
||||||
width = "28vw",
|
width = "28vw",
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
setIsOpen,
|
setIsOpen,
|
||||||
isOpen
|
isOpen,
|
||||||
}: LayoutFilterModalProps) => {
|
}: LayoutFilterModalProps) => {
|
||||||
const { setObjectToEdit } = useObjectToEdit();
|
const { setObjectToEdit } = useObjectToEdit();
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|
@ -46,9 +46,9 @@ const LayoutFilterModal = ({
|
||||||
setObjectToEdit({});
|
setObjectToEdit({});
|
||||||
};
|
};
|
||||||
const handleOpen = () => {
|
const handleOpen = () => {
|
||||||
setIsOpen(true)
|
setIsOpen(true);
|
||||||
setObjectToEdit({})
|
setObjectToEdit({});
|
||||||
}
|
};
|
||||||
|
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
return (
|
return (
|
||||||
|
|
@ -62,28 +62,30 @@ const LayoutFilterModal = ({
|
||||||
onOk={handleOpen}
|
onOk={handleOpen}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
mask={false}
|
mask={false}
|
||||||
style={{position:"absolute",top:"31.4%",left:"16.7%"}}
|
style={{ position: "absolute", top: "31.4%", left: "16.7%" }}
|
||||||
>
|
>
|
||||||
<FormikForm
|
<FormikForm
|
||||||
handleSubmit={handleSubmit}
|
handleSubmit={handleSubmit}
|
||||||
initialValues={getInitialValues}
|
initialValues={getInitialValues}
|
||||||
validationSchema={getValidationSchema}
|
validationSchema={getValidationSchema}
|
||||||
>
|
>
|
||||||
<header>
|
<header>{t("models.filter")}</header>
|
||||||
{t("models.filter")}
|
<Divider />
|
||||||
</header>
|
|
||||||
<Divider/>
|
|
||||||
<main className="main_modal">
|
<main className="main_modal">
|
||||||
{isLoading ? <SpinContainer /> : children}
|
{isLoading ? <SpinContainer /> : children}
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<div className="back_button pointer" style={{width:"7vw"}} onClick={handleCancel}>
|
<div
|
||||||
|
className="back_button pointer"
|
||||||
|
style={{ width: "7vw" }}
|
||||||
|
onClick={handleCancel}
|
||||||
|
>
|
||||||
{t("practical.reset")}
|
{t("practical.reset")}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="add_button"
|
className="add_button"
|
||||||
style={{width:"7vw"}}
|
style={{ width: "7vw" }}
|
||||||
// disabled={status === QueryStatusEnum.LOADING}
|
// disabled={status === QueryStatusEnum.LOADING}
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -75,13 +75,13 @@ const LayoutModel = ({
|
||||||
{t(`practical.${isAddModal ? "add" : "edit"}`)}{" "}
|
{t(`practical.${isAddModal ? "add" : "edit"}`)}{" "}
|
||||||
{t(`models.${modelTitle}`)}{" "}
|
{t(`models.${modelTitle}`)}{" "}
|
||||||
</span>
|
</span>
|
||||||
<MdCancel onClick={handleCancel}/>
|
<MdCancel onClick={handleCancel} />
|
||||||
</header>
|
</header>
|
||||||
<Divider/>
|
<Divider />
|
||||||
<main className="main_modal">
|
<main className="main_modal">
|
||||||
{isLoading ? <SpinContainer /> : children}
|
{isLoading ? <SpinContainer /> : children}
|
||||||
<Divider/>
|
<Divider />
|
||||||
|
|
||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<div className="back_button pointer" onClick={handleCancel}>
|
<div className="back_button pointer" onClick={handleCancel}>
|
||||||
{t("practical.cancel")}
|
{t("practical.cancel")}
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,17 @@ const PageHeader = ({
|
||||||
ModelAbility,
|
ModelAbility,
|
||||||
pageTitle,
|
pageTitle,
|
||||||
openModel = true,
|
openModel = true,
|
||||||
locationToNavigate
|
locationToNavigate,
|
||||||
}:{
|
}: {
|
||||||
canAdd:any,
|
canAdd: any;
|
||||||
ModelAbility:any,
|
ModelAbility: any;
|
||||||
pageTitle:string,
|
pageTitle: string;
|
||||||
openModel?:boolean,
|
openModel?: boolean;
|
||||||
locationToNavigate?: string | any
|
locationToNavigate?: string | any;
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
const {t} = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { PageTitle } = usePageTitleState((state) => state);
|
const { PageTitle } = usePageTitleState((state) => state);
|
||||||
const PrevPath = getPrevPathRoute(location.pathname);
|
const PrevPath = getPrevPathRoute(location.pathname);
|
||||||
|
|
@ -36,29 +36,34 @@ const PageHeader = ({
|
||||||
}
|
}
|
||||||
navigate(deletePathSegments(location.pathname, PrevPath));
|
navigate(deletePathSegments(location.pathname, PrevPath));
|
||||||
};
|
};
|
||||||
const handleNavigateToPage = (location:string) => {
|
const handleNavigateToPage = (location: string) => {
|
||||||
navigate(location)
|
navigate(location);
|
||||||
}
|
};
|
||||||
return (
|
return (
|
||||||
<div className="page_header">
|
<div className="page_header">
|
||||||
<header className="d-flex justify-content-between">
|
<header className="d-flex justify-content-between">
|
||||||
<span className="page_header_links" onClick={handelNavigate}>
|
<span className="page_header_links" onClick={handelNavigate}>
|
||||||
<h1 className="page_title">{t(`sidebar.${pageTitle}`)}</h1>
|
<h1 className="page_title">{t(`sidebar.${pageTitle}`)}</h1>
|
||||||
<span className="page_links"><MdOutlineArrowForwardIos /> {PageTitle}</span>
|
<span className="page_links">
|
||||||
|
<MdOutlineArrowForwardIos /> {PageTitle}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{canAdd && (
|
{canAdd && (
|
||||||
<div className="Selects">
|
<div className="Selects">
|
||||||
<button
|
<button
|
||||||
onClick={() => openModel ? handel_open_model(ModelAbility): handleNavigateToPage(locationToNavigate)}
|
onClick={() =>
|
||||||
className="add_button"
|
openModel
|
||||||
>
|
? handel_open_model(ModelAbility)
|
||||||
<BsPlusCircleFill />
|
: handleNavigateToPage(locationToNavigate)
|
||||||
{t(`models.${pageTitle}`)}
|
}
|
||||||
</button>
|
className="add_button"
|
||||||
</div>
|
>
|
||||||
)}
|
<BsPlusCircleFill />
|
||||||
|
{t(`models.${pageTitle}`)}
|
||||||
</header>
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</header>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import React, { lazy, Suspense } from "react";
|
import React, { lazy, Suspense } from "react";
|
||||||
import {
|
import { useAddKeyToData, Table, useTranslation, usePagination } from ".";
|
||||||
useAddKeyToData,
|
|
||||||
Table,
|
|
||||||
useTranslation,
|
|
||||||
usePagination,
|
|
||||||
} from ".";
|
|
||||||
import { DataTableProps } from "../../../types/Table";
|
import { DataTableProps } from "../../../types/Table";
|
||||||
const NotFoundLottie = React.lazy(() => import("../../../Components/Lottie/NotFound/NotFoundLottie"));
|
const NotFoundLottie = React.lazy(
|
||||||
const LoadingLottie = React.lazy(() => import("../../../Components/Lottie/Loading/LoadingLottie"));
|
() => import("../../../Components/Lottie/NotFound/NotFoundLottie"),
|
||||||
|
);
|
||||||
|
const LoadingLottie = React.lazy(
|
||||||
|
() => import("../../../Components/Lottie/Loading/LoadingLottie"),
|
||||||
|
);
|
||||||
|
|
||||||
const DataTable: React.FC<DataTableProps> = ({
|
const DataTable: React.FC<DataTableProps> = ({
|
||||||
response,
|
response,
|
||||||
|
|
@ -27,38 +26,36 @@ const DataTable: React.FC<DataTableProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
style={{minHeight:"300px"}}
|
style={{ minHeight: "300px" }}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
rowClassName={(record, index) => getRowClassName(record, index)}
|
rowClassName={(record, index) => getRowClassName(record, index)}
|
||||||
className="DataTable"
|
className="DataTable"
|
||||||
loading={{
|
loading={{
|
||||||
spinning: isLoading || isRefetching,
|
spinning: isLoading || isRefetching,
|
||||||
indicator:<Suspense fallback={<></>}>
|
indicator: (
|
||||||
<LoadingLottie />
|
<Suspense fallback={<></>}>
|
||||||
</Suspense> ,
|
<LoadingLottie />
|
||||||
|
</Suspense>
|
||||||
|
),
|
||||||
size: "large",
|
size: "large",
|
||||||
}}
|
}}
|
||||||
locale={{
|
locale={{
|
||||||
emptyText: (
|
emptyText:
|
||||||
isLoading || isRefetching ?
|
isLoading || isRefetching ? (
|
||||||
<></>
|
<></>
|
||||||
:
|
) : (
|
||||||
|
<Suspense fallback={<></>}>
|
||||||
<Suspense fallback={<></>}>
|
<NotFoundLottie />
|
||||||
<NotFoundLottie
|
</Suspense>
|
||||||
|
),
|
||||||
/>
|
|
||||||
</Suspense>
|
|
||||||
),
|
|
||||||
}}
|
}}
|
||||||
pagination={{
|
pagination={{
|
||||||
...pagination,
|
...pagination,
|
||||||
onChange: handlePageChange,
|
onChange: handlePageChange,
|
||||||
nextIcon:<>{t("practical.next")}</>,
|
nextIcon: <>{t("practical.next")}</>,
|
||||||
prevIcon:<> {t("practical.prev")} </>,
|
prevIcon: <> {t("practical.prev")} </>,
|
||||||
className:"pagination_antd"
|
className: "pagination_antd",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,4 @@ import { useAddKeyToData } from "../../../Hooks/useAddKeyToData";
|
||||||
import usePagination from "../usePagination";
|
import usePagination from "../usePagination";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export {
|
export { Table, useAddKeyToData, usePagination, useTranslation };
|
||||||
Table,
|
|
||||||
useAddKeyToData,
|
|
||||||
usePagination,
|
|
||||||
useTranslation,
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@ const Layout = ({
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProtectedRouteProvider className="Layout">
|
<ProtectedRouteProvider className="Layout">
|
||||||
<main className={`${className} ${isOpen ?"Layout_Body":"Layout_Body side_bar_close" }`}>
|
<main
|
||||||
<NavBar isOpen={isOpen}/>
|
className={`${className} ${isOpen ? "Layout_Body" : "Layout_Body side_bar_close"}`}
|
||||||
|
>
|
||||||
|
<NavBar isOpen={isOpen} />
|
||||||
<div className="Layout_Children">{children}</div>
|
<div className="Layout_Children">{children}</div>
|
||||||
</main>
|
</main>
|
||||||
<SideBar isOpen={isOpen} setIsOpen={setIsOpen} />
|
<SideBar isOpen={isOpen} setIsOpen={setIsOpen} />
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import { useTranslation } from "react-i18next";
|
||||||
// Lazy load the ChangePasswordModel
|
// Lazy load the ChangePasswordModel
|
||||||
const ChangePasswordModel = lazy(() => import("./model/AddModel"));
|
const ChangePasswordModel = lazy(() => import("./model/AddModel"));
|
||||||
|
|
||||||
const NavBar = ({isOpen}:{isOpen:boolean}) => {
|
const NavBar = ({ isOpen }: { isOpen: boolean }) => {
|
||||||
const { PageTitle } = usePageTitleState((state) => state);
|
const { PageTitle } = usePageTitleState((state) => state);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -33,17 +33,17 @@ const NavBar = ({isOpen}:{isOpen:boolean}) => {
|
||||||
return (
|
return (
|
||||||
<div className="NavBar">
|
<div className="NavBar">
|
||||||
<Suspense fallback={<></>}>
|
<Suspense fallback={<></>}>
|
||||||
{/* <span className="navbar_link" onClick={handelNavigate}>
|
{/* <span className="navbar_link" onClick={handelNavigate}>
|
||||||
<MdOutlineArrowForwardIos /> {PageTitle}
|
<MdOutlineArrowForwardIos /> {PageTitle}
|
||||||
</span> */}
|
</span> */}
|
||||||
<div className="header_search">
|
<div className="header_search">
|
||||||
<SearchFieldWithSelect
|
<SearchFieldWithSelect
|
||||||
options={translateArray}
|
options={translateArray}
|
||||||
placeholder={t("practical.search_here")}
|
placeholder={t("practical.search_here")}
|
||||||
withIcon
|
withIcon
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<NavBarRightSide />
|
<NavBarRightSide />
|
||||||
<ChangePasswordModel />
|
<ChangePasswordModel />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,13 @@ import { CiMenuBurger, CiSettings } from "react-icons/ci";
|
||||||
import { IoIosMenu } from "react-icons/io";
|
import { IoIosMenu } from "react-icons/io";
|
||||||
import { HiMenuAlt2, HiMenuAlt3 } from "react-icons/hi";
|
import { HiMenuAlt2, HiMenuAlt3 } from "react-icons/hi";
|
||||||
|
|
||||||
const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
|
const SideBar = ({
|
||||||
|
isOpen,
|
||||||
|
setIsOpen,
|
||||||
|
}: {
|
||||||
|
isOpen: boolean;
|
||||||
|
setIsOpen: any;
|
||||||
|
}) => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { logout } = useAuthState();
|
const { logout } = useAuthState();
|
||||||
|
|
@ -21,35 +27,38 @@ const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
|
||||||
const branch_name = getLocalStorage(BRANCH_OBJECT_KEY)?.name;
|
const branch_name = getLocalStorage(BRANCH_OBJECT_KEY)?.name;
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
const toggleSidebar = () => {
|
||||||
setIsOpen((prev: boolean) => prev === true ? false : true);
|
setIsOpen((prev: boolean) => (prev === true ? false : true));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={isOpen ? "side_bar" :"side_bar side_bar_closed"} >
|
<div className={isOpen ? "side_bar" : "side_bar side_bar_closed"}>
|
||||||
<div className="side_bar_header">
|
<div className="side_bar_header">
|
||||||
<img src={isOpen ? "/App/Logo.png" : "/App/Logo2.png"} alt="" />
|
<img src={isOpen ? "/App/Logo.png" : "/App/Logo2.png"} alt="" />
|
||||||
<HiMenuAlt3 onClick={toggleSidebar} />
|
<HiMenuAlt3 onClick={toggleSidebar} />
|
||||||
</div>
|
</div>
|
||||||
{/* <Divider /> */}
|
{/* <Divider /> */}
|
||||||
<HiMenuAlt2 className="side_bar_close_menu" style={isOpen? {display:"none"}: {display:"inline"}} onClick={toggleSidebar} />
|
<HiMenuAlt2
|
||||||
|
className="side_bar_close_menu"
|
||||||
|
style={isOpen ? { display: "none" } : { display: "inline" }}
|
||||||
|
onClick={toggleSidebar}
|
||||||
|
/>
|
||||||
<div className="side_bar_links">
|
<div className="side_bar_links">
|
||||||
<p>{t("sidebar.main_menu")}</p>
|
<p>{t("sidebar.main_menu")}</p>
|
||||||
{menuItems.map((item, index) => {
|
{menuItems.map((item, index) => {
|
||||||
const useAbility = hasAbility(item.abilities, item.abilities_value);
|
const useAbility = hasAbility(item.abilities, item.abilities_value);
|
||||||
if (!useAbility) {
|
if (!useAbility) {
|
||||||
return <React.Fragment key={index}></React.Fragment>;
|
return <React.Fragment key={index}></React.Fragment>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={index}
|
key={index}
|
||||||
item={item}
|
item={item}
|
||||||
location={location}
|
location={location}
|
||||||
index={index}
|
index={index}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="side_bar_setting">
|
<div className="side_bar_setting">
|
||||||
<p>{t("sidebar.setting")}</p>
|
<p>{t("sidebar.setting")}</p>
|
||||||
|
|
@ -58,11 +67,12 @@ const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
|
||||||
<span>{t("sidebar.setting")}</span>
|
<span>{t("sidebar.setting")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="logout_button"
|
className="logout_button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
logout();
|
logout();
|
||||||
navigate("/auth");
|
navigate("/auth");
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<MdLogout />
|
<MdLogout />
|
||||||
<span>{t("sidebar.logout")}</span>
|
<span>{t("sidebar.logout")}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -72,5 +82,3 @@ const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SideBar;
|
export default SideBar;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const EditModel: React.FC = () => {
|
||||||
getInitialValues={getInitialValues(objectToEdit)}
|
getInitialValues={getInitialValues(objectToEdit)}
|
||||||
getValidationSchema={getValidationSchema}
|
getValidationSchema={getValidationSchema}
|
||||||
isAddModal={false}
|
isAddModal={false}
|
||||||
width="500px"
|
width="500px"
|
||||||
>
|
>
|
||||||
<ModelForm />
|
<ModelForm />
|
||||||
</LayoutModel>
|
</LayoutModel>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,15 @@ const TableHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="curriculum"
|
pageTitle="curriculum"
|
||||||
ModelAbility={ModalEnum?.CURRICULUM_ADD}
|
ModelAbility={ModalEnum?.CURRICULUM_ADD}
|
||||||
canAdd={canAddCurriculum}/>
|
canAdd={canAddCurriculum}
|
||||||
|
/>
|
||||||
<FilterLayout
|
<FilterLayout
|
||||||
sub_children={<FilterForm/>}
|
sub_children={<FilterForm />}
|
||||||
filterTitle="sidebar.curriculum"/>
|
filterTitle="sidebar.curriculum"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -54,15 +54,15 @@ export const useColumns = () => {
|
||||||
|
|
||||||
{
|
{
|
||||||
// canAddCurriculum ? (
|
// canAddCurriculum ? (
|
||||||
// <button
|
// <button
|
||||||
// onClick={() => handel_open_model(ModalEnum?.CURRICULUM_ADD)}
|
// onClick={() => handel_open_model(ModalEnum?.CURRICULUM_ADD)}
|
||||||
// className="add_button"
|
// className="add_button"
|
||||||
// >
|
// >
|
||||||
// {t("practical.add")} {t("models.curriculum")} <FaPlus />
|
// {t("practical.add")} {t("models.curriculum")} <FaPlus />
|
||||||
// </button>
|
// </button>
|
||||||
// ) : (
|
// ) : (
|
||||||
// ""
|
// ""
|
||||||
// ),
|
// ),
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,15 @@ const TableHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
|
<PageHeader
|
||||||
<PageHeader
|
pageTitle="grade"
|
||||||
pageTitle="grade"
|
ModelAbility={ModalEnum?.GRADE_ADD}
|
||||||
ModelAbility={ModalEnum?.GRADE_ADD}
|
canAdd={canAddGrade}
|
||||||
canAdd={canAddGrade}/>
|
/>
|
||||||
<FilterLayout
|
<FilterLayout
|
||||||
sub_children={<FilterForm/>}
|
sub_children={<FilterForm />}
|
||||||
filterTitle="sidebar.grade"/>
|
filterTitle="sidebar.grade"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -64,16 +64,16 @@ export const useColumns = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// canAddGrade ? (
|
// canAddGrade ? (
|
||||||
// <button
|
// <button
|
||||||
// onClick={() => handel_open_model(ModalEnum?.GRADE_ADD)}
|
// onClick={() => handel_open_model(ModalEnum?.GRADE_ADD)}
|
||||||
// className="add_button"
|
// className="add_button"
|
||||||
// >
|
// >
|
||||||
// {t("practical.add")} {t("models.grade")} <FaPlus />
|
// {t("practical.add")} {t("models.grade")} <FaPlus />
|
||||||
// </button>
|
// </button>
|
||||||
// ) : (
|
// ) : (
|
||||||
// ""
|
// ""
|
||||||
// ),
|
// ),
|
||||||
|
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@ import FilterForm from "./Model/FilterForm";
|
||||||
const Table = lazy(() => import("./Table"));
|
const Table = lazy(() => import("./Table"));
|
||||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||||
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
|
const DeleteModalForm = lazy(
|
||||||
|
() => import("../../../Layout/Dashboard/DeleteModels"),
|
||||||
|
);
|
||||||
const SearchField = lazy(
|
const SearchField = lazy(
|
||||||
() => import("../../../Components/DataTable/SearchField"),
|
() => import("../../../Components/DataTable/SearchField"),
|
||||||
);
|
);
|
||||||
|
|
@ -21,25 +23,25 @@ const SearchField = lazy(
|
||||||
const TableHeader = () => {
|
const TableHeader = () => {
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
useSetPageTitle(
|
useSetPageTitle(t(`page_header.report`));
|
||||||
t(`page_header.report`),
|
|
||||||
);
|
|
||||||
const deleteMutation = useDeleteTag();
|
const deleteMutation = useDeleteTag();
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="report"
|
pageTitle="report"
|
||||||
ModelAbility={ModalEnum?.REPORT_ADD}
|
ModelAbility={ModalEnum?.REPORT_ADD}
|
||||||
canAdd={canAddReport}/>
|
canAdd={canAddReport}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.report"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.report"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<DeleteModalForm
|
<DeleteModalForm
|
||||||
deleteMutation={deleteMutation}
|
deleteMutation={deleteMutation}
|
||||||
ModelEnum={ModalEnum?.REPORT_DELETE}
|
ModelEnum={ModalEnum?.REPORT_DELETE}
|
||||||
/>
|
/>
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ export const useColumns = () => {
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
const { setIsOpen } = useModalState((state) => state);
|
||||||
|
|
||||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||||
const handelDelete = (record:any) => {
|
const handelDelete = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.REPORT_DELETE);
|
setIsOpen(ModalEnum?.REPORT_DELETE);
|
||||||
};
|
};
|
||||||
const handleEdit = (record:any) => {
|
const handleEdit = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.REPORT_EDIT);
|
setIsOpen(ModalEnum?.REPORT_EDIT);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,11 @@ import { ModalEnum } from "../../../enums/Model";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { lazy, Suspense } from "react";
|
import { lazy, Suspense } from "react";
|
||||||
import { Spin } from "antd";
|
import { Spin } from "antd";
|
||||||
import { canAddReport, canAddReseller, canAddTags } from "../../../utils/hasAbilityFn";
|
import {
|
||||||
|
canAddReport,
|
||||||
|
canAddReseller,
|
||||||
|
canAddTags,
|
||||||
|
} from "../../../utils/hasAbilityFn";
|
||||||
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
||||||
import { useDeleteTag } from "../../../api/tags";
|
import { useDeleteTag } from "../../../api/tags";
|
||||||
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
||||||
|
|
@ -13,7 +17,9 @@ import FilterForm from "./Model/FilterForm";
|
||||||
const Table = lazy(() => import("./Table"));
|
const Table = lazy(() => import("./Table"));
|
||||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||||
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
|
const DeleteModalForm = lazy(
|
||||||
|
() => import("../../../Layout/Dashboard/DeleteModels"),
|
||||||
|
);
|
||||||
const SearchField = lazy(
|
const SearchField = lazy(
|
||||||
() => import("../../../Components/DataTable/SearchField"),
|
() => import("../../../Components/DataTable/SearchField"),
|
||||||
);
|
);
|
||||||
|
|
@ -21,25 +27,25 @@ const SearchField = lazy(
|
||||||
const TableHeader = () => {
|
const TableHeader = () => {
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
useSetPageTitle(
|
useSetPageTitle(t(`page_header.reseller`));
|
||||||
t(`page_header.reseller`),
|
|
||||||
);
|
|
||||||
const deleteMutation = useDeleteTag();
|
const deleteMutation = useDeleteTag();
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="reseller"
|
pageTitle="reseller"
|
||||||
ModelAbility={ModalEnum?.RESELLER_ADD}
|
ModelAbility={ModalEnum?.RESELLER_ADD}
|
||||||
canAdd={canAddReseller}/>
|
canAdd={canAddReseller}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.reseller"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.reseller"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<DeleteModalForm
|
<DeleteModalForm
|
||||||
deleteMutation={deleteMutation}
|
deleteMutation={deleteMutation}
|
||||||
ModelEnum={ModalEnum?.RESELLER_DELETE}
|
ModelEnum={ModalEnum?.RESELLER_DELETE}
|
||||||
/>
|
/>
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,12 @@ import { ModalEnum } from "../../../enums/Model";
|
||||||
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
|
||||||
import { useModalState } from "../../../zustand/Modal";
|
import { useModalState } from "../../../zustand/Modal";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { canDeleteReseller, canDeleteUser, canEditReseller, canEditUser } from "../../../utils/hasAbilityFn";
|
import {
|
||||||
|
canDeleteReseller,
|
||||||
|
canDeleteUser,
|
||||||
|
canEditReseller,
|
||||||
|
canEditUser,
|
||||||
|
} from "../../../utils/hasAbilityFn";
|
||||||
import ActionButtons from "../../../Components/Table/ActionButtons";
|
import ActionButtons from "../../../Components/Table/ActionButtons";
|
||||||
|
|
||||||
export const useColumns = () => {
|
export const useColumns = () => {
|
||||||
|
|
@ -13,11 +18,11 @@ export const useColumns = () => {
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
const { setIsOpen } = useModalState((state) => state);
|
||||||
|
|
||||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||||
const handelDelete = (record:any) => {
|
const handelDelete = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.RESELLER_DELETE);
|
setIsOpen(ModalEnum?.RESELLER_DELETE);
|
||||||
};
|
};
|
||||||
const handleEdit = (record:any) => {
|
const handleEdit = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.RESELLER_EDIT);
|
setIsOpen(ModalEnum?.RESELLER_EDIT);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -5,37 +5,52 @@ import { useValidationValidationParamState } from "../../../../Components/Valida
|
||||||
|
|
||||||
const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
|
const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
|
||||||
const { ValidationParamState } = useValidationValidationParamState();
|
const { ValidationParamState } = useValidationValidationParamState();
|
||||||
const {
|
const { GradeName, GradeCurrentPage } = ValidationParamState;
|
||||||
GradeName, GradeCurrentPage,
|
|
||||||
} = ValidationParamState;
|
|
||||||
|
|
||||||
|
|
||||||
const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({
|
const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({
|
||||||
name: GradeName,
|
name: GradeName,
|
||||||
page: GradeCurrentPage
|
page: GradeCurrentPage,
|
||||||
});
|
});
|
||||||
const GradeOption = Grade?.data ?? []
|
const GradeOption = Grade?.data ?? [];
|
||||||
const canChangeGradePage = !!Grade?.links?.next;
|
const canChangeGradePage = !!Grade?.links?.next;
|
||||||
const GradePage = Grade?.meta?.currentPage;
|
const GradePage = Grade?.meta?.currentPage;
|
||||||
|
|
||||||
const sex = [
|
const sex = [
|
||||||
{name:"male" , id :"male"},
|
{ name: "male", id: "male" },
|
||||||
{name:"female" , id :"female"}
|
{ name: "female", id: "female" },
|
||||||
]
|
];
|
||||||
return (
|
return (
|
||||||
<Row className="w-100">
|
<Row className="w-100">
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField name="first_name" placeholder="first_name" label="first_name" />
|
<ValidationField
|
||||||
<ValidationField name="last_name" placeholder="last_name" label="last_name" />
|
name="first_name"
|
||||||
<ValidationField name="username" placeholder="username" label="username" />
|
placeholder="first_name"
|
||||||
{!isEdit &&
|
label="first_name"
|
||||||
<ValidationField name="password" placeholder="password" label="password" />
|
/>
|
||||||
}
|
<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>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField name="phone_number" placeholder="contact_number1" label="contact_number1" />
|
<ValidationField
|
||||||
|
name="phone_number"
|
||||||
|
placeholder="contact_number1"
|
||||||
|
label="contact_number1"
|
||||||
|
/>
|
||||||
<ValidationField
|
<ValidationField
|
||||||
searchBy="GradeName"
|
searchBy="GradeName"
|
||||||
name="grade_id"
|
name="grade_id"
|
||||||
|
|
@ -46,10 +61,8 @@ const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
|
||||||
canChangePage={canChangeGradePage}
|
canChangePage={canChangeGradePage}
|
||||||
PageName={"GradeCurrentPage"}
|
PageName={"GradeCurrentPage"}
|
||||||
page={GradePage}
|
page={GradePage}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<ValidationField type="Select" name="sex" option={sex} />
|
<ValidationField type="Select" name="sex" option={sex} />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,9 @@ export const getInitialValues = (
|
||||||
// address: objectToEdit?.address ?? "",
|
// address: objectToEdit?.address ?? "",
|
||||||
// birthday: objectToEdit?.birthday ?? "",
|
// birthday: objectToEdit?.birthday ?? "",
|
||||||
// city: objectToEdit?.city ?? "",
|
// city: objectToEdit?.city ?? "",
|
||||||
grade_id: objectToEdit?.grade_id ,
|
grade_id: objectToEdit?.grade_id,
|
||||||
// image: objectToEdit?.image ?? "",
|
// image: objectToEdit?.image ?? "",
|
||||||
sex: objectToEdit?.sex ,
|
sex: objectToEdit?.sex,
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,15 @@ const TableHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="student"
|
pageTitle="student"
|
||||||
ModelAbility={ModalEnum?.STUDENT_ADD}
|
ModelAbility={ModalEnum?.STUDENT_ADD}
|
||||||
canAdd={canAddStudent}/>
|
canAdd={canAddStudent}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="table.student"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="table.student"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,3 @@ const App: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ export const useColumns = () => {
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.sex,
|
render: (_text, record) => record?.sex,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "",
|
title: "",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const Form = () => {
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<DynamicTags />
|
<DynamicTags />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@ import FilterForm from "./Model/FilterForm";
|
||||||
const Table = lazy(() => import("./Table"));
|
const Table = lazy(() => import("./Table"));
|
||||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||||
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
|
const DeleteModalForm = lazy(
|
||||||
|
() => import("../../../Layout/Dashboard/DeleteModels"),
|
||||||
|
);
|
||||||
const SearchField = lazy(
|
const SearchField = lazy(
|
||||||
() => import("../../../Components/DataTable/SearchField"),
|
() => import("../../../Components/DataTable/SearchField"),
|
||||||
);
|
);
|
||||||
|
|
@ -21,25 +23,25 @@ const SearchField = lazy(
|
||||||
const TableHeader = () => {
|
const TableHeader = () => {
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
useSetPageTitle(
|
useSetPageTitle(t(`page_header.tags`));
|
||||||
t(`page_header.tags`),
|
|
||||||
);
|
|
||||||
const deleteMutation = useDeleteTag();
|
const deleteMutation = useDeleteTag();
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="tags"
|
pageTitle="tags"
|
||||||
ModelAbility={ModalEnum?.TAGS_ADD}
|
ModelAbility={ModalEnum?.TAGS_ADD}
|
||||||
canAdd={canAddTags}/>
|
canAdd={canAddTags}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.tags"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.tags"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<DeleteModalForm
|
<DeleteModalForm
|
||||||
deleteMutation={deleteMutation}
|
deleteMutation={deleteMutation}
|
||||||
ModelEnum={ModalEnum?.TAGS_DELETE}
|
ModelEnum={ModalEnum?.TAGS_DELETE}
|
||||||
/>
|
/>
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ export const useColumns = () => {
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
const { setIsOpen } = useModalState((state) => state);
|
||||||
|
|
||||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||||
const handelDelete = (record:any) => {
|
const handelDelete = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.TAGS_DELETE);
|
setIsOpen(ModalEnum?.TAGS_DELETE);
|
||||||
};
|
};
|
||||||
const handleEdit = (record:any) => {
|
const handleEdit = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.TAGS_EDIT);
|
setIsOpen(ModalEnum?.TAGS_EDIT);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,12 @@ import { useParams } from "react-router-dom";
|
||||||
import { ParamsEnum } from "../../../enums/params";
|
import { ParamsEnum } from "../../../enums/params";
|
||||||
import { useGetAllUnit, useUpdateUnitOrder } from "../../../api/unit";
|
import { useGetAllUnit, useUpdateUnitOrder } from "../../../api/unit";
|
||||||
|
|
||||||
const NotFoundLottie = React.lazy(() => import("../../../Components/Lottie/NotFound/NotFoundLottie"));
|
const NotFoundLottie = React.lazy(
|
||||||
const LoadingLottie = React.lazy(() => import("../../../Components/Lottie/Loading/LoadingLottie" ));
|
() => import("../../../Components/Lottie/NotFound/NotFoundLottie"),
|
||||||
|
);
|
||||||
|
const LoadingLottie = React.lazy(
|
||||||
|
() => import("../../../Components/Lottie/Loading/LoadingLottie"),
|
||||||
|
);
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useColumns } from "./useTableColumns";
|
import { useColumns } from "./useTableColumns";
|
||||||
|
|
@ -52,7 +55,6 @@ export const DragHandleUnit: React.FC = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||||
"data-row-key": string;
|
"data-row-key": string;
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +98,7 @@ const DrapableTable: React.FC = () => {
|
||||||
response?.data?.data?.map((item: any, index: number) => ({
|
response?.data?.data?.map((item: any, index: number) => ({
|
||||||
id: item.id, // Ensure this is a unique identifier
|
id: item.id, // Ensure this is a unique identifier
|
||||||
order: index + 1, // Assign order based on index
|
order: index + 1, // Assign order based on index
|
||||||
...item
|
...item,
|
||||||
})) ?? [];
|
})) ?? [];
|
||||||
|
|
||||||
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
||||||
|
|
@ -107,39 +109,42 @@ const DrapableTable: React.FC = () => {
|
||||||
setDataSource(sortedData);
|
setDataSource(sortedData);
|
||||||
}, [response?.data?.data]);
|
}, [response?.data?.data]);
|
||||||
|
|
||||||
const {mutate:orderUnit} = useUpdateUnitOrder({},{
|
const { mutate: orderUnit } = useUpdateUnitOrder(
|
||||||
retry:false
|
{},
|
||||||
})
|
{
|
||||||
|
retry: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||||
if (active.id !== over?.id) {
|
if (active.id !== over?.id) {
|
||||||
setDataSource((prevState) => {
|
setDataSource((prevState) => {
|
||||||
const activeIndex = prevState.findIndex(
|
const activeIndex = prevState.findIndex(
|
||||||
(record) => record.id === active.id,
|
(record) => record.id === active.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
const overIndex = prevState.findIndex(
|
const overIndex = prevState.findIndex(
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
(record) => record.id === over.id,
|
(record) => record.id === over.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Move the items in the array
|
// Move the items in the array
|
||||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||||
const orderedNewState = newState.map((item, index) => ({
|
const orderedNewState = newState.map((item, index) => ({
|
||||||
...item,
|
...item,
|
||||||
order: index + 1, // Update the order based on the new index
|
order: index + 1, // Update the order based on the new index
|
||||||
}));
|
}));
|
||||||
// Update the order based on the new positions
|
// Update the order based on the new positions
|
||||||
const orderedNewStateWithNewChape = orderedNewState?.map((item:any)=>{
|
const orderedNewStateWithNewChape = orderedNewState?.map(
|
||||||
return {
|
(item: any) => {
|
||||||
"unit_id":item?.id,
|
return {
|
||||||
"order":item?.order
|
unit_id: item?.id,
|
||||||
}
|
order: item?.order,
|
||||||
})
|
};
|
||||||
orderUnit({units: orderedNewStateWithNewChape, _method:"PUT"})
|
},
|
||||||
return orderedNewState
|
);
|
||||||
|
orderUnit({ units: orderedNewStateWithNewChape, _method: "PUT" });
|
||||||
|
return orderedNewState;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -147,11 +152,11 @@ const DrapableTable: React.FC = () => {
|
||||||
return index % 2 === 0 ? "even-row" : "odd-row";
|
return index % 2 === 0 ? "even-row" : "odd-row";
|
||||||
};
|
};
|
||||||
const isLoading = response?.isLoading;
|
const isLoading = response?.isLoading;
|
||||||
const [t] = useTranslation()
|
const [t] = useTranslation();
|
||||||
const columns = useColumns();
|
const columns = useColumns();
|
||||||
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order) ;
|
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order);
|
||||||
console.log(sortedDataSource,"sortedDataSource");
|
console.log(sortedDataSource, "sortedDataSource");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||||
<SortableContext
|
<SortableContext
|
||||||
|
|
@ -161,32 +166,30 @@ const DrapableTable: React.FC = () => {
|
||||||
<Table
|
<Table
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
components={{ body: { row: Row } }}
|
components={{ body: { row: Row } }}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={sortedDataSource}
|
dataSource={sortedDataSource}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
rowClassName={(record, index) => getRowClassName(record, index)}
|
rowClassName={(record, index) => getRowClassName(record, index)}
|
||||||
className="DataTable"
|
className="DataTable"
|
||||||
loading={{
|
loading={{
|
||||||
spinning: isLoading,
|
spinning: isLoading,
|
||||||
indicator:<Suspense fallback={<></>}>
|
indicator: (
|
||||||
<LoadingLottie />
|
<Suspense fallback={<></>}>
|
||||||
</Suspense> ,
|
<LoadingLottie />
|
||||||
size: "large",
|
</Suspense>
|
||||||
}}
|
),
|
||||||
locale={{
|
size: "large",
|
||||||
emptyText: (
|
}}
|
||||||
isLoading ?
|
locale={{
|
||||||
<></>
|
emptyText: isLoading ? (
|
||||||
:
|
<></>
|
||||||
|
) : (
|
||||||
<Suspense fallback={<></>}>
|
<Suspense fallback={<></>}>
|
||||||
<NotFoundLottie
|
<NotFoundLottie />
|
||||||
|
</Suspense>
|
||||||
/>
|
),
|
||||||
</Suspense>
|
}}
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</SortableContext>
|
</SortableContext>
|
||||||
</DndContext>
|
</DndContext>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ const AddModel: React.FC = () => {
|
||||||
handleSubmit={handleSubmit}
|
handleSubmit={handleSubmit}
|
||||||
getInitialValues={getInitialValues({})}
|
getInitialValues={getInitialValues({})}
|
||||||
getValidationSchema={getValidationSchema}
|
getValidationSchema={getValidationSchema}
|
||||||
|
|
||||||
>
|
>
|
||||||
<ModelForm />
|
<ModelForm />
|
||||||
</LayoutModel>
|
</LayoutModel>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ const EditModel: React.FC = () => {
|
||||||
getInitialValues={getInitialValues(objectToEdit)}
|
getInitialValues={getInitialValues(objectToEdit)}
|
||||||
getValidationSchema={getValidationSchema}
|
getValidationSchema={getValidationSchema}
|
||||||
isAddModal={false}
|
isAddModal={false}
|
||||||
|
|
||||||
>
|
>
|
||||||
<ModelForm />
|
<ModelForm />
|
||||||
</LayoutModel>
|
</LayoutModel>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import { enumToArray } from "../../../../api/utils/enumToArray";
|
||||||
|
|
||||||
const Form = () => {
|
const Form = () => {
|
||||||
const termsArray = enumToArray(TermEnum);
|
const termsArray = enumToArray(TermEnum);
|
||||||
console.log(termsArray);
|
console.log(termsArray);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="w-100">
|
<Row className="w-100">
|
||||||
<Col>
|
<Col>
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,15 @@ const TableHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="unit"
|
pageTitle="unit"
|
||||||
ModelAbility={ModalEnum?.UNIT_ADD}
|
ModelAbility={ModalEnum?.UNIT_ADD}
|
||||||
canAdd={canAddUnit}/>
|
canAdd={canAddUnit}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.unit"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.unit"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,12 @@ export const useColumns = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
const columns: TableColumnsType<Unit> = [
|
const columns: TableColumnsType<Unit> = [
|
||||||
{ key: "sort", align: "center", width: 80, render: () => <DragHandleUnit /> },
|
{
|
||||||
|
key: "sort",
|
||||||
|
align: "center",
|
||||||
|
width: 80,
|
||||||
|
render: () => <DragHandleUnit />,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: t("columns.id"),
|
title: t("columns.id"),
|
||||||
|
|
@ -68,7 +73,6 @@ export const useColumns = () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,13 @@ const Form = () => {
|
||||||
return (
|
return (
|
||||||
<Row className="w-100">
|
<Row className="w-100">
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" type="Number" />
|
<ValidationField
|
||||||
|
placeholder="name"
|
||||||
|
label="name"
|
||||||
|
name="name"
|
||||||
|
type="Number"
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { ModalEnum } from "../../../enums/Model";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { lazy, Suspense } from "react";
|
import { lazy, Suspense } from "react";
|
||||||
import { Spin } from "antd";
|
import { Spin } from "antd";
|
||||||
import { canAddUser } from "../../../utils/hasAbilityFn";
|
import { canAddUser } from "../../../utils/hasAbilityFn";
|
||||||
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
||||||
import { useDeleteTag } from "../../../api/tags";
|
import { useDeleteTag } from "../../../api/tags";
|
||||||
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
||||||
|
|
@ -11,29 +11,31 @@ import FilterForm from "./Model/FilterForm";
|
||||||
const Table = lazy(() => import("./Table"));
|
const Table = lazy(() => import("./Table"));
|
||||||
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
const AddModalForm = lazy(() => import("./Model/AddModel"));
|
||||||
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
const EditModalForm = lazy(() => import("./Model/EditModel"));
|
||||||
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
|
const DeleteModalForm = lazy(
|
||||||
|
() => import("../../../Layout/Dashboard/DeleteModels"),
|
||||||
|
);
|
||||||
|
|
||||||
const TableHeader = () => {
|
const TableHeader = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
useSetPageTitle(
|
useSetPageTitle(t(`page_header.user`));
|
||||||
t(`page_header.user`),
|
|
||||||
);
|
|
||||||
const deleteMutation = useDeleteTag();
|
const deleteMutation = useDeleteTag();
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="user"
|
pageTitle="user"
|
||||||
ModelAbility={ModalEnum?.USER_ADD}
|
ModelAbility={ModalEnum?.USER_ADD}
|
||||||
canAdd={canAddUser}/>
|
canAdd={canAddUser}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.user"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.user"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<DeleteModalForm
|
<DeleteModalForm
|
||||||
deleteMutation={deleteMutation}
|
deleteMutation={deleteMutation}
|
||||||
ModelEnum={ModalEnum?.USER_DELETE}
|
ModelEnum={ModalEnum?.USER_DELETE}
|
||||||
/>
|
/>
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ const App: React.FC = () => {
|
||||||
const response = useGetAllUser({
|
const response = useGetAllUser({
|
||||||
name: searchQuery,
|
name: searchQuery,
|
||||||
pagination: true,
|
pagination: true,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ export const useColumns = () => {
|
||||||
const { setIsOpen } = useModalState((state) => state);
|
const { setIsOpen } = useModalState((state) => state);
|
||||||
|
|
||||||
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
const { setObjectToEdit } = useObjectToEdit((state) => state);
|
||||||
const handelDelete = (record:any) => {
|
const handelDelete = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.USER_DELETE);
|
setIsOpen(ModalEnum?.USER_DELETE);
|
||||||
};
|
};
|
||||||
const handleEdit = (record:any) => {
|
const handleEdit = (record: any) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
setIsOpen(ModalEnum?.USER_EDIT);
|
setIsOpen(ModalEnum?.USER_EDIT);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,12 @@ import { useParams } from "react-router-dom";
|
||||||
import { ParamsEnum } from "../../../enums/params";
|
import { ParamsEnum } from "../../../enums/params";
|
||||||
import { useGetAllLesson, useUpdateLessonOrder } from "../../../api/lesson";
|
import { useGetAllLesson, useUpdateLessonOrder } from "../../../api/lesson";
|
||||||
|
|
||||||
|
const NotFoundLottie = React.lazy(
|
||||||
const NotFoundLottie = React.lazy(() => import("../../../Components/Lottie/NotFound/NotFoundLottie"));
|
() => import("../../../Components/Lottie/NotFound/NotFoundLottie"),
|
||||||
const LoadingLottie = React.lazy(() => import("../../../Components/Lottie/Loading/LoadingLottie" ));
|
);
|
||||||
|
const LoadingLottie = React.lazy(
|
||||||
|
() => import("../../../Components/Lottie/Loading/LoadingLottie"),
|
||||||
|
);
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useColumns } from "./useTableColumns";
|
import { useColumns } from "./useTableColumns";
|
||||||
|
|
@ -53,7 +55,6 @@ export const DragHandleLesson: React.FC = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
||||||
"data-row-key": string;
|
"data-row-key": string;
|
||||||
}
|
}
|
||||||
|
|
@ -90,14 +91,17 @@ const Row: React.FC<RowProps> = (props) => {
|
||||||
|
|
||||||
const DrapableTable: React.FC = () => {
|
const DrapableTable: React.FC = () => {
|
||||||
const { subject_id } = useParams<ParamsEnum>();
|
const { subject_id } = useParams<ParamsEnum>();
|
||||||
const response = useGetAllLesson({ subject_id: subject_id, pagination: false });
|
const response = useGetAllLesson({
|
||||||
|
subject_id: subject_id,
|
||||||
|
pagination: false,
|
||||||
|
});
|
||||||
|
|
||||||
// Assuming the response contains a unique id for each item
|
// Assuming the response contains a unique id for each item
|
||||||
const data =
|
const data =
|
||||||
response?.data?.data?.map((item: any, index: number) => ({
|
response?.data?.data?.map((item: any, index: number) => ({
|
||||||
id: item.id, // Ensure this is a unique identifier
|
id: item.id, // Ensure this is a unique identifier
|
||||||
order: index + 1, // Assign order based on index
|
order: index + 1, // Assign order based on index
|
||||||
...item
|
...item,
|
||||||
})) ?? [];
|
})) ?? [];
|
||||||
|
|
||||||
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
|
||||||
|
|
@ -108,48 +112,48 @@ const DrapableTable: React.FC = () => {
|
||||||
setDataSource(sortedData);
|
setDataSource(sortedData);
|
||||||
}, [response?.data?.data]);
|
}, [response?.data?.data]);
|
||||||
|
|
||||||
const {mutate:orderLesson} = useUpdateLessonOrder()
|
const { mutate: orderLesson } = useUpdateLessonOrder();
|
||||||
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
const onDragEnd = ({ active, over }: DragEndEvent) => {
|
||||||
if (active.id !== over?.id) {
|
if (active.id !== over?.id) {
|
||||||
setDataSource((prevState) => {
|
setDataSource((prevState) => {
|
||||||
const activeIndex = prevState.findIndex(
|
const activeIndex = prevState.findIndex(
|
||||||
(record) => record.id === active.id,
|
(record) => record.id === active.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
const overIndex = prevState.findIndex(
|
const overIndex = prevState.findIndex(
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
(record) => record.id === over.id,
|
(record) => record.id === over.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Move the items in the array
|
// Move the items in the array
|
||||||
const newState = arrayMove(prevState, activeIndex, overIndex);
|
const newState = arrayMove(prevState, activeIndex, overIndex);
|
||||||
const orderedNewState = newState.map((item, index) => ({
|
const orderedNewState = newState.map((item, index) => ({
|
||||||
...item,
|
...item,
|
||||||
order: index + 1, // Update the order based on the new index
|
order: index + 1, // Update the order based on the new index
|
||||||
}));
|
}));
|
||||||
// Update the order based on the new positions
|
// Update the order based on the new positions
|
||||||
const orderedNewStateWithNewChape = orderedNewState?.map((item:any)=>{
|
const orderedNewStateWithNewChape = orderedNewState?.map(
|
||||||
return {
|
(item: any) => {
|
||||||
"lesson_id":item?.id,
|
return {
|
||||||
"order":item?.order
|
lesson_id: item?.id,
|
||||||
}
|
order: item?.order,
|
||||||
})
|
};
|
||||||
orderLesson({lessons: orderedNewStateWithNewChape, _method:"PUT"})
|
},
|
||||||
return orderedNewState
|
);
|
||||||
|
orderLesson({ lessons: orderedNewStateWithNewChape, _method: "PUT" });
|
||||||
|
return orderedNewState;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRowClassName = (record: any, index: number): string => {
|
const getRowClassName = (record: any, index: number): string => {
|
||||||
return index % 2 === 0 ? "even-row" : "odd-row";
|
return index % 2 === 0 ? "even-row" : "odd-row";
|
||||||
};
|
};
|
||||||
const [t] = useTranslation()
|
const [t] = useTranslation();
|
||||||
const columns = useColumns();
|
const columns = useColumns();
|
||||||
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order) ;
|
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order);
|
||||||
console.log(sortedDataSource,"sortedDataSource");
|
console.log(sortedDataSource, "sortedDataSource");
|
||||||
const isLoading = response?.isLoading
|
const isLoading = response?.isLoading;
|
||||||
return (
|
return (
|
||||||
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
|
||||||
<SortableContext
|
<SortableContext
|
||||||
|
|
@ -159,32 +163,30 @@ const DrapableTable: React.FC = () => {
|
||||||
<Table
|
<Table
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
components={{ body: { row: Row } }}
|
components={{ body: { row: Row } }}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={sortedDataSource}
|
dataSource={sortedDataSource}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
rowClassName={(record, index) => getRowClassName(record, index)}
|
rowClassName={(record, index) => getRowClassName(record, index)}
|
||||||
className="DataTable"
|
className="DataTable"
|
||||||
loading={{
|
loading={{
|
||||||
spinning: isLoading,
|
spinning: isLoading,
|
||||||
indicator:<Suspense fallback={<></>}>
|
indicator: (
|
||||||
<LoadingLottie />
|
<Suspense fallback={<></>}>
|
||||||
</Suspense> ,
|
<LoadingLottie />
|
||||||
size: "large",
|
</Suspense>
|
||||||
}}
|
),
|
||||||
locale={{
|
size: "large",
|
||||||
emptyText: (
|
}}
|
||||||
isLoading ?
|
locale={{
|
||||||
<></>
|
emptyText: isLoading ? (
|
||||||
:
|
<></>
|
||||||
|
) : (
|
||||||
<Suspense fallback={<></>}>
|
<Suspense fallback={<></>}>
|
||||||
<NotFoundLottie
|
<NotFoundLottie />
|
||||||
|
</Suspense>
|
||||||
/>
|
),
|
||||||
</Suspense>
|
}}
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</SortableContext>
|
</SortableContext>
|
||||||
</DndContext>
|
</DndContext>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const ModalForm: React.FC = () => {
|
||||||
getInitialValues={getInitialValues(objectToEdit)}
|
getInitialValues={getInitialValues(objectToEdit)}
|
||||||
getValidationSchema={getValidationSchema}
|
getValidationSchema={getValidationSchema}
|
||||||
isAddModal={false}
|
isAddModal={false}
|
||||||
width="500px"
|
width="500px"
|
||||||
>
|
>
|
||||||
<ModelForm />
|
<ModelForm />
|
||||||
</LayoutModel>
|
</LayoutModel>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,15 @@ const TableHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="lesson"
|
pageTitle="lesson"
|
||||||
ModelAbility={ModalEnum?.LESSON_ADD}
|
ModelAbility={ModalEnum?.LESSON_ADD}
|
||||||
canAdd={canAddLesson}/>
|
canAdd={canAddLesson}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.lesson"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.lesson"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,12 @@ export const useColumns = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
const columns: TableColumnsType<Lesson> = [
|
const columns: TableColumnsType<Lesson> = [
|
||||||
{ key: "sort", align: "center", width: 80, render: () => <DragHandleLesson /> },
|
{
|
||||||
|
key: "sort",
|
||||||
|
align: "center",
|
||||||
|
width: 80,
|
||||||
|
render: () => <DragHandleLesson />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t("columns.id"),
|
title: t("columns.id"),
|
||||||
dataIndex: "id",
|
dataIndex: "id",
|
||||||
|
|
@ -55,15 +60,15 @@ export const useColumns = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// canAddLesson ? (
|
// canAddLesson ? (
|
||||||
// <button
|
// <button
|
||||||
// onClick={() => handel_open_model(ModalEnum?.LESSON_ADD)}
|
// onClick={() => handel_open_model(ModalEnum?.LESSON_ADD)}
|
||||||
// className="add_button"
|
// className="add_button"
|
||||||
// >
|
// >
|
||||||
// {t("practical.add")} {t("models.lesson")} <FaPlus />
|
// {t("practical.add")} {t("models.lesson")} <FaPlus />
|
||||||
// </button>
|
// </button>
|
||||||
// ) : (
|
// ) : (
|
||||||
// ""
|
// ""
|
||||||
// ),
|
// ),
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "end",
|
align: "end",
|
||||||
|
|
|
||||||
|
|
@ -125,52 +125,52 @@ const AddPage: React.FC = () => {
|
||||||
Questions?.map((item: Question) => {
|
Questions?.map((item: Question) => {
|
||||||
const tags = processTags(item);
|
const tags = processTags(item);
|
||||||
console.log(item);
|
console.log(item);
|
||||||
const answers = item?.answers?.map((item:any,index:number)=>{
|
const answers = item?.answers?.map((item: any, index: number) => {
|
||||||
return {
|
return {
|
||||||
order:index,
|
order: index,
|
||||||
...item
|
...item,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
console.log(answers);
|
console.log(answers);
|
||||||
|
|
||||||
mutate({
|
mutate({
|
||||||
...item,
|
...item,
|
||||||
parent_id: newBseQuestionId,
|
parent_id: newBseQuestionId,
|
||||||
subject_id: subject_id,
|
subject_id: subject_id,
|
||||||
tags,
|
tags,
|
||||||
lessons_ids: [lesson_id],
|
lessons_ids: [lesson_id],
|
||||||
answers
|
answers,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
console.log(newBseQuestionId, "newBseQuestionId");
|
console.log(newBseQuestionId, "newBseQuestionId");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const tags = processTags(DataToSend);
|
const tags = processTags(DataToSend);
|
||||||
|
|
||||||
const answers = values?.answers?.map((item:any,index:number)=>{
|
const answers = values?.answers?.map((item: any, index: number) => {
|
||||||
return {
|
return {
|
||||||
order:index,
|
order: index,
|
||||||
...item
|
...item,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
const NewQuestion = {
|
const NewQuestion = {
|
||||||
...values,
|
...values,
|
||||||
subject_id: subject_id,
|
subject_id: subject_id,
|
||||||
tags,
|
tags,
|
||||||
lessons_ids: [lesson_id],
|
lessons_ids: [lesson_id],
|
||||||
canAnswersBeShuffled,
|
canAnswersBeShuffled,
|
||||||
answers
|
answers,
|
||||||
}
|
};
|
||||||
console.clear()
|
console.clear();
|
||||||
console.log(NewQuestion,"NewQuestion");
|
console.log(NewQuestion, "NewQuestion");
|
||||||
|
|
||||||
mutate(NewQuestion);
|
mutate(NewQuestion);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// console.log(SavedQuestionData);
|
// console.log(SavedQuestionData);
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// if (
|
// if (
|
||||||
// isSuccessAsync &&
|
// isSuccessAsync &&
|
||||||
|
|
@ -191,12 +191,12 @@ const AddPage: React.FC = () => {
|
||||||
// let cleanedAnswers = cleanObject(SavedQuestionData);
|
// let cleanedAnswers = cleanObject(SavedQuestionData);
|
||||||
// let noChange = hasItems(cleanedAnswers);
|
// let noChange = hasItems(cleanedAnswers);
|
||||||
// console.log(SavedQuestionData);
|
// console.log(SavedQuestionData);
|
||||||
|
|
||||||
// useSaveOnDisconnect(noChange, QUESTION_OBJECT_KEY, SavedQuestionData);
|
// useSaveOnDisconnect(noChange, QUESTION_OBJECT_KEY, SavedQuestionData);
|
||||||
|
|
||||||
// const SavedData = getLocalStorageQuestions(QUESTION_OBJECT_KEY);
|
// const SavedData = getLocalStorageQuestions(QUESTION_OBJECT_KEY);
|
||||||
// console.log(SavedData);
|
// console.log(SavedData);
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
navigate(-1);
|
navigate(-1);
|
||||||
// if (!noChange) {
|
// if (!noChange) {
|
||||||
|
|
@ -206,7 +206,7 @@ const AddPage: React.FC = () => {
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isBseQuestion ) {
|
if (isBseQuestion) {
|
||||||
return (
|
return (
|
||||||
<div className="exercise_add">
|
<div className="exercise_add">
|
||||||
<FormikForm
|
<FormikForm
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -31,31 +31,36 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
|
||||||
<TextField
|
<TextField
|
||||||
className="textarea_exercise"
|
className="textarea_exercise"
|
||||||
placeholder={"choice"}
|
placeholder={"choice"}
|
||||||
label2={t(`input.choice`) + ` ` +`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
|
label2={
|
||||||
|
t(`input.choice`) +
|
||||||
|
` ` +
|
||||||
|
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
|
||||||
|
}
|
||||||
name={index}
|
name={index}
|
||||||
id={`choice_${index + 1}`}
|
id={`choice_${index + 1}`}
|
||||||
type="TextArea"
|
type="TextArea"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImageBoxField name={`answers.${index}.content_image`} />
|
|
||||||
|
|
||||||
<div className="answer_status">
|
<ImageBoxField name={`answers.${index}.content_image`} />
|
||||||
|
|
||||||
<CheckboxField
|
<div className="answer_status">
|
||||||
className=""
|
<CheckboxField
|
||||||
label="The_correct_answer"
|
className=""
|
||||||
name={index}
|
label="The_correct_answer"
|
||||||
type="Checkbox"
|
name={index}
|
||||||
|
type="Checkbox"
|
||||||
/>
|
/>
|
||||||
<p className="delete_question_options">
|
<p className="delete_question_options">
|
||||||
{t("header.delete_choice")}
|
{t("header.delete_choice")}
|
||||||
<GoTrash className="trash_icon" onClick={handleDeleteChoice} size={17} />
|
<GoTrash
|
||||||
</p>
|
className="trash_icon"
|
||||||
</div>
|
onClick={handleDeleteChoice}
|
||||||
|
size={17}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="exercise_form_width">
|
<div className="exercise_form_width">
|
||||||
|
|
||||||
<ValidationField
|
<ValidationField
|
||||||
className=" "
|
className=" "
|
||||||
placeholder="_"
|
placeholder="_"
|
||||||
|
|
|
||||||
|
|
@ -37,32 +37,30 @@ const Choices = () => {
|
||||||
<Droppable droppableId="choices">
|
<Droppable droppableId="choices">
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<div {...provided.droppableProps} ref={provided.innerRef}>
|
<div {...provided.droppableProps} ref={provided.innerRef}>
|
||||||
{formik?.values?.answers?.map(
|
{formik?.values?.answers?.map((item: Choice, index: number) => {
|
||||||
(item: Choice, index: number) => {
|
// Use a unique identifier for draggableId
|
||||||
// Use a unique identifier for draggableId
|
const draggableId = item.name
|
||||||
const draggableId = item.name
|
? item.name.toString()
|
||||||
? item.name.toString()
|
: `item-${index}`;
|
||||||
: `item-${index}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable
|
<Draggable
|
||||||
key={draggableId}
|
key={draggableId}
|
||||||
draggableId={draggableId}
|
draggableId={draggableId}
|
||||||
index={index}
|
index={index}
|
||||||
>
|
>
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<div
|
<div
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
{...provided.draggableProps}
|
{...provided.draggableProps}
|
||||||
{...provided.dragHandleProps}
|
{...provided.dragHandleProps}
|
||||||
>
|
>
|
||||||
<ChoiceFields index={index} data={item} />
|
<ChoiceFields index={index} data={item} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Draggable>
|
</Draggable>
|
||||||
);
|
);
|
||||||
},
|
})}
|
||||||
)}
|
|
||||||
{provided.placeholder} {/* Placeholder for spacing */}
|
{provided.placeholder} {/* Placeholder for spacing */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,8 @@ const Form = () => {
|
||||||
|
|
||||||
<Choices parent_index={parent_index} />
|
<Choices parent_index={parent_index} />
|
||||||
|
|
||||||
{formik?.values?.Questions?.[parent_index]?.answers
|
{formik?.values?.Questions?.[parent_index]?.answers?.length <
|
||||||
?.length < 5 && (
|
5 && (
|
||||||
<p className="add_new_button">
|
<p className="add_new_button">
|
||||||
<FaCirclePlus
|
<FaCirclePlus
|
||||||
onClick={() => handleAddChoice(parent_index)}
|
onClick={() => handleAddChoice(parent_index)}
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,9 @@ const CheckboxField = ({
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const CheckboxhandleChange = (value: any) => {
|
const CheckboxhandleChange = (value: any) => {
|
||||||
|
const allAreZero = formik?.values?.Questions?.[parent_index]?.answers?.some(
|
||||||
const allAreZero = formik?.values?.Questions?.[
|
(item: any) => item.isCorrect === 1,
|
||||||
parent_index
|
);
|
||||||
]?.answers?.some((item: any) => item.isCorrect === 1);
|
|
||||||
if (allAreZero) {
|
if (allAreZero) {
|
||||||
formik?.values?.Questions?.[parent_index]?.answers.forEach(
|
formik?.values?.Questions?.[parent_index]?.answers.forEach(
|
||||||
(item: any, index: number) => {
|
(item: any, index: number) => {
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ const ChoiceFields = ({
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
const handleDeleteChoice = () => {
|
const handleDeleteChoice = () => {
|
||||||
const arrayLength =
|
const arrayLength = formik.values.Questions?.[parent_index].answers?.length;
|
||||||
formik.values.Questions?.[parent_index].answers?.length;
|
|
||||||
|
|
||||||
console.log(arrayLength);
|
console.log(arrayLength);
|
||||||
|
|
||||||
|
|
@ -42,46 +41,49 @@ const ChoiceFields = ({
|
||||||
const updatedAnswers = formik.values.Questions?.[
|
const updatedAnswers = formik.values.Questions?.[
|
||||||
parent_index
|
parent_index
|
||||||
].answers.filter((_: any, i: any) => i !== index);
|
].answers.filter((_: any, i: any) => i !== index);
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(`Questions[${parent_index}].answers`, updatedAnswers);
|
||||||
`Questions[${parent_index}].answers`,
|
|
||||||
updatedAnswers,
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="ChoiceFields">
|
<div className="ChoiceFields">
|
||||||
<TextField
|
<TextField
|
||||||
className="textarea_exercise"
|
className="textarea_exercise"
|
||||||
placeholder={"choice"}
|
placeholder={"choice"}
|
||||||
label2={t(`input.choice`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
|
label2={
|
||||||
name={index}
|
t(`input.choice`) +
|
||||||
parent_index={parent_index}
|
` ` +
|
||||||
type="TextArea"
|
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
|
||||||
/>
|
}
|
||||||
|
name={index}
|
||||||
|
parent_index={parent_index}
|
||||||
|
type="TextArea"
|
||||||
|
/>
|
||||||
|
|
||||||
<ImageBoxField name={`Questions.${parent_index}.answers.${index}.answer_image`} />
|
<ImageBoxField
|
||||||
|
name={`Questions.${parent_index}.answers.${index}.answer_image`}
|
||||||
<div className="answer_status">
|
/>
|
||||||
|
|
||||||
<CheckboxField
|
<div className="answer_status">
|
||||||
className=""
|
<CheckboxField
|
||||||
label="The_correct_answer"
|
className=""
|
||||||
name={index}
|
label="The_correct_answer"
|
||||||
type="Checkbox"
|
name={index}
|
||||||
parent_index={parent_index}
|
type="Checkbox"
|
||||||
/>
|
parent_index={parent_index}
|
||||||
<p className="delete_question_options">
|
/>
|
||||||
{t("header.delete_choice")}
|
<p className="delete_question_options">
|
||||||
<GoTrash className="trash_icon" onClick={handleDeleteChoice} size={17} />
|
{t("header.delete_choice")}
|
||||||
</p>
|
<GoTrash
|
||||||
</div>
|
className="trash_icon"
|
||||||
</div>
|
onClick={handleDeleteChoice}
|
||||||
|
size={17}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="exercise_form_width">
|
||||||
|
<ValidationField
|
||||||
|
|
||||||
<div className="exercise_form_width">
|
|
||||||
<ValidationField
|
|
||||||
className=" "
|
className=" "
|
||||||
placeholder="_"
|
placeholder="_"
|
||||||
name={`Questions.${parent_index}.answers.${index}.hint`}
|
name={`Questions.${parent_index}.answers.${index}.hint`}
|
||||||
|
|
@ -89,8 +91,8 @@ const ChoiceFields = ({
|
||||||
type="text"
|
type="text"
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,16 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
|
||||||
const handleDragEnd = (result: any) => {
|
const handleDragEnd = (result: any) => {
|
||||||
// Check if the item was dropped outside the list
|
// Check if the item was dropped outside the list
|
||||||
console.log(1);
|
console.log(1);
|
||||||
console.log(result.destination);
|
console.log(result.destination);
|
||||||
|
|
||||||
if (!result.destination) return;
|
if (!result.destination) return;
|
||||||
|
|
||||||
console.log(formik?.values?.Questions?.[parent_index]?.answers);
|
console.log(formik?.values?.Questions?.[parent_index]?.answers);
|
||||||
|
|
||||||
// Create a new array from the current answers
|
// Create a new array from the current answers
|
||||||
const items = Array.from(formik?.values?.Questions?.[parent_index]?.answers);
|
const items = Array.from(
|
||||||
|
formik?.values?.Questions?.[parent_index]?.answers,
|
||||||
|
);
|
||||||
console.log(items);
|
console.log(items);
|
||||||
// Remove the item from the original position
|
// Remove the item from the original position
|
||||||
const [reorderedItem] = items.splice(result.source.index, 1);
|
const [reorderedItem] = items.splice(result.source.index, 1);
|
||||||
|
|
@ -26,8 +28,8 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
|
||||||
items.splice(result.destination.index, 0, reorderedItem);
|
items.splice(result.destination.index, 0, reorderedItem);
|
||||||
|
|
||||||
// Update the order keys based on the new indices
|
// Update the order keys based on the new indices
|
||||||
console.log(items,"items");
|
console.log(items, "items");
|
||||||
|
|
||||||
const updatedItems = items.map((item, index) => ({
|
const updatedItems = items.map((item, index) => ({
|
||||||
...(item ?? {}),
|
...(item ?? {}),
|
||||||
order: index + 1, // Update order to be 1-based index
|
order: index + 1, // Update order to be 1-based index
|
||||||
|
|
@ -46,8 +48,8 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<div {...provided.droppableProps} ref={provided.innerRef}>
|
<div {...provided.droppableProps} ref={provided.innerRef}>
|
||||||
{(
|
{(
|
||||||
(formik?.values as any)?.Questions?.[parent_index]
|
(formik?.values as any)?.Questions?.[parent_index]?.answers ||
|
||||||
?.answers || []
|
[]
|
||||||
).map((item: Choice, index: number) => {
|
).map((item: Choice, index: number) => {
|
||||||
const draggableId = item.name
|
const draggableId = item.name
|
||||||
? item.name.toString()
|
? item.name.toString()
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ const File = ({
|
||||||
|
|
||||||
const { formik, t, isError, errorMsg } = useFormField(newName, props);
|
const { formik, t, isError, errorMsg } = useFormField(newName, props);
|
||||||
let imageUrl =
|
let imageUrl =
|
||||||
formik?.values?.Questions?.[parent_index]?.answers[name]
|
formik?.values?.Questions?.[parent_index]?.answers[name]?.answer_image ??
|
||||||
?.answer_image ?? null;
|
null;
|
||||||
// console.log(imageUrl);
|
// console.log(imageUrl);
|
||||||
|
|
||||||
const fileList: UploadFile[] = useMemo(() => {
|
const fileList: UploadFile[] = useMemo(() => {
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ const HintField = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
||||||
<label htmlFor={name} className="text">
|
<label htmlFor={name} className="text">
|
||||||
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
||||||
</label>
|
</label>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
hasFeedback
|
hasFeedback
|
||||||
validateStatus={isError ? "error" : ""}
|
validateStatus={isError ? "error" : ""}
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,8 @@ const Form = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{(
|
{(
|
||||||
(formik?.values as any)?.Questions?.[parent_index]
|
(formik?.values as any)?.Questions?.[parent_index]?.answers ||
|
||||||
?.answers || []
|
[]
|
||||||
).map((item: Choice, index: number) => {
|
).map((item: Choice, index: number) => {
|
||||||
return (
|
return (
|
||||||
<ChoiceFields
|
<ChoiceFields
|
||||||
|
|
@ -114,8 +114,8 @@ const Form = () => {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{formik?.values?.Questions?.[parent_index]?.answers
|
{formik?.values?.Questions?.[parent_index]?.answers?.length <
|
||||||
?.length < 5 && (
|
5 && (
|
||||||
<p className="add_new_button">
|
<p className="add_new_button">
|
||||||
<FaCirclePlus
|
<FaCirclePlus
|
||||||
onClick={() => handleAddChoice(parent_index)}
|
onClick={() => handleAddChoice(parent_index)}
|
||||||
|
|
|
||||||
|
|
@ -72,9 +72,13 @@ const Form = () => {
|
||||||
return (
|
return (
|
||||||
<Row className="w-100 exercise_form_container">
|
<Row className="w-100 exercise_form_container">
|
||||||
<div className="exercise_form">
|
<div className="exercise_form">
|
||||||
|
<ValidationField
|
||||||
<ValidationField className="textarea_exercise" name="content" label="main_question" type="TextArea" />
|
className="textarea_exercise"
|
||||||
<ImageBoxField name="image" />
|
name="content"
|
||||||
|
label="main_question"
|
||||||
|
type="TextArea"
|
||||||
|
/>
|
||||||
|
<ImageBoxField name="image" />
|
||||||
|
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -94,8 +98,8 @@ const Form = () => {
|
||||||
|
|
||||||
<Choices parent_index={parent_index} />
|
<Choices parent_index={parent_index} />
|
||||||
|
|
||||||
{formik?.values?.Questions?.[parent_index]?.answers
|
{formik?.values?.Questions?.[parent_index]?.answers?.length <
|
||||||
?.length < 5 && (
|
5 && (
|
||||||
<p className="add_new_button">
|
<p className="add_new_button">
|
||||||
<FaCirclePlus
|
<FaCirclePlus
|
||||||
onClick={() => handleAddChoice(parent_index)}
|
onClick={() => handleAddChoice(parent_index)}
|
||||||
|
|
@ -105,19 +109,17 @@ const Form = () => {
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="exercise_form_width">
|
||||||
<div className="exercise_form_width">
|
<ValidationField
|
||||||
|
className=" "
|
||||||
<ValidationField
|
placeholder="_"
|
||||||
className=" "
|
name={`answers.${parent_index}.hint`}
|
||||||
placeholder="_"
|
label="hint_question"
|
||||||
name={`answers.${parent_index}.hint`}
|
type="text"
|
||||||
label="hint_question"
|
style={{ width: "100%" }}
|
||||||
type="text"
|
/>
|
||||||
style={{ width: "100%" }}
|
<MaltySelectTag parent_index={parent_index} />
|
||||||
/>
|
</div>
|
||||||
<MaltySelectTag parent_index={parent_index} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ const HintField = ({
|
||||||
// console.log('Change:', e.target.value);
|
// console.log('Change:', e.target.value);
|
||||||
formik.setFieldValue(newName, e.target.value);
|
formik.setFieldValue(newName, e.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
<div className={`ValidationField w-100 ${className ?? ""} `}>
|
||||||
<label htmlFor={name} className="text">
|
<label htmlFor={name} className="text">
|
||||||
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
{label2 ? label2 : t(`input.${label ? label : name}`)}
|
||||||
</label>
|
</label>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
hasFeedback
|
hasFeedback
|
||||||
validateStatus={isError ? "error" : ""}
|
validateStatus={isError ? "error" : ""}
|
||||||
|
|
|
||||||
|
|
@ -36,34 +36,35 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<div className="exercise_forms">
|
||||||
<div className="exercise_forms">
|
<div className="ChoiceFields">
|
||||||
<div className="ChoiceFields">
|
<TextField
|
||||||
<TextField
|
className="textarea_exercise"
|
||||||
className="textarea_exercise"
|
placeholder={"question"}
|
||||||
placeholder={"question"}
|
label2={
|
||||||
label2={t(`input.question`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
|
t(`input.question`) +
|
||||||
name={index}
|
` ` +
|
||||||
id={`question_${index + 1}`}
|
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
|
||||||
type="TextArea"
|
}
|
||||||
/>
|
name={index}
|
||||||
|
id={`question_${index + 1}`}
|
||||||
|
type="TextArea"
|
||||||
|
/>
|
||||||
|
|
||||||
<ImageBoxField name={`Questions.${index}.image`} />
|
<ImageBoxField name={`Questions.${index}.image`} />
|
||||||
|
|
||||||
<div className="answer_status">
|
|
||||||
|
|
||||||
<p className="delete_question_options">
|
|
||||||
{t("header.delete_question")}
|
|
||||||
<GoTrash className="trash_icon" onClick={handleDeleteQuestion} size={17} />
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
<div className="answer_status">
|
||||||
|
<p className="delete_question_options">
|
||||||
|
{t("header.delete_question")}
|
||||||
|
<GoTrash
|
||||||
|
className="trash_icon"
|
||||||
|
onClick={handleDeleteQuestion}
|
||||||
|
size={17}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,32 @@
|
||||||
import React, { useState, useMemo } from 'react';
|
import React, { useState, useMemo } from "react";
|
||||||
import { Select, Spin } from 'antd';
|
import { Select, Spin } from "antd";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from "formik";
|
||||||
import { useDebounce } from '../../../../../../utils/useDebounce';
|
import { useDebounce } from "../../../../../../utils/useDebounce";
|
||||||
import { useGetAllTag } from '../../../../../../api/tags';
|
import { useGetAllTag } from "../../../../../../api/tags";
|
||||||
|
|
||||||
const MaltySelectTag = ({parent_index}:{parent_index:number}) => {
|
const MaltySelectTag = ({ parent_index }: { parent_index: number }) => {
|
||||||
const [searchValue, setSearchValue] = useState<string>('');
|
const [searchValue, setSearchValue] = useState<string>("");
|
||||||
const [fieldValue, setFieldValue] = useState<string>('');
|
const [fieldValue, setFieldValue] = useState<string>("");
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const values = formik?.values?.Questions?.[parent_index]?.tags;
|
const values = formik?.values?.Questions?.[parent_index]?.tags;
|
||||||
const handleChange = (value: string[]) => {
|
const handleChange = (value: string[]) => {
|
||||||
formik.setFieldValue(`Questions.[${parent_index}].tags`,value)
|
formik.setFieldValue(`Questions.[${parent_index}].tags`, value);
|
||||||
setSearchValue('');
|
setSearchValue("");
|
||||||
setFieldValue('');
|
setFieldValue("");
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = useDebounce((value: string) => {
|
const handleSearch = useDebounce((value: string) => {
|
||||||
setSearchValue(value);
|
setSearchValue(value);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleFieldChange = (value: string) => {
|
const handleFieldChange = (value: string) => {
|
||||||
setFieldValue(value);
|
setFieldValue(value);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
setSearchValue('');
|
setSearchValue("");
|
||||||
setFieldValue('');
|
setFieldValue("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data, isLoading } = useGetAllTag({
|
const { data, isLoading } = useGetAllTag({
|
||||||
|
|
@ -38,38 +35,38 @@ const MaltySelectTag = ({parent_index}:{parent_index:number}) => {
|
||||||
|
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
const options = data?.data ?? []
|
const options = data?.data ?? [];
|
||||||
const additionalData = options?.length < 1 && searchValue.length > 1 && !isLoading ? [{id:`new_${searchValue}`,name:searchValue}] :[];
|
const additionalData =
|
||||||
|
options?.length < 1 && searchValue.length > 1 && !isLoading
|
||||||
|
? [{ id: `new_${searchValue}`, name: searchValue }]
|
||||||
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='SelectTag'>
|
<div className="SelectTag">
|
||||||
|
<label htmlFor="">{t("models.tag")}</label>
|
||||||
<label htmlFor="">
|
<Select
|
||||||
{t("models.tag")}
|
mode="multiple"
|
||||||
</label>
|
allowClear
|
||||||
<Select
|
style={{ width: "100%", height: "40px" }}
|
||||||
mode="multiple"
|
placeholder=""
|
||||||
allowClear
|
fieldNames={{ label: "name", value: "id" }}
|
||||||
style={{ width: '100%' ,height:"40px"}}
|
onChange={handleChange}
|
||||||
placeholder=""
|
options={[...options, ...additionalData]}
|
||||||
fieldNames={{ label: 'name', value: 'id' }}
|
filterOption={false}
|
||||||
onChange={handleChange}
|
loading={isLoading}
|
||||||
options={[...options,...additionalData]}
|
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
|
||||||
filterOption={false}
|
onSearch={(value) => {
|
||||||
loading={isLoading}
|
handleSearch(value);
|
||||||
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
|
handleFieldChange(value);
|
||||||
onSearch={(value) => {
|
}}
|
||||||
handleSearch(value);
|
searchValue={fieldValue}
|
||||||
handleFieldChange(value);
|
onDropdownVisibleChange={(open) => {
|
||||||
}}
|
if (!open) {
|
||||||
searchValue={fieldValue}
|
handleBlur();
|
||||||
onDropdownVisibleChange={(open) => {
|
}
|
||||||
if (!open) {
|
}}
|
||||||
handleBlur();
|
value={values ?? []}
|
||||||
}
|
/>
|
||||||
}}
|
|
||||||
value={values ?? []}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ const Form = () => {
|
||||||
}, [Success]);
|
}, [Success]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(formik.values,"formik.values");
|
console.log(formik.values, "formik.values");
|
||||||
|
|
||||||
setSavedQuestionData(formik.values);
|
setSavedQuestionData(formik.values);
|
||||||
}, [formik?.values]);
|
}, [formik?.values]);
|
||||||
|
|
||||||
|
|
@ -42,15 +42,20 @@ const Form = () => {
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(formik?.values);
|
console.log(formik?.values);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="w-100 exercise_form_container">
|
<Row className="w-100 exercise_form_container">
|
||||||
<div className="exercise_form">
|
<div className="exercise_form">
|
||||||
<ValidationField className="textarea_exercise" name="content" label="answer_content" type="TextArea" />
|
<ValidationField
|
||||||
|
className="textarea_exercise"
|
||||||
|
name="content"
|
||||||
|
label="answer_content"
|
||||||
|
type="TextArea"
|
||||||
|
/>
|
||||||
<ImageBoxField name="content_image" />
|
<ImageBoxField name="content_image" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Choices />
|
<Choices />
|
||||||
{formik?.values?.answers?.length < 5 && (
|
{formik?.values?.answers?.length < 5 && (
|
||||||
<p className="add_new_button">
|
<p className="add_new_button">
|
||||||
|
|
@ -60,8 +65,7 @@ const Form = () => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="exercise_form_width">
|
<div className="exercise_form_width">
|
||||||
|
<ValidationField
|
||||||
<ValidationField
|
|
||||||
className=" "
|
className=" "
|
||||||
placeholder="_"
|
placeholder="_"
|
||||||
name="hint"
|
name="hint"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export const getInitialValues = (objectToEdit: Question): any => {
|
||||||
return { ...item, key: index };
|
return { ...item, key: index };
|
||||||
});
|
});
|
||||||
console.log(objectToEdit);
|
console.log(objectToEdit);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: objectToEdit?.id ?? null,
|
id: objectToEdit?.id ?? null,
|
||||||
content: objectToEdit?.content ?? "",
|
content: objectToEdit?.content ?? "",
|
||||||
|
|
@ -47,7 +47,7 @@ export const getInitialValuesBase = (objectToEdit: Question): any => {
|
||||||
name: tag?.name,
|
name: tag?.name,
|
||||||
key: `${tag?.id}_key_${tag?.name}`,
|
key: `${tag?.id}_key_${tag?.name}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ? 1 : 0,
|
canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ? 1 : 0,
|
||||||
|
|
@ -96,7 +96,7 @@ export const getValidationSchemaBase = () => {
|
||||||
|
|
||||||
export function processTags(DataToSend: any) {
|
export function processTags(DataToSend: any) {
|
||||||
console.log(DataToSend?.tags);
|
console.log(DataToSend?.tags);
|
||||||
|
|
||||||
const oldTags = DataToSend?.tags
|
const oldTags = DataToSend?.tags
|
||||||
?.map((item: any, index: number) => {
|
?.map((item: any, index: number) => {
|
||||||
if (typeof item === "number") {
|
if (typeof item === "number") {
|
||||||
|
|
@ -108,16 +108,16 @@ export function processTags(DataToSend: any) {
|
||||||
const newTags = DataToSend?.tags
|
const newTags = DataToSend?.tags
|
||||||
?.map((item: any, index: number) => {
|
?.map((item: any, index: number) => {
|
||||||
console.log(item);
|
console.log(item);
|
||||||
|
|
||||||
if (typeof item === "string" && item !== "") {
|
if (typeof item === "string" && item !== "") {
|
||||||
console.log(item);
|
console.log(item);
|
||||||
|
|
||||||
return { name: item };
|
return { name: item };
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((item: any) => item !== undefined);
|
.filter((item: any) => item !== undefined);
|
||||||
console.log(newTags);
|
console.log(newTags);
|
||||||
console.log(oldTags);
|
console.log(oldTags);
|
||||||
|
|
||||||
return { new: newTags, old: oldTags };
|
return { new: newTags, old: oldTags };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,15 +74,17 @@ const TableHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="question"
|
pageTitle="question"
|
||||||
ModelAbility={ModalEnum?.QUESTION_ACCEPT}
|
ModelAbility={ModalEnum?.QUESTION_ACCEPT}
|
||||||
canAdd={canAddQuestion}
|
canAdd={canAddQuestion}
|
||||||
locationToNavigate={`${ABILITIES_ENUM?.QUESTION}/add`}
|
locationToNavigate={`${ABILITIES_ENUM?.QUESTION}/add`}
|
||||||
openModel={false}/>
|
openModel={false}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.question"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.question"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<DeleteModels
|
<DeleteModels
|
||||||
|
|
|
||||||
|
|
@ -67,12 +67,12 @@ export const useColumns = () => {
|
||||||
render: (text, record) =>
|
render: (text, record) =>
|
||||||
record?.canAnswersBeShuffled ? t("practical.yes") : t("practical.no"),
|
record?.canAnswersBeShuffled ? t("practical.yes") : t("practical.no"),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '#',
|
title: "#",
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
||||||
render: (_text, record, index) => {
|
render: (_text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<ActionButtons
|
<ActionButtons
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import ValidationField from '../../../../Components/ValidationField/ValidationField'
|
import ValidationField from "../../../../Components/ValidationField/ValidationField";
|
||||||
import { Col, Row } from "reactstrap";
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
|
|
@ -7,19 +7,16 @@ const FilterForm = () => {
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FilterForm
|
export default FilterForm;
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,15 @@ const TableWithHeader = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<PageHeader
|
<PageHeader
|
||||||
pageTitle="subjects"
|
pageTitle="subjects"
|
||||||
ModelAbility={ModalEnum?.SUBJECT_ADD}
|
ModelAbility={ModalEnum?.SUBJECT_ADD}
|
||||||
canAdd={canAddSubject}/>
|
canAdd={canAddSubject}
|
||||||
<FilterLayout
|
/>
|
||||||
sub_children={<FilterForm/>}
|
<FilterLayout
|
||||||
filterTitle="sidebar.subjects"/>
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="sidebar.subjects"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
|
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,11 @@ import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import ActionButtons from "../../../../Components/Table/ActionButtons";
|
import ActionButtons from "../../../../Components/Table/ActionButtons";
|
||||||
import { canDeleteSubject, canEditSubject, canShowSubject } from "../../../../utils/hasAbilityFn";
|
import {
|
||||||
|
canDeleteSubject,
|
||||||
|
canEditSubject,
|
||||||
|
canShowSubject,
|
||||||
|
} from "../../../../utils/hasAbilityFn";
|
||||||
import { ABILITIES_ENUM } from "../../../../enums/abilities";
|
import { ABILITIES_ENUM } from "../../../../enums/abilities";
|
||||||
import { Subject } from "../../../../types/Subject";
|
import { Subject } from "../../../../types/Subject";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,7 @@ const FormField = ({ isLoading }: FormFieldType) => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button disabled={isLoading} type="submit" className="auth_submit_button">
|
||||||
disabled={isLoading}
|
|
||||||
type="submit"
|
|
||||||
className="auth_submit_button"
|
|
||||||
>
|
|
||||||
{t("practical.login")}
|
{t("practical.login")}
|
||||||
</button>
|
</button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -19,26 +19,23 @@ const LoginForm = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { login } = useAuthState();
|
const { login } = useAuthState();
|
||||||
|
|
||||||
const LoginData = {
|
const LoginData = {
|
||||||
...data,
|
...data,
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
const LocalType = getLocalStorage(USER_KEY)?.type ?? false ;
|
const LocalType = getLocalStorage(USER_KEY)?.type ?? false;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (isSuccess) {
|
||||||
if(isSuccess){
|
login(LoginData?.data as any);
|
||||||
login(LoginData?.data as any)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}, [isSuccess])
|
}, [isSuccess]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if(LocalType ){
|
|
||||||
window.location.href = ("/")
|
|
||||||
}
|
|
||||||
}, [LocalType])
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (LocalType) {
|
||||||
|
window.location.href = "/";
|
||||||
|
}
|
||||||
|
}, [LocalType]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="LoginForm">
|
<div className="LoginForm">
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const Auth = () => {
|
||||||
<div className="Auth">
|
<div className="Auth">
|
||||||
<div className="In_Auth">
|
<div className="In_Auth">
|
||||||
{/* <header> */}
|
{/* <header> */}
|
||||||
{/* <h1>{t("header.Welcome")}</h1>
|
{/* <h1>{t("header.Welcome")}</h1>
|
||||||
<p>{t("header.Enter your email and password to log in")}</p> */}
|
<p>{t("header.Enter your email and password to log in")}</p> */}
|
||||||
{/* </header> */}
|
{/* </header> */}
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,7 @@ const Dummy = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
|
useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
|
||||||
|
|
||||||
return (
|
return <div className="DummyHomePage"></div>;
|
||||||
<div className="DummyHomePage">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Dummy;
|
export default Dummy;
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,12 @@ const Unit = React.lazy(() => import("./Pages/Admin/Unit/Page"));
|
||||||
const Lesson = React.lazy(() => import("./Pages/Admin/lesson/Page"));
|
const Lesson = React.lazy(() => import("./Pages/Admin/lesson/Page"));
|
||||||
|
|
||||||
const Question = React.lazy(() => import("./Pages/Admin/question/Page"));
|
const Question = React.lazy(() => import("./Pages/Admin/question/Page"));
|
||||||
const AddQuestionPage = React.lazy(() => import("./Pages/Admin/question/AddPage"));
|
const AddQuestionPage = React.lazy(
|
||||||
const EditQuestionPage = React.lazy(() => import("./Pages/Admin/question/EditPage"));
|
() => import("./Pages/Admin/question/AddPage"),
|
||||||
|
);
|
||||||
|
const EditQuestionPage = React.lazy(
|
||||||
|
() => import("./Pages/Admin/question/EditPage"),
|
||||||
|
);
|
||||||
|
|
||||||
const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
|
const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
|
||||||
const Student = React.lazy(() => import("./Pages/Admin/Student/Page"));
|
const Student = React.lazy(() => import("./Pages/Admin/Student/Page"));
|
||||||
|
|
@ -27,7 +31,7 @@ export const menuItems: TMenuItem[] = [
|
||||||
{
|
{
|
||||||
header: "page_header.dashboard",
|
header: "page_header.dashboard",
|
||||||
element: <Dummy />,
|
element: <Dummy />,
|
||||||
icon: <TbCategory />,
|
icon: <TbCategory />,
|
||||||
text: "sidebar.dashboard",
|
text: "sidebar.dashboard",
|
||||||
path: "/",
|
path: "/",
|
||||||
abilities: ABILITIES_ENUM?.PASS,
|
abilities: ABILITIES_ENUM?.PASS,
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination_antd {
|
||||||
.pagination_antd{
|
|
||||||
margin-inline: 16px !important;
|
margin-inline: 16px !important;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user