Merge branch 'dev' of https://git.point-dev.net/Karimaldeen/Quiz_dashboard into dev
This commit is contained in:
commit
7b966d93ed
1
.env.example
Normal file
1
.env.example
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
REACT_APP_BASE_URL=
|
||||||
1
package-lock.json
generated
1
package-lock.json
generated
|
|
@ -12782,7 +12782,6 @@
|
||||||
"version": "2.0.15",
|
"version": "2.0.15",
|
||||||
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.15.tgz",
|
||||||
"integrity": "sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==",
|
"integrity": "sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
"qr.js": "0.0.0"
|
"qr.js": "0.0.0"
|
||||||
|
|
|
||||||
9417
pnpm-lock.yaml
9417
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,11 +1,11 @@
|
||||||
import { Divider } from 'antd'
|
import { Divider } from "antd";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import { RxHome } from "react-icons/rx";
|
import { RxHome } from "react-icons/rx";
|
||||||
|
|
||||||
const AddressCard = ({ data }: { data: any }) => {
|
const AddressCard = ({ data }: { data: any }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div className='address_card'>
|
<div className="address_card">
|
||||||
<h5>{t("practical.address")}</h5>
|
<h5>{t("practical.address")}</h5>
|
||||||
<Divider />
|
<Divider />
|
||||||
<div className="address_card_body">
|
<div className="address_card_body">
|
||||||
|
|
@ -20,9 +20,7 @@ const AddressCard = ({ data }: { data: any }) => {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default AddressCard
|
|
||||||
|
|
||||||
|
|
||||||
|
export default AddressCard;
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import { Divider } from 'antd';
|
import { Divider } from "antd";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import ImageBoxField from '../CustomFields/ImageBoxField/ImageBoxField';
|
import ImageBoxField from "../CustomFields/ImageBoxField/ImageBoxField";
|
||||||
|
|
||||||
const AttachmentsCard = ({ data }: { data?: any }) => {
|
const AttachmentsCard = ({ data }: { data?: any }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='attachments_card'>
|
<div className="attachments_card">
|
||||||
<h5>{t("practical.address")}</h5>
|
<h5>{t("practical.address")}</h5>
|
||||||
<Divider />
|
<Divider />
|
||||||
<div className='attachments_body'>
|
<div className="attachments_body">
|
||||||
<h5>{t("practical.id_photo")}</h5>
|
<h5>{t("practical.id_photo")}</h5>
|
||||||
{/* {data?.map((address:any)=>( */}
|
{/* {data?.map((address:any)=>( */}
|
||||||
<span>
|
<span>
|
||||||
|
|
@ -18,7 +18,7 @@ const AttachmentsCard = ({data}:{data?:any}) => {
|
||||||
{/* ))} */}
|
{/* ))} */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default AttachmentsCard
|
export default AttachmentsCard;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,24 @@
|
||||||
import { Button, Divider } from 'antd'
|
import { Button, Divider } from "antd";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import { canAddReSeller } from '../../utils/hasAbilityFn';
|
import { canAddReSeller } from "../../utils/hasAbilityFn";
|
||||||
|
|
||||||
const InfoCard = ({ data, name, status,withButton = false,handleClick}:{ data:any, name:any, status:any,withButton?:boolean,handleClick?:() => void}) => {
|
const InfoCard = ({
|
||||||
|
data,
|
||||||
|
name,
|
||||||
|
status,
|
||||||
|
withButton = false,
|
||||||
|
handleClick,
|
||||||
|
}: {
|
||||||
|
data: any;
|
||||||
|
name: any;
|
||||||
|
status: any;
|
||||||
|
withButton?: boolean;
|
||||||
|
handleClick?: () => void;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='info_card'>
|
<div className="info_card">
|
||||||
<div className="info_card_header">
|
<div className="info_card_header">
|
||||||
<img src="/Image/faker_user.png " alt="" />
|
<img src="/Image/faker_user.png " alt="" />
|
||||||
<div className="student_name_and_sub">
|
<div className="student_name_and_sub">
|
||||||
|
|
@ -22,18 +34,16 @@ const InfoCard = ({ data, name, status,withButton = false,handleClick}:{ data:an
|
||||||
<p>{student?.value}</p>
|
<p>{student?.value}</p>
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
{withButton ?
|
{withButton
|
||||||
canAddReSeller &&
|
? canAddReSeller && (
|
||||||
<Button onClick={handleClick} className='info_card_button'>
|
<Button onClick={handleClick} className="info_card_button">
|
||||||
{t("practical.collecting_an_amount")}
|
{t("practical.collecting_an_amount")}
|
||||||
</Button>
|
</Button>
|
||||||
|
)
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default InfoCard
|
|
||||||
|
|
||||||
|
|
||||||
|
export default InfoCard;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ export const StudentParamInfo = [
|
||||||
{ key: "sex", value: "male" },
|
{ key: "sex", value: "male" },
|
||||||
{ key: "sex", value: "male" },
|
{ key: "sex", value: "male" },
|
||||||
{ key: "sex", value: "male" },
|
{ key: "sex", value: "male" },
|
||||||
{key:"sex" , value:"male"}
|
{ key: "sex", value: "male" },
|
||||||
]
|
];
|
||||||
|
|
||||||
export const ReSellerParamInfo = [
|
export const ReSellerParamInfo = [
|
||||||
{ key: "رقم الهوية", value: "12i9128921019" },
|
{ key: "رقم الهوية", value: "12i9128921019" },
|
||||||
|
|
@ -15,13 +15,16 @@ export const ReSellerParamInfo = [
|
||||||
{ key: "تاريخ الإضافة", value: "1/10/2010" },
|
{ key: "تاريخ الإضافة", value: "1/10/2010" },
|
||||||
{ key: "تاريخ الإضافة", value: "1/10/2010" },
|
{ key: "تاريخ الإضافة", value: "1/10/2010" },
|
||||||
{ key: "تاريخ الإضافة", value: "1/10/2010" },
|
{ key: "تاريخ الإضافة", value: "1/10/2010" },
|
||||||
]
|
];
|
||||||
|
|
||||||
export const StudentAddressInfo = [
|
export const StudentAddressInfo = [
|
||||||
{ key: "address", value: "moa moamasom aoms omaosm oasm oasm oasm asm aom" },
|
{ key: "address", value: "moa moamasom aoms omaosm oasm oasm oasm asm aom" },
|
||||||
]
|
];
|
||||||
|
|
||||||
export const ReSellerAddressInfo = [
|
export const ReSellerAddressInfo = [
|
||||||
{key:"governorate" , value:"moa moamasom aoms omaosm oasm oasm oasm asm aom"},
|
{
|
||||||
|
key: "governorate",
|
||||||
|
value: "moa moamasom aoms omaosm oasm oasm oasm asm aom",
|
||||||
|
},
|
||||||
{ key: "address", value: "moa moamasom aoms omaosm oasm oasm oasm asm aom" },
|
{ key: "address", value: "moa moamasom aoms omaosm oasm oasm oasm asm aom" },
|
||||||
]
|
];
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const ImageBoxField = ({ name }: 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);
|
||||||
const [t] = useTranslation()
|
const [t] = useTranslation();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value instanceof File) {
|
if (value instanceof File) {
|
||||||
generateImagePreview(value, setImagePreview);
|
generateImagePreview(value, setImagePreview);
|
||||||
|
|
@ -32,8 +32,8 @@ const ImageBoxField = ({ name }: any) => {
|
||||||
const maxSize = 2 * 1024 * 1024;
|
const maxSize = 2 * 1024 * 1024;
|
||||||
|
|
||||||
if (file.size > maxSize) {
|
if (file.size > maxSize) {
|
||||||
alert(t('validation.File_size_exceeds_2_MB_limit.'));
|
alert(t("validation.File_size_exceeds_2_MB_limit."));
|
||||||
event.target.value = '';
|
event.target.value = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
|
||||||
|
|
||||||
// Helper function to generate image preview from a File
|
// Helper function to generate image preview from a File
|
||||||
|
|
||||||
const ImageBoxFieldMemo = memo(({ form,field }: any) => {
|
const ImageBoxFieldMemo = memo(
|
||||||
const {values,setFieldValue} = form
|
({ form, field }: any) => {
|
||||||
|
const { values, setFieldValue } = form;
|
||||||
const { name } = field;
|
const { name } = field;
|
||||||
const value = getNestedValue(values, name);
|
const value = getNestedValue(values, name);
|
||||||
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||||
|
|
@ -33,8 +34,8 @@ import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
|
||||||
const maxSize = 2 * 1024 * 1024;
|
const maxSize = 2 * 1024 * 1024;
|
||||||
|
|
||||||
if (file.size > maxSize) {
|
if (file.size > maxSize) {
|
||||||
alert(t('validation.File_size_exceeds_2_MB_limit.'));
|
alert(t("validation.File_size_exceeds_2_MB_limit."));
|
||||||
event.target.value = '';
|
event.target.value = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,8 +99,10 @@ import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, (prevProps, nextProps) => {
|
},
|
||||||
return areFieldPropsEqual(prevProps, nextProps)
|
(prevProps, nextProps) => {
|
||||||
});
|
return areFieldPropsEqual(prevProps, nextProps);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
export default ImageBoxFieldMemo;
|
export default ImageBoxFieldMemo;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import { BlockMath } from 'react-katex';
|
import { BlockMath } from "react-katex";
|
||||||
import 'katex/dist/katex.min.css';
|
import "katex/dist/katex.min.css";
|
||||||
|
|
||||||
|
|
||||||
const LatexPreview = ({ latex }: { latex: string }) => {
|
const LatexPreview = ({ latex }: { latex: string }) => {
|
||||||
// console.log(latex);
|
// console.log(latex);
|
||||||
|
|
@ -10,13 +9,7 @@ const LatexPreview = ({ latex }: { latex: string }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<BlockMath>{latex}</BlockMath>
|
||||||
|
|
||||||
<BlockMath>
|
|
||||||
{latex}
|
|
||||||
</BlockMath>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,19 @@ 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 [NewAdditionalData, setNewAdditionalData] = useState({})
|
const [NewAdditionalData, setNewAdditionalData] = useState({});
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const handleChange = (value: any, option: any) => {
|
const handleChange = (value: any, option: any) => {
|
||||||
console.log(option);
|
console.log(option);
|
||||||
console.log(value);
|
console.log(value);
|
||||||
const newSelectedOption = option?.pop()
|
const newSelectedOption = option?.pop();
|
||||||
console.log(newSelectedOption);
|
console.log(newSelectedOption);
|
||||||
|
|
||||||
const newObject = {
|
const newObject = {
|
||||||
id: newSelectedOption?.id,
|
id: newSelectedOption?.id,
|
||||||
name:newSelectedOption?.name
|
name: newSelectedOption?.name,
|
||||||
}
|
};
|
||||||
setNewAdditionalData(newObject)
|
setNewAdditionalData(newObject);
|
||||||
formik.setFieldValue("tags", value);
|
formik.setFieldValue("tags", value);
|
||||||
setSearchValue("");
|
setSearchValue("");
|
||||||
setFieldValue("");
|
setFieldValue("");
|
||||||
|
|
@ -34,7 +34,6 @@ const SelectTag: React.FC = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleFieldChange = (value: string) => {
|
const handleFieldChange = (value: string) => {
|
||||||
|
|
||||||
setFieldValue(value);
|
setFieldValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -48,12 +47,10 @@ const SelectTag: React.FC = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const initialData = formik?.values?.tags?.filter((item:any)=>{
|
const initialData =
|
||||||
return item?.id
|
formik?.values?.tags?.filter((item: any) => {
|
||||||
|
return item?.id;
|
||||||
}) ?? []
|
}) ?? [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const options = data?.data ?? [];
|
const options = data?.data ?? [];
|
||||||
const additionalData =
|
const additionalData =
|
||||||
|
|
@ -64,17 +61,20 @@ const SelectTag: React.FC = () => {
|
||||||
const value =
|
const value =
|
||||||
formik?.values?.tags?.map((item: any) => item?.id ?? item) ?? [];
|
formik?.values?.tags?.map((item: any) => item?.id ?? item) ?? [];
|
||||||
|
|
||||||
const AllOptions = [...options, ...additionalData,NewAdditionalData, ...(initialData)];
|
const AllOptions = [
|
||||||
|
...options,
|
||||||
|
...additionalData,
|
||||||
|
NewAdditionalData,
|
||||||
|
...initialData,
|
||||||
|
];
|
||||||
|
|
||||||
const uniqueOptions = Array.from(
|
const uniqueOptions = Array.from(
|
||||||
new Map(
|
new Map(
|
||||||
AllOptions
|
AllOptions.filter((item) => Object.keys(item).length > 0) // Filter out empty objects
|
||||||
.filter(item => Object.keys(item).length > 0) // Filter out empty objects
|
.map((item) => [item.id, item]), // Create [id, item] pairs to ensure uniqueness
|
||||||
.map(item => [item.id, item]) // Create [id, item] pairs to ensure uniqueness
|
).values(),
|
||||||
).values()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="SelectTag">
|
<div className="SelectTag">
|
||||||
<label htmlFor="">{t("models.tag")}</label>
|
<label htmlFor="">{t("models.tag")}</label>
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,13 @@ const SelectTagV2: React.FC = () => {
|
||||||
const { data, isLoading } = useGetAllTag({ name: searchValue });
|
const { data, isLoading } = useGetAllTag({ name: searchValue });
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
||||||
// Get selected tags from Formik
|
// Get selected tags from Formik
|
||||||
const CurrentTags = formik.values.tags ?? []; // Assuming tags are stored as array of objects
|
const CurrentTags = formik.values.tags ?? []; // Assuming tags are stored as array of objects
|
||||||
console.log(CurrentTags, "CurrentTags");
|
console.log(CurrentTags, "CurrentTags");
|
||||||
|
|
||||||
const NewShapeTags = CurrentTags?.map((item:any)=> {return item?.name ?? item })
|
const NewShapeTags = CurrentTags?.map((item: any) => {
|
||||||
|
return item?.name ?? item;
|
||||||
|
});
|
||||||
|
|
||||||
const handleChange = (_value: any[], option: any) => {
|
const handleChange = (_value: any[], option: any) => {
|
||||||
// console.log(option,"option");
|
// console.log(option,"option");
|
||||||
|
|
@ -51,7 +52,6 @@ const SelectTagV2: React.FC = () => {
|
||||||
|
|
||||||
console.log(additionalData);
|
console.log(additionalData);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="SelectTag">
|
<div className="SelectTag">
|
||||||
<label>{t("models.tag")}</label>
|
<label>{t("models.tag")}</label>
|
||||||
|
|
@ -77,7 +77,6 @@ const SelectTagV2: React.FC = () => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
value={NewShapeTags}
|
value={NewShapeTags}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ const SearchField: React.FC<Props> = ({ placeholder, searchBy }) => {
|
||||||
|
|
||||||
const handleInputChangeWithDebounce = useDebounce((value: string) => {
|
const handleInputChangeWithDebounce = useDebounce((value: string) => {
|
||||||
if (Number(page) > 1) {
|
if (Number(page) > 1) {
|
||||||
|
|
||||||
}
|
}
|
||||||
setFilter({
|
setFilter({
|
||||||
[searchBy]: value,
|
[searchBy]: value,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ const SearchFieldWithSelect: React.FC<Props> = ({
|
||||||
const filteredOptions = options.filter((option) =>
|
const filteredOptions = options.filter((option) =>
|
||||||
option.label.toLowerCase().includes(searchTerm.toLowerCase()),
|
option.label.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
const Type = localStorage.getItem('type');
|
const Type = localStorage.getItem("type");
|
||||||
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}>
|
||||||
|
|
@ -87,7 +87,7 @@ const SearchFieldWithSelect: React.FC<Props> = ({
|
||||||
<div>{option.label}</div>
|
<div>{option.label}</div>
|
||||||
{/* {withIcon && <IoSearch className="search__icon" />} */}
|
{/* {withIcon && <IoSearch className="search__icon" />} */}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,12 @@ const PaginationColumn = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { Filter, setFilter } = useFilterStateState();
|
const { Filter, setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
const handleChange = (value: string) => {
|
const handleChange = (value: string) => {
|
||||||
navigate(`?per_page=${value}`);
|
navigate(`?per_page=${value}`);
|
||||||
|
|
||||||
setFilter({
|
setFilter({
|
||||||
per_page:value
|
per_page: value,
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
import '../styles/index.scss';
|
import "../styles/index.scss";
|
||||||
import CustomInput from "../design-system/CustomInput";
|
import CustomInput from "../design-system/CustomInput";
|
||||||
import { Button } from "antd";
|
import { Button } from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
@ -24,22 +24,23 @@ const useFilter = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const FilterBody = ({ children }: IFilterBody) => {
|
const FilterBody = ({ children }: IFilterBody) => {
|
||||||
const [values, setValues] = useState({ name1: '', name2: '' });
|
const [values, setValues] = useState({ name1: "", name2: "" });
|
||||||
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = useCallback(
|
||||||
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target;
|
||||||
setValues((prev) => ({ ...prev, [name]: value }));
|
setValues((prev) => ({ ...prev, [name]: value }));
|
||||||
}, []);
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
console.log(values, "values");
|
console.log(values, "values");
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [t] = useTranslation();
|
||||||
const [t] = useTranslation()
|
|
||||||
return (
|
return (
|
||||||
<div className={`filter_body ${isBodyVisible ? 'visible' : 'hidden'}`}>
|
<div className={`filter_body ${isBodyVisible ? "visible" : "hidden"}`}>
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
{children}
|
{children}
|
||||||
<CustomInput
|
<CustomInput
|
||||||
|
|
@ -52,8 +53,10 @@ const useFilter = () => {
|
||||||
value={values.name2}
|
value={values.name2}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
<Button block htmlType="submit" type="primary" > {t("practical.submit")} </Button>
|
<Button block htmlType="submit" type="primary">
|
||||||
|
{" "}
|
||||||
|
{t("practical.submit")}{" "}
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Input } from 'antd';
|
import { Input } from "antd";
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
interface CustomInputProps {
|
interface CustomInputProps {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -7,16 +7,11 @@ interface CustomInputProps {
|
||||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomInput: React.FC<CustomInputProps> = React.memo(({ name, value, onChange }) => {
|
const CustomInput: React.FC<CustomInputProps> = React.memo(
|
||||||
|
({ name, value, onChange }) => {
|
||||||
console.log(`Rendering ${name}`); // For debugging purposes
|
console.log(`Rendering ${name}`); // For debugging purposes
|
||||||
return (
|
return <Input type="text" name={name} value={value} onChange={onChange} />;
|
||||||
<Input
|
},
|
||||||
type="text"
|
|
||||||
name={name}
|
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
export default CustomInput;
|
export default CustomInput;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
.filter_body {
|
.filter_body {
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: max-height 0.3s ease-out, opacity 0.3s ease-out, transform 0.3s ease-out;
|
transition:
|
||||||
|
max-height 0.3s ease-out,
|
||||||
|
opacity 0.3s ease-out,
|
||||||
|
transform 0.3s ease-out;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-20px);
|
transform: translateY(-20px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter_body.visible {
|
.filter_body.visible {
|
||||||
|
|
@ -30,4 +32,3 @@
|
||||||
width: 70%;
|
width: 70%;
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,23 +1,29 @@
|
||||||
import { Modal } from 'antd'
|
import { Modal } from "antd";
|
||||||
import TextArea from 'antd/es/input/TextArea'
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from "formik";
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
|
import { convertMathMLToLaTeX } from "../../utils/convertMathMLToLaTeX";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen,setCurrentValue}:{
|
|
||||||
name:string,
|
|
||||||
setLatex: (value:string)=> void,
|
|
||||||
Latex:string,
|
|
||||||
setIsModalOpen: (value:boolean)=> void ,
|
|
||||||
isModalOpen:boolean,
|
|
||||||
setCurrentValue:(value:string)=> void
|
|
||||||
|
|
||||||
|
const AddLaTexModal = ({
|
||||||
|
name,
|
||||||
|
setLatex,
|
||||||
|
Latex,
|
||||||
|
setIsModalOpen,
|
||||||
|
isModalOpen,
|
||||||
|
setCurrentValue,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
setLatex: (value: string) => void;
|
||||||
|
Latex: string;
|
||||||
|
setIsModalOpen: (value: boolean) => void;
|
||||||
|
isModalOpen: boolean;
|
||||||
|
setCurrentValue: (value: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const {values,setFieldValue,getFieldProps} = useFormikContext<any>()
|
const { values, setFieldValue, getFieldProps } = useFormikContext<any>();
|
||||||
|
|
||||||
const currentValue = getFieldProps(name).value
|
const currentValue = getFieldProps(name).value;
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const oldValue = currentValue ?? "";
|
const oldValue = currentValue ?? "";
|
||||||
const newLatex = convertMathMLToLaTeX(Latex);
|
const newLatex = convertMathMLToLaTeX(Latex);
|
||||||
|
|
@ -25,35 +31,39 @@ const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen,setCurren
|
||||||
|
|
||||||
if (newLatex) {
|
if (newLatex) {
|
||||||
setFieldValue(name, oldValue + " $$ " + newLatex + " $$ ");
|
setFieldValue(name, oldValue + " $$ " + newLatex + " $$ ");
|
||||||
setCurrentValue(oldValue + " $$ " +newLatex +" $$ ")
|
setCurrentValue(oldValue + " $$ " + newLatex + " $$ ");
|
||||||
setLatex("")
|
setLatex("");
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
} else {
|
} else {
|
||||||
setFieldValue(name, oldValue + " $$ " + Latex + " $$ ");
|
setFieldValue(name, oldValue + " $$ " + Latex + " $$ ");
|
||||||
setCurrentValue(oldValue + " $$ " +Latex +" $$ ")
|
setCurrentValue(oldValue + " $$ " + Latex + " $$ ");
|
||||||
setLatex("")
|
setLatex("");
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
setLatex("")
|
setLatex("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChangeInputLatex = (
|
const handleChangeInputLatex = (
|
||||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
) => {
|
) => {
|
||||||
const newValue = e.target.value;
|
const newValue = e.target.value;
|
||||||
setLatex(newValue)
|
setLatex(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [t] = useTranslation()
|
const [t] = useTranslation();
|
||||||
return (
|
return (
|
||||||
|
<Modal
|
||||||
<Modal footer={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
footer={false}
|
||||||
<div className='latexModal'>
|
open={isModalOpen}
|
||||||
<label className='mb-3'> {t("header.past_your_MMl_text")} </label>
|
onOk={handleOk}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
>
|
||||||
|
<div className="latexModal">
|
||||||
|
<label className="mb-3"> {t("header.past_your_MMl_text")} </label>
|
||||||
<TextArea
|
<TextArea
|
||||||
size="large"
|
size="large"
|
||||||
showCount
|
showCount
|
||||||
|
|
@ -67,17 +77,13 @@ const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen,setCurren
|
||||||
<div className="back_button pointer" onClick={handleCancel}>
|
<div className="back_button pointer" onClick={handleCancel}>
|
||||||
{t("practical.cancel")}
|
{t("practical.cancel")}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="add_button" onClick={handleOk}>
|
||||||
className="add_button"
|
|
||||||
onClick={handleOk}
|
|
||||||
>
|
|
||||||
{t(`practical.${"add"}`)}
|
{t(`practical.${"add"}`)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
)
|
export default AddLaTexModal;
|
||||||
}
|
|
||||||
|
|
||||||
export default AddLaTexModal
|
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,27 @@
|
||||||
import { Modal } from 'antd'
|
import { Modal } from "antd";
|
||||||
import TextArea from 'antd/es/input/TextArea'
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from "formik";
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
|
import { convertMathMLToLaTeX } from "../../utils/convertMathMLToLaTeX";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from "react-toastify";
|
||||||
import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
|
import { parseTextAndLatex } from "../../utils/parseTextAndLatex";
|
||||||
|
|
||||||
const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
|
|
||||||
name:string,
|
|
||||||
setLatex: (value:string)=> void,
|
|
||||||
Latex:any,
|
|
||||||
setIsModalOpen: (value:boolean)=> void ,
|
|
||||||
isModalOpen:boolean,
|
|
||||||
|
|
||||||
|
const EditLaTexModal = ({
|
||||||
|
name,
|
||||||
|
setLatex,
|
||||||
|
Latex,
|
||||||
|
setIsModalOpen,
|
||||||
|
isModalOpen,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
setLatex: (value: string) => void;
|
||||||
|
Latex: any;
|
||||||
|
setIsModalOpen: (value: boolean) => void;
|
||||||
|
isModalOpen: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const {values} = useFormikContext<any>()
|
const { values } = useFormikContext<any>();
|
||||||
const [Value, setValue] = useState(Latex?.text ?? Latex)
|
const [Value, setValue] = useState(Latex?.text ?? Latex);
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
console.log(1);
|
console.log(1);
|
||||||
|
|
@ -31,18 +36,16 @@ const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
|
||||||
|
|
||||||
if (newLatex) {
|
if (newLatex) {
|
||||||
const newArray = Preview?.map((item: any, index: number) => {
|
const newArray = Preview?.map((item: any, index: number) => {
|
||||||
if(item?.key)
|
if (item?.key) return item;
|
||||||
return item
|
});
|
||||||
})
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
toast.error(t("validation.that_is_not_a_valid_mml"))
|
toast.error(t("validation.that_is_not_a_valid_mml"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
setLatex("")
|
setLatex("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChangeInputLatex = (
|
const handleChangeInputLatex = (
|
||||||
|
|
@ -50,15 +53,19 @@ const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
|
||||||
) => {
|
) => {
|
||||||
const newValue = e.target.value;
|
const newValue = e.target.value;
|
||||||
console.log(newValue, "newValue");
|
console.log(newValue, "newValue");
|
||||||
setValue(newValue)
|
setValue(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [t] = useTranslation()
|
const [t] = useTranslation();
|
||||||
return (
|
return (
|
||||||
|
<Modal
|
||||||
<Modal footer={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
footer={false}
|
||||||
<div className='latexModal'>
|
open={isModalOpen}
|
||||||
<label className='mb-3'> {t("header.past_your_MMl_text")} </label>
|
onOk={handleOk}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
>
|
||||||
|
<div className="latexModal">
|
||||||
|
<label className="mb-3"> {t("header.past_your_MMl_text")} </label>
|
||||||
<TextArea
|
<TextArea
|
||||||
size="large"
|
size="large"
|
||||||
showCount
|
showCount
|
||||||
|
|
@ -66,24 +73,19 @@ const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
|
||||||
autoSize={{ minRows: 4, maxRows: 10 }}
|
autoSize={{ minRows: 4, maxRows: 10 }}
|
||||||
style={{ height: "400px" }}
|
style={{ height: "400px" }}
|
||||||
onChange={handleChangeInputLatex}
|
onChange={handleChangeInputLatex}
|
||||||
value={Value
|
value={Value}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<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")}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="add_button" onClick={handleOk}>
|
||||||
className="add_button"
|
|
||||||
onClick={handleOk}
|
|
||||||
>
|
|
||||||
{t(`practical.${"edit"}`)}
|
{t(`practical.${"edit"}`)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
)
|
export default EditLaTexModal;
|
||||||
}
|
|
||||||
|
|
||||||
export default EditLaTexModal
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
import TextArea from 'antd/es/input/TextArea';
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import React, { Suspense, useEffect, useState } from 'react';
|
import React, { Suspense, useEffect, useState } from "react";
|
||||||
import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
|
import { parseTextAndLatex } from "../../utils/parseTextAndLatex";
|
||||||
import LatexPreview from '../CustomFields/MathComponent';
|
import LatexPreview from "../CustomFields/MathComponent";
|
||||||
import { Checkbox } from 'antd';
|
import { Checkbox } from "antd";
|
||||||
import { CheckboxProps } from 'antd/lib';
|
import { CheckboxProps } from "antd/lib";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { FaPlus } from 'react-icons/fa';
|
import { FaPlus } from "react-icons/fa";
|
||||||
import { useObjectToEdit } from '../../zustand/ObjectToEditState';
|
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
|
||||||
import SpinContainer from '../Layout/SpinContainer';
|
import SpinContainer from "../Layout/SpinContainer";
|
||||||
import { areFieldPropsEqual } from './areFieldPropsEqual';
|
import { areFieldPropsEqual } from "./areFieldPropsEqual";
|
||||||
|
|
||||||
const AddLazyModal = React.lazy(() => import("./AddLaTexModal"));
|
const AddLazyModal = React.lazy(() => import("./AddLaTexModal"));
|
||||||
const EditLazyModal = React.lazy(() => import("./EditLaTexModal"));
|
const EditLazyModal = React.lazy(() => import("./EditLaTexModal"));
|
||||||
|
|
||||||
|
const LaTeXInputMemo: React.FC<any> = React.memo(
|
||||||
const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...props }) => {
|
({ field, form, label, ...props }) => {
|
||||||
const { name, value } = field;
|
const { name, value } = field;
|
||||||
|
|
||||||
const { setFieldValue, touched, errors, getFieldProps, values } = form;
|
const { setFieldValue, touched, errors, getFieldProps, values } = form;
|
||||||
|
|
@ -23,8 +23,7 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
|
||||||
const [showPreview, setShowPreview] = useState(false);
|
const [showPreview, setShowPreview] = useState(false);
|
||||||
const Preview = parseTextAndLatex(value ?? "");
|
const Preview = parseTextAndLatex(value ?? "");
|
||||||
|
|
||||||
|
const onPreviewChange: CheckboxProps["onChange"] = (e) => {
|
||||||
const onPreviewChange: CheckboxProps['onChange'] = (e) => {
|
|
||||||
setShowPreview(e.target.checked);
|
setShowPreview(e.target.checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -44,62 +43,65 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
|
||||||
// setIsEditModalOpen(true);
|
// setIsEditModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [curCentValue, setCurrentValue] = useState(value)
|
const [curCentValue, setCurrentValue] = useState(value);
|
||||||
const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
const handleChangeInput = (
|
||||||
setCurrentValue(e.target.value)
|
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
) => {
|
||||||
|
setCurrentValue(e.target.value);
|
||||||
};
|
};
|
||||||
const onBlur = () => {
|
const onBlur = () => {
|
||||||
if (curCentValue !== value) {
|
if (curCentValue !== value) {
|
||||||
setFieldValue(name, curCentValue);
|
setFieldValue(name, curCentValue);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Success) {
|
if (Success) {
|
||||||
setCurrentValue(null)
|
setCurrentValue(null);
|
||||||
}
|
}
|
||||||
}, [Success])
|
}, [Success]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value) {
|
if (value) {
|
||||||
setCurrentValue(value)
|
setCurrentValue(value);
|
||||||
}
|
}
|
||||||
}, [value])
|
}, [value]);
|
||||||
|
|
||||||
|
|
||||||
const isError = !!touched?.[name] && !!errors?.[name];
|
const isError = !!touched?.[name] && !!errors?.[name];
|
||||||
const errorMessage = isError ? errors?.[name] as string ?? "" : "" ;
|
const errorMessage = isError ? ((errors?.[name] as string) ?? "") : "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log(values);
|
console.log(values);
|
||||||
|
|
||||||
let metaName = name.substring(0, name.lastIndexOf('.'));
|
let metaName = name.substring(0, name.lastIndexOf("."));
|
||||||
if (metaName.includes('.') || metaName.includes('[')) { metaName += ".meta";} else {metaName += "meta"}
|
if (metaName.includes(".") || metaName.includes("[")) {
|
||||||
|
metaName += ".meta";
|
||||||
|
} else {
|
||||||
|
metaName += "meta";
|
||||||
|
}
|
||||||
const meta = getFieldProps(metaName).value;
|
const meta = getFieldProps(metaName).value;
|
||||||
console.log(metaName, meta);
|
console.log(metaName, meta);
|
||||||
const direction = meta?.direction === "ltr" ? "ltr" : "rtl"
|
const direction = meta?.direction === "ltr" ? "ltr" : "rtl";
|
||||||
|
|
||||||
const [Dir, setDir] = useState<"ltr" | "rtl">(direction)
|
const [Dir, setDir] = useState<"ltr" | "rtl">(direction);
|
||||||
|
|
||||||
const handleChangeDirection = () => {
|
const handleChangeDirection = () => {
|
||||||
if (Dir === "ltr") {
|
if (Dir === "ltr") {
|
||||||
setDir("rtl")
|
setDir("rtl");
|
||||||
setFieldValue(metaName,{...(meta ?? {}), direction:"rtl"})
|
setFieldValue(metaName, { ...(meta ?? {}), direction: "rtl" });
|
||||||
} else {
|
} else {
|
||||||
setDir("ltr")
|
setDir("ltr");
|
||||||
setFieldValue(metaName,{...(meta ?? {}), direction:"ltr"})
|
setFieldValue(metaName, { ...(meta ?? {}), direction: "ltr" });
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='LaTeXInput'>
|
<div className="LaTeXInput">
|
||||||
<label htmlFor={name} className="text">
|
<label htmlFor={name} className="text">
|
||||||
<div>{t(label || name)}</div> <div className='error_message'>{t(errorMessage)}</div>
|
<div>{t(label || name)}</div>{" "}
|
||||||
|
<div className="error_message">{t(errorMessage)}</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div className='LaTeXInputArea'>
|
<div className="LaTeXInputArea">
|
||||||
<TextArea
|
<TextArea
|
||||||
size="large"
|
size="large"
|
||||||
showCount
|
showCount
|
||||||
|
|
@ -112,30 +114,39 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
|
||||||
dir={Dir}
|
dir={Dir}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
<div className='LaTeXInputOptions'>
|
<div className="LaTeXInputOptions">
|
||||||
<Checkbox onChange={handleChangeDirection} checked={direction === "ltr"} >{t("header.change_direction")}</Checkbox>
|
<Checkbox
|
||||||
|
onChange={handleChangeDirection}
|
||||||
|
checked={direction === "ltr"}
|
||||||
|
>
|
||||||
|
{t("header.change_direction")}
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
{ShowLatexOption && (
|
{ShowLatexOption && (
|
||||||
<>
|
<>
|
||||||
<Checkbox onChange={onPreviewChange}>{t("header.show_preview")}</Checkbox>
|
<Checkbox onChange={onPreviewChange}>
|
||||||
<button type='button' className='addMML' onClick={showModal}>
|
{t("header.show_preview")}
|
||||||
|
</Checkbox>
|
||||||
|
<button type="button" className="addMML" onClick={showModal}>
|
||||||
<FaPlus /> {t("MML")}
|
<FaPlus /> {t("MML")}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showPreview && (
|
{showPreview && (
|
||||||
<div className='showPreviewInput'>
|
<div className="showPreviewInput">
|
||||||
{Preview?.map((item: any, index: number) => {
|
{Preview?.map((item: any, index: number) => {
|
||||||
if (item?.isLatex) {
|
if (item?.isLatex) {
|
||||||
console.log(item?.text);
|
console.log(item?.text);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span dir='ltr' key={index} onClick={() => handleEditModal(item)} className='LatexPreview'>
|
<span
|
||||||
|
dir="ltr"
|
||||||
|
key={index}
|
||||||
|
onClick={() => handleEditModal(item)}
|
||||||
|
className="LatexPreview"
|
||||||
|
>
|
||||||
<LatexPreview latex={item?.text} />
|
<LatexPreview latex={item?.text} />
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
@ -147,14 +158,28 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Suspense fallback={<SpinContainer />}>
|
<Suspense fallback={<SpinContainer />}>
|
||||||
<AddLazyModal name={name} Latex={Latex} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} setLatex={setLatex} setCurrentValue={setCurrentValue} />
|
<AddLazyModal
|
||||||
<EditLazyModal name={name} Latex={Latex} isModalOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} setLatex={setLatex} />
|
name={name}
|
||||||
|
Latex={Latex}
|
||||||
|
isModalOpen={isModalOpen}
|
||||||
|
setIsModalOpen={setIsModalOpen}
|
||||||
|
setLatex={setLatex}
|
||||||
|
setCurrentValue={setCurrentValue}
|
||||||
|
/>
|
||||||
|
<EditLazyModal
|
||||||
|
name={name}
|
||||||
|
Latex={Latex}
|
||||||
|
isModalOpen={isEditModalOpen}
|
||||||
|
setIsModalOpen={setIsEditModalOpen}
|
||||||
|
setLatex={setLatex}
|
||||||
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, (prevProps, nextProps) => {
|
},
|
||||||
return areFieldPropsEqual(prevProps, nextProps)
|
(prevProps, nextProps) => {
|
||||||
});
|
return areFieldPropsEqual(prevProps, nextProps);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
export default LaTeXInputMemo;
|
export default LaTeXInputMemo;
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
// utilityFunctions.ts
|
// utilityFunctions.ts
|
||||||
import { FieldProps } from 'formik';
|
import { FieldProps } from "formik";
|
||||||
|
|
||||||
export const areFieldPropsEqual = (
|
export const areFieldPropsEqual = (prevProps: any, nextProps: any): boolean => {
|
||||||
prevProps: any,
|
|
||||||
nextProps: any
|
|
||||||
): boolean => {
|
|
||||||
const prevError = prevProps.form.errors[prevProps.field.name];
|
const prevError = prevProps.form.errors[prevProps.field.name];
|
||||||
const nextError = nextProps.form.errors[nextProps.field.name];
|
const nextError = nextProps.form.errors[nextProps.field.name];
|
||||||
|
|
||||||
|
|
@ -14,7 +11,5 @@ export const areFieldPropsEqual = (
|
||||||
const prevValue = prevProps.field.value;
|
const prevValue = prevProps.field.value;
|
||||||
const nextValue = nextProps.field.value;
|
const nextValue = nextProps.field.value;
|
||||||
|
|
||||||
return (
|
return false;
|
||||||
false
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const NavBarRightSide = () => {
|
||||||
icon={<CiCirclePlus size={25} />}
|
icon={<CiCirclePlus size={25} />}
|
||||||
/>
|
/>
|
||||||
<TooltipComp
|
<TooltipComp
|
||||||
onClick={()=>(Navigate('/notifications'))}
|
onClick={() => Navigate("/notifications")}
|
||||||
className="NotificationsIcon"
|
className="NotificationsIcon"
|
||||||
note="notification"
|
note="notification"
|
||||||
color="#E0E0E0"
|
color="#E0E0E0"
|
||||||
|
|
@ -57,7 +57,9 @@ const NavBarRightSide = () => {
|
||||||
</span> */}
|
</span> */}
|
||||||
<Image
|
<Image
|
||||||
// onClick={()=>(Navigate('/profile'))}
|
// onClick={()=>(Navigate('/profile'))}
|
||||||
src="/Image/faker_user.png" alt="Profile" />
|
src="/Image/faker_user.png"
|
||||||
|
alt="Profile"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const TooltipComp = ({
|
||||||
color: string;
|
color: string;
|
||||||
icon: any;
|
icon: any;
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick?:() => void
|
onClick?: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
const handleNavigate = () => {
|
const handleNavigate = () => {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(item.path || "/")
|
navigate(item.path || "/");
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -26,11 +26,7 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
|
||||||
className={`link ${isActive ? "active" : ""} ${item?.children && "DropDownLink"}`}
|
className={`link ${isActive ? "active" : ""} ${item?.children && "DropDownLink"}`}
|
||||||
onClick={() => handleNavigate()}
|
onClick={() => handleNavigate()}
|
||||||
>
|
>
|
||||||
<Tooltip
|
<Tooltip placement="topLeft" title={t(item?.text)} color={"#E0E0E0"}>
|
||||||
placement="topLeft"
|
|
||||||
title={t(item?.text)}
|
|
||||||
color={'#E0E0E0'}
|
|
||||||
>
|
|
||||||
<i>{item.icon}</i>
|
<i>{item.icon}</i>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/* Conditionally render the text based on sidebar width */}
|
{/* Conditionally render the text based on sidebar width */}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ export const renderRoutesRecursively = (routes: TMenuItem[]) =>
|
||||||
if (!useAbility) {
|
if (!useAbility) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={route.path}>
|
<React.Fragment key={route.path}>
|
||||||
<Route path={route.path} element={RenderRouteElement(route)} />
|
<Route path={route.path} element={RenderRouteElement(route)} />
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import { Switch } from 'antd';
|
import { Switch } from "antd";
|
||||||
export interface SwitchProps {
|
export interface SwitchProps {
|
||||||
onChange?: (checked: any, event: any) => any;
|
onChange?: (checked: any, event: any) => any;
|
||||||
checked?: boolean;
|
checked?: boolean;
|
||||||
|
|
@ -11,14 +11,14 @@ const onSwitchChange = (checked: boolean) => {
|
||||||
const SwitchButton = ({ onChange, checked }: SwitchProps) => {
|
const SwitchButton = ({ onChange, checked }: SwitchProps) => {
|
||||||
return (
|
return (
|
||||||
<Switch
|
<Switch
|
||||||
className='switch_button'
|
className="switch_button"
|
||||||
defaultChecked
|
defaultChecked
|
||||||
onChange={(checked: any, event: any) =>
|
onChange={(checked: any, event: any) =>
|
||||||
onChange ? onChange(checked, event) : onSwitchChange(checked)
|
onChange ? onChange(checked, event) : onSwitchChange(checked)
|
||||||
}
|
}
|
||||||
// checked={checked}
|
// checked={checked}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default SwitchButton;
|
export default SwitchButton;
|
||||||
|
|
@ -7,7 +7,6 @@ import { BsEyeFill } from "react-icons/bs";
|
||||||
import { GoTrash } from "react-icons/go";
|
import { GoTrash } from "react-icons/go";
|
||||||
import { BsQrCode } from "react-icons/bs";
|
import { BsQrCode } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
interface ActionButtonsProps {
|
interface ActionButtonsProps {
|
||||||
canEdit?: boolean;
|
canEdit?: boolean;
|
||||||
canDelete?: boolean;
|
canDelete?: boolean;
|
||||||
|
|
@ -19,7 +18,7 @@ interface ActionButtonsProps {
|
||||||
onShow?: () => void;
|
onShow?: () => void;
|
||||||
index?: number;
|
index?: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
canShowQr?:boolean
|
canShowQr?: boolean;
|
||||||
onShoqQr?: () => void;
|
onShoqQr?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import QRCode from 'react-qr-code';
|
import QRCode from "react-qr-code";
|
||||||
|
|
||||||
|
const QRCodeGenerator = ({ url, serial }: any) => {
|
||||||
const QRCodeGenerator = ({url}:any) => {
|
const qrValue = `${url}/${serial}`;
|
||||||
|
console.log(qrValue);
|
||||||
return (
|
return (
|
||||||
<div style={{display:'flex',justifyContent:'center'}} >
|
<div style={{ display: "flex", justifyContent: "center" }}>
|
||||||
<QRCode value={url} size={230} type='link' />
|
<QRCode value={qrValue} size={230} type="link" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,24 @@
|
||||||
import { Button } from 'antd'
|
import { Button } from "antd";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
import { CiEdit } from "react-icons/ci";
|
import { CiEdit } from "react-icons/ci";
|
||||||
|
|
||||||
const EditSettingButton = ({buttonName,onClick}:{buttonName?:string,onClick?:() => void}) => {
|
const EditSettingButton = ({
|
||||||
|
buttonName,
|
||||||
|
onClick,
|
||||||
|
}: {
|
||||||
|
buttonName?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button className=' setting_edit_button' onClick={onClick}>
|
<Button className=" setting_edit_button" onClick={onClick}>
|
||||||
<CiEdit />
|
<CiEdit />
|
||||||
{t(`header.edit`) ?? (`header.${buttonName}`)}
|
{t(`header.edit`) ?? `header.${buttonName}`}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default EditSettingButton
|
export default EditSettingButton;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,23 @@
|
||||||
import { Button } from 'antd'
|
import { Button } from "antd";
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const SecuritySettingButton = ({name,danger = false}:{name:string,danger?:boolean}) => {
|
const SecuritySettingButton = ({
|
||||||
|
name,
|
||||||
|
danger = false,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
danger?: boolean;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button className={`security_setting_button ${danger ? "security_setting_button_danger" :""}`}>{t(name)}</Button>
|
<Button
|
||||||
|
className={`security_setting_button ${danger ? "security_setting_button_danger" : ""}`}
|
||||||
|
>
|
||||||
|
{t(name)}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default SecuritySettingButton
|
export default SecuritySettingButton;
|
||||||
|
|
|
||||||
22
src/Components/Ui/ReportTableIcon.tsx
Normal file
22
src/Components/Ui/ReportTableIcon.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Tooltip } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { FaPaperclip } from "react-icons/fa";
|
||||||
|
|
||||||
|
interface ReportButtonsProps {
|
||||||
|
editTooltipTitle?: any;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReportTableIcon = ({ editTooltipTitle, onClick }: ReportButtonsProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<Tooltip placement="top" title={t(editTooltipTitle)} color="#E0E0E0">
|
||||||
|
<span onClick={onClick}>
|
||||||
|
<FaPaperclip size={22} style={{ color: "#A098AE" }} />
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReportTableIcon;
|
||||||
|
|
@ -1,15 +1,23 @@
|
||||||
import { Button } from 'antd';
|
import { Button } from "antd";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
import { HiOutlineTrash } from "react-icons/hi2";
|
import { HiOutlineTrash } from "react-icons/hi2";
|
||||||
|
|
||||||
const TrashButton = ({name,onClick,icon = true}:{name:string,onClick?:() =>void,icon?:boolean}) => {
|
const TrashButton = ({
|
||||||
|
name,
|
||||||
|
onClick,
|
||||||
|
icon = true,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
icon?: boolean;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Button className='trash_button' onClick={onClick}>
|
<Button className="trash_button" onClick={onClick}>
|
||||||
{icon ? <HiOutlineTrash /> : ""}
|
{icon ? <HiOutlineTrash /> : ""}
|
||||||
{t(`header.${name}`)}
|
{t(`header.${name}`)}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default TrashButton
|
export default TrashButton;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ interface FormikFormProps extends Omit<FormikConfig<any>, OmitFormikProps> {
|
||||||
setIsOpen: any;
|
setIsOpen: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const useFilter = () => {
|
const useFilter = () => {
|
||||||
const { setIsOpen, isOpen } = useModalState((state) => state);
|
const { setIsOpen, isOpen } = useModalState((state) => state);
|
||||||
const { filterState, setFilterState, clearFilterState } = useFilterState();
|
const { filterState, setFilterState, clearFilterState } = useFilterState();
|
||||||
|
|
|
||||||
|
|
@ -53,13 +53,12 @@ const File = ({
|
||||||
const maxSize = 2 * 1024 * 1024; // 2 MB in bytes
|
const maxSize = 2 * 1024 * 1024; // 2 MB in bytes
|
||||||
|
|
||||||
if (file.size > maxSize) {
|
if (file.size > maxSize) {
|
||||||
alert(t('validation.File_size_exceeds_2_MB_limit.'));
|
alert(t("validation.File_size_exceeds_2_MB_limit."));
|
||||||
return Upload.LIST_IGNORE; // Prevent the file from being uploaded
|
return Upload.LIST_IGNORE; // Prevent the file from being uploaded
|
||||||
}
|
}
|
||||||
return true; // Allow the file to be uploaded
|
return true; // Allow the file to be uploaded
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`ValidationField upload_image_button ${className ?? ""} `}>
|
<div className={`ValidationField upload_image_button ${className ?? ""} `}>
|
||||||
<label htmlFor={name} className="text">
|
<label htmlFor={name} className="text">
|
||||||
|
|
@ -76,7 +75,6 @@ const File = ({
|
||||||
customRequest={customRequest}
|
customRequest={customRequest}
|
||||||
className={` w-100`}
|
className={` w-100`}
|
||||||
id={name}
|
id={name}
|
||||||
|
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
className={isError ? "isError w-100 " : " w-100"}
|
className={isError ? "isError w-100 " : " w-100"}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ const SearchField = ({
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
formik?.setFieldValue(name, option ?? []);
|
formik?.setFieldValue(name, option ?? []);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
formik?.setFieldValue(name, option ?? {});
|
formik?.setFieldValue(name, option ?? {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +95,8 @@ const SearchField = ({
|
||||||
const handleScroll = (event: any) => {
|
const handleScroll = (event: any) => {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
const isAtBottom =
|
const isAtBottom =
|
||||||
target.scrollHeight - 10 <= Math.floor(target.scrollTop + target.clientHeight);
|
target.scrollHeight - 10 <=
|
||||||
|
Math.floor(target.scrollTop + target.clientHeight);
|
||||||
|
|
||||||
if (isAtBottom && canChangePage && PageName && page) {
|
if (isAtBottom && canChangePage && PageName && page) {
|
||||||
console.log("Scrolled to the last option!");
|
console.log("Scrolled to the last option!");
|
||||||
|
|
@ -109,9 +109,11 @@ const SearchField = ({
|
||||||
|
|
||||||
console.log(AllPagesOption);
|
console.log(AllPagesOption);
|
||||||
console.log(option, "option");
|
console.log(option, "option");
|
||||||
const value = isMulti ? formik.values[name]?.map((item:any)=>{
|
const value = isMulti
|
||||||
return item?.name ?? item
|
? formik.values[name]?.map((item: any) => {
|
||||||
}) : formik.values[name]?.["name"] ?? ""
|
return item?.name ?? item;
|
||||||
|
})
|
||||||
|
: (formik.values[name]?.["name"] ?? "");
|
||||||
console.log(value);
|
console.log(value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ const TextField = ({
|
||||||
showCount
|
showCount
|
||||||
maxLength={1000}
|
maxLength={1000}
|
||||||
autoSize={{ minRows: 4, maxRows: 10 }}
|
autoSize={{ minRows: 4, maxRows: 10 }}
|
||||||
|
|
||||||
onChange={onChange || TextFilehandleChange}
|
onChange={onChange || TextFilehandleChange}
|
||||||
id={name}
|
id={name}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,7 @@ const TextFieldMML = ({
|
||||||
onChange={onChange || TextFilehandleChange}
|
onChange={onChange || TextFilehandleChange}
|
||||||
id={name}
|
id={name}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
</ValidationFieldContainer>
|
</ValidationFieldContainer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,5 +23,5 @@ export {
|
||||||
SearchField,
|
SearchField,
|
||||||
TextField,
|
TextField,
|
||||||
DropFile,
|
DropFile,
|
||||||
TextAreaMML
|
TextAreaMML,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,6 @@
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//// malty select
|
//// malty select
|
||||||
///
|
///
|
||||||
.ant-select-multiple {
|
.ant-select-multiple {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
export const translateOptions = (options: any, t: any) => {
|
export const translateOptions = (options: any, t: any) => {
|
||||||
|
|
||||||
return options?.map((opt: any) => ({
|
return options?.map((opt: any) => ({
|
||||||
...opt,
|
...opt,
|
||||||
label: t(`${opt?.label}`),
|
label: t(`${opt?.label}`),
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,14 @@ export type SearchFieldProps = BaseFieldProps &
|
||||||
|
|
||||||
type DateFieldProps = BaseFieldProps & {
|
type DateFieldProps = BaseFieldProps & {
|
||||||
type: "DataRange" | "Date" | "Time";
|
type: "DataRange" | "Date" | "Time";
|
||||||
Format?: "YYYY/MM/DD" | "MM/DD" | "YYYY/MM" | "YYYY-MM-DD HH:mm:ss.SSS" | "YYYY-MM-DD HH:mm:ss";
|
Format?:
|
||||||
|
| "YYYY/MM/DD"
|
||||||
|
| "MM/DD"
|
||||||
|
| "YYYY/MM"
|
||||||
|
| "YYYY-MM-DD HH:mm:ss.SSS"
|
||||||
|
| "YYYY-MM-DD HH:mm:ss";
|
||||||
picker?: "data" | "week" | "month" | "quarter" | "year";
|
picker?: "data" | "week" | "month" | "quarter" | "year";
|
||||||
showTime?:boolean
|
showTime?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FileFieldProps = BaseFieldProps & {
|
type FileFieldProps = BaseFieldProps & {
|
||||||
|
|
|
||||||
|
|
@ -12,22 +12,28 @@ import { LocalStorageEnum } from "../../enums/LocalStorageEnum";
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const { values, setValues } = useFormikContext<any>();
|
const { values, setValues } = useFormikContext<any>();
|
||||||
const { isBseQuestion, setIsBseQuestion,ShowHint,setShowHint,ShowLatexOption,setShowLatexOption } = useObjectToEdit();
|
const {
|
||||||
|
isBseQuestion,
|
||||||
|
setIsBseQuestion,
|
||||||
|
ShowHint,
|
||||||
|
setShowHint,
|
||||||
|
ShowLatexOption,
|
||||||
|
setShowLatexOption,
|
||||||
|
} = useObjectToEdit();
|
||||||
// const [Setting, setSetting] = useState(false)
|
// const [Setting, setSetting] = useState(false)
|
||||||
const isEdited = () => {
|
const isEdited = () => {
|
||||||
|
|
||||||
if (isBseQuestion || values?.isBase === 1) {
|
if (isBseQuestion || values?.isBase === 1) {
|
||||||
|
|
||||||
const content = !values?.content;
|
const content = !values?.content;
|
||||||
const content_image = !values?.content_image;
|
const content_image = !values?.content_image;
|
||||||
|
|
||||||
const Questions = values?.Questions?.length <= 1 && values?.Questions?.[0]?.answers?.length === 0 ;
|
const Questions =
|
||||||
const defaultQuestionHint = Object.keys(values?.Questions?.[0] ?? {})?.length <= 1
|
values?.Questions?.length <= 1 &&
|
||||||
|
values?.Questions?.[0]?.answers?.length === 0;
|
||||||
|
const defaultQuestionHint =
|
||||||
|
Object.keys(values?.Questions?.[0] ?? {})?.length <= 1;
|
||||||
|
|
||||||
if (content && content_image && Questions && defaultQuestionHint) {
|
if (content && content_image && Questions && defaultQuestionHint) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const content = !values?.content;
|
const content = !values?.content;
|
||||||
|
|
@ -36,11 +42,11 @@ const Header = () => {
|
||||||
const answers = !(values?.answers?.length > 0);
|
const answers = !(values?.answers?.length > 0);
|
||||||
const tags = !(values?.tags?.length > 0);
|
const tags = !(values?.tags?.length > 0);
|
||||||
if (content && content_image && hint && answers && tags) {
|
if (content && content_image && hint && answers && tags) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleChange = () => {
|
const handleChange = () => {
|
||||||
if (isBseQuestion) {
|
if (isBseQuestion) {
|
||||||
|
|
@ -52,11 +58,10 @@ const Header = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const confirm: PopconfirmProps['onConfirm'] = (e) => {
|
const confirm: PopconfirmProps["onConfirm"] = (e) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleChange();
|
handleChange();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
|
|
@ -73,21 +78,24 @@ const Header = () => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onChangeHint: CheckboxProps["onChange"] = (e) => {
|
||||||
const onChangeHint: CheckboxProps['onChange'] = (e) => {
|
|
||||||
setShowHint(e.target.checked);
|
setShowHint(e.target.checked);
|
||||||
localStorage?.setItem(LocalStorageEnum.HINT_INPUT,e.target.checked ? "true" : "false" )
|
localStorage?.setItem(
|
||||||
|
LocalStorageEnum.HINT_INPUT,
|
||||||
|
e.target.checked ? "true" : "false",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeLatexOption: CheckboxProps['onChange'] = (e) => {
|
const onChangeLatexOption: CheckboxProps["onChange"] = (e) => {
|
||||||
setShowLatexOption(e.target.checked);
|
setShowLatexOption(e.target.checked);
|
||||||
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
|
localStorage?.setItem(
|
||||||
|
LocalStorageEnum.LATEX_OPTION_INPUT,
|
||||||
|
e.target.checked ? "true" : "false",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const contentSetting = (
|
const contentSetting = (
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<Checkbox checked={ShowHint} onChange={onChangeHint}>
|
<Checkbox checked={ShowHint} onChange={onChangeHint}>
|
||||||
{t("header.show_hint")}
|
{t("header.show_hint")}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
|
@ -95,11 +103,9 @@ const Header = () => {
|
||||||
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
|
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
|
||||||
{t("header.show_MMl")}
|
{t("header.show_MMl")}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="exercise_add_header mb-4">
|
<header className="exercise_add_header mb-4">
|
||||||
<article>
|
<article>
|
||||||
|
|
@ -112,48 +118,35 @@ const Header = () => {
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<div className="question_header_setting">
|
<div className="question_header_setting">
|
||||||
<Popover trigger="click" content={contentSetting}>
|
<Popover trigger="click" content={contentSetting}>
|
||||||
<SettingFilled />
|
<SettingFilled />
|
||||||
|
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{isEdited() ? (
|
||||||
isEdited() ?
|
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={t("header.this_will_un_do_all_your_changes")}
|
title={t("header.this_will_un_do_all_your_changes")}
|
||||||
okText={t("practical.yes")}
|
okText={t("practical.yes")}
|
||||||
cancelText={t("practical.no")}
|
cancelText={t("practical.no")}
|
||||||
onConfirm={()=>{confirm()}}
|
onConfirm={() => {
|
||||||
|
confirm();
|
||||||
|
}}
|
||||||
defaultOpen={false}
|
defaultOpen={false}
|
||||||
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<GoArrowSwitch className="m-2" />
|
<GoArrowSwitch className="m-2" />
|
||||||
{isBseQuestion || values?.isBase === 1
|
{isBseQuestion || values?.isBase === 1
|
||||||
? t("header.malty_exercise")
|
? t("header.malty_exercise")
|
||||||
: t("header.exercise")}
|
: t("header.exercise")}
|
||||||
|
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
) : (
|
||||||
|
|
||||||
:
|
|
||||||
|
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
|
||||||
<GoArrowSwitch onClick={() => confirm()} className="m-2" />
|
<GoArrowSwitch onClick={() => confirm()} className="m-2" />
|
||||||
{isBseQuestion || values?.isBase === 1
|
{isBseQuestion || values?.isBase === 1
|
||||||
? t("header.malty_exercise")
|
? t("header.malty_exercise")
|
||||||
: t("header.exercise")}
|
: t("header.exercise")}
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const useFormField = (name: string, props?: any) => {
|
||||||
const errorMsg =
|
const errorMsg =
|
||||||
!!isError && meta.error
|
!!isError && meta.error
|
||||||
? t(meta.error.toString())
|
? t(meta.error.toString())
|
||||||
: Validation[name as any] ?? "";
|
: (Validation[name as any] ?? "");
|
||||||
|
|
||||||
return { Field, field, meta, formik, isError, errorMsg, t };
|
return { Field, field, meta, formik, isError, errorMsg, t };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from "react";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
|
const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
@ -10,7 +10,7 @@ const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
|
||||||
// Prevent default action and stop the event
|
// Prevent default action and stop the event
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
// Optionally set returnValue to an empty string
|
// Optionally set returnValue to an empty string
|
||||||
event.returnValue = '';
|
event.returnValue = "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -21,19 +21,19 @@ const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('beforeunload', handleBeforeUnload);
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
||||||
|
|
||||||
// Intercept link clicks (example for <a> elements)
|
// Intercept link clicks (example for <a> elements)
|
||||||
document.querySelectorAll('a').forEach(link => {
|
document.querySelectorAll("a").forEach((link) => {
|
||||||
link.addEventListener('click', handleNavigation);
|
link.addEventListener("click", handleNavigation);
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('beforeunload', handleBeforeUnload);
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
||||||
|
|
||||||
// Clean up event listeners
|
// Clean up event listeners
|
||||||
document.querySelectorAll('a').forEach(link => {
|
document.querySelectorAll("a").forEach((link) => {
|
||||||
link.removeEventListener('click', handleNavigation);
|
link.removeEventListener("click", handleNavigation);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}, [unsavedChanges, t]);
|
}, [unsavedChanges, t]);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
export const useWindowResize = () => {
|
export const useWindowResize = () => {
|
||||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener('resize', handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
// Cleanup function to remove the event listener
|
// Cleanup function to remove the event listener
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', handleResize);
|
window.removeEventListener("resize", handleResize);
|
||||||
};
|
};
|
||||||
}, [windowWidth]);
|
}, [windowWidth]);
|
||||||
|
|
||||||
|
|
@ -16,5 +16,4 @@ export const useWindowResize = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return { windowWidth, handleResize };
|
return { windowWidth, handleResize };
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const FilterLayout = ({
|
||||||
width = "500px",
|
width = "500px",
|
||||||
haveFilter = true,
|
haveFilter = true,
|
||||||
haveOrder = true,
|
haveOrder = true,
|
||||||
haveSearch = true
|
haveSearch = true,
|
||||||
}: {
|
}: {
|
||||||
filterTitle: string;
|
filterTitle: string;
|
||||||
sub_children?: any;
|
sub_children?: any;
|
||||||
|
|
@ -26,7 +26,7 @@ const FilterLayout = ({
|
||||||
width?: string;
|
width?: string;
|
||||||
haveFilter?: boolean;
|
haveFilter?: boolean;
|
||||||
haveOrder?: boolean;
|
haveOrder?: boolean;
|
||||||
haveSearch?:boolean
|
haveSearch?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const translateArray = translateOptions(search_array, t);
|
const translateArray = translateOptions(search_array, t);
|
||||||
|
|
@ -49,8 +49,7 @@ const FilterLayout = ({
|
||||||
<div className="model_sub_children">{sub_children}</div>
|
<div className="model_sub_children">{sub_children}</div>
|
||||||
<FilterSubmit />
|
<FilterSubmit />
|
||||||
</FilterBody>
|
</FilterBody>
|
||||||
{haveFilter &&
|
{haveFilter && (
|
||||||
|
|
||||||
<div className="filter_button" onClick={() => setIsOpen(true)}>
|
<div className="filter_button" onClick={() => setIsOpen(true)}>
|
||||||
<span>
|
<span>
|
||||||
<BiFilterAlt className="addition_select_icon" />
|
<BiFilterAlt className="addition_select_icon" />
|
||||||
|
|
@ -58,12 +57,10 @@ const FilterLayout = ({
|
||||||
</span>
|
</span>
|
||||||
<MdKeyboardArrowDown />
|
<MdKeyboardArrowDown />
|
||||||
</div>
|
</div>
|
||||||
}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>
|
<span>{haveOrder && <OrderBySelect />}</span>
|
||||||
{haveOrder && <OrderBySelect />}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -77,7 +74,12 @@ const FilterLayout = ({
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div className="header_search">
|
<div className="header_search">
|
||||||
{haveSearch && <SearchField searchBy={search_by} placeholder={t("practical.search_here")} />}
|
{haveSearch && (
|
||||||
|
<SearchField
|
||||||
|
searchBy={search_by}
|
||||||
|
placeholder={t("practical.search_here")}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ const FormikFormModel: React.FC<FormikFormProps> = ({
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
|
||||||
>
|
>
|
||||||
{(formik) => {
|
{(formik) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ interface LayoutModalProps {
|
||||||
width?: string;
|
width?: string;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
buttonTitle?: string;
|
buttonTitle?: string;
|
||||||
initialButtonName?:boolean
|
initialButtonName?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LayoutModel = ({
|
const LayoutModel = ({
|
||||||
|
|
@ -70,7 +70,6 @@ const LayoutModel = ({
|
||||||
open={isOpen === ModelEnum}
|
open={isOpen === ModelEnum}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
>
|
>
|
||||||
|
|
||||||
<Formik
|
<Formik
|
||||||
enableReinitialize={true}
|
enableReinitialize={true}
|
||||||
initialValues={getInitialValues}
|
initialValues={getInitialValues}
|
||||||
|
|
@ -85,8 +84,8 @@ const LayoutModel = ({
|
||||||
}
|
}
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
return <Form className="w-100">
|
return (
|
||||||
|
<Form className="w-100">
|
||||||
<header>
|
<header>
|
||||||
<span>
|
<span>
|
||||||
{t(`practical.${isAddModal ? "add" : "edit"}`)}{" "}
|
{t(`practical.${isAddModal ? "add" : "edit"}`)}{" "}
|
||||||
|
|
@ -100,18 +99,22 @@ const LayoutModel = ({
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<Button className="back_button pointer" onClick={handleCancel}>
|
<Button
|
||||||
|
className="back_button pointer"
|
||||||
|
onClick={handleCancel}
|
||||||
|
>
|
||||||
{t("practical.cancel")}
|
{t("practical.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className="add_button"
|
className="add_button"
|
||||||
disabled={status === QueryStatusEnum.LOADING || !formik.dirty}
|
disabled={
|
||||||
|
status === QueryStatusEnum.LOADING || !formik.dirty
|
||||||
|
}
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
>
|
>
|
||||||
{
|
{initialButtonName
|
||||||
initialButtonName ? t(`practical.${isAddModal ? "add" : "edit"}`)
|
? t(`practical.${isAddModal ? "add" : "edit"}`)
|
||||||
: t(`practical.${buttonTitle}`)
|
: t(`practical.${buttonTitle}`)}
|
||||||
}
|
|
||||||
{status === QueryStatusEnum.LOADING && (
|
{status === QueryStatusEnum.LOADING && (
|
||||||
<span className="Spinier_Div">
|
<span className="Spinier_Div">
|
||||||
<Spin />
|
<Spin />
|
||||||
|
|
@ -120,8 +123,8 @@ const LayoutModel = ({
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</Form>
|
||||||
</Form>;
|
);
|
||||||
}}
|
}}
|
||||||
</Formik>
|
</Formik>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { BsPlusCircleFill } from "react-icons/bs";
|
import { BsPlusCircleFill } from "react-icons/bs";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
@ -14,7 +13,8 @@ const PageHeader = ({
|
||||||
pageTitle,
|
pageTitle,
|
||||||
openModel = true,
|
openModel = true,
|
||||||
locationToNavigate,
|
locationToNavigate,
|
||||||
addModal = true
|
addModal = true,
|
||||||
|
modelButtonTitle = "add",
|
||||||
}: {
|
}: {
|
||||||
canAdd?: any;
|
canAdd?: any;
|
||||||
ModelAbility?: any;
|
ModelAbility?: any;
|
||||||
|
|
@ -22,6 +22,7 @@ const PageHeader = ({
|
||||||
openModel?: boolean;
|
openModel?: boolean;
|
||||||
locationToNavigate?: string | any;
|
locationToNavigate?: string | any;
|
||||||
addModal?: boolean;
|
addModal?: boolean;
|
||||||
|
modelButtonTitle?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { handel_open_model } = useModalHandler();
|
const { handel_open_model } = useModalHandler();
|
||||||
|
|
@ -31,9 +32,8 @@ const PageHeader = ({
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
const handleNavigateToPage = (location: string) => {
|
const handleNavigateToPage = (location: string) => {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(location);
|
navigate(location);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log();
|
console.log();
|
||||||
|
|
@ -46,7 +46,8 @@ const PageHeader = ({
|
||||||
<PageTitleComponent />
|
<PageTitleComponent />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{ addModal ? canAdd && (
|
{addModal
|
||||||
|
? canAdd && (
|
||||||
<div className="Selects">
|
<div className="Selects">
|
||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
@ -57,10 +58,11 @@ const PageHeader = ({
|
||||||
className="add_button"
|
className="add_button"
|
||||||
>
|
>
|
||||||
<BsPlusCircleFill />
|
<BsPlusCircleFill />
|
||||||
{t(`practical.add`)}
|
{t(`practical.${modelButtonTitle}`)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) :""}
|
)
|
||||||
|
: ""}
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,38 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { usePageTitleState } from '../../zustand/PageTitleState'
|
import { usePageTitleState } from "../../zustand/PageTitleState";
|
||||||
import { useFilterStateState } from '../../zustand/Filter'
|
import { useFilterStateState } from "../../zustand/Filter";
|
||||||
|
|
||||||
const PageTitleComponent = () => {
|
const PageTitleComponent = () => {
|
||||||
|
const { PageTitle } = usePageTitleState();
|
||||||
const {PageTitle} = usePageTitleState()
|
const navigate = useNavigate();
|
||||||
const navigate = useNavigate()
|
const location = useLocation();
|
||||||
const location = useLocation()
|
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
const handleNavigate = (path: string) => {
|
const handleNavigate = (path: string) => {
|
||||||
const currentPath = location.pathname;
|
const currentPath = location.pathname;
|
||||||
const newPath = currentPath?.split(path)?.[0] + path;
|
const newPath = currentPath?.split(path)?.[0] + path;
|
||||||
if (newPath !== currentPath) {
|
if (newPath !== currentPath) {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(newPath)
|
navigate(newPath);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className='PageTitle'>
|
<div className="PageTitle">
|
||||||
{(Array.isArray(PageTitle) ? PageTitle : [])?.map((item, index) => {
|
{(Array.isArray(PageTitle) ? PageTitle : [])?.map((item, index) => {
|
||||||
const lastItem = PageTitle?.length - 1 === index
|
const lastItem = PageTitle?.length - 1 === index;
|
||||||
return (
|
return (
|
||||||
<div key={index} className={`PageTitleItems ${lastItem ? "PageTitleLastItem" : ""} `} onClick={()=>handleNavigate(item?.path)}>
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`PageTitleItems ${lastItem ? "PageTitleLastItem" : ""} `}
|
||||||
|
onClick={() => handleNavigate(item?.path)}
|
||||||
|
>
|
||||||
{item?.name} {lastItem ? "" : "/"}
|
{item?.name} {lastItem ? "" : "/"}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default PageTitleComponent
|
export default PageTitleComponent;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ const QrCodeModels: React.FC<ModalFormProps> = ({
|
||||||
|
|
||||||
const { objectToEdit, setObjectToEdit } = useObjectToEdit();
|
const { objectToEdit, setObjectToEdit } = useObjectToEdit();
|
||||||
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setIsOpen("");
|
setIsOpen("");
|
||||||
setObjectToEdit({});
|
setObjectToEdit({});
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ const DataTable: React.FC<DataTableProps> = ({
|
||||||
const isRefetching = response?.isRefetching;
|
const isRefetching = response?.isRefetching;
|
||||||
const isLoading = response?.isLoading;
|
const isLoading = response?.isLoading;
|
||||||
const dataLength = data?.length;
|
const dataLength = data?.length;
|
||||||
const {setDataTableLength} = useDataTableState()
|
const { setDataTableLength } = useDataTableState();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDataTableLength(dataLength)
|
setDataTableLength(dataLength);
|
||||||
}, [dataLength])
|
}, [dataLength]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
|
|
@ -63,10 +63,8 @@ const DataTable: React.FC<DataTableProps> = ({
|
||||||
nextIcon: <>{t("practical.next")}</>,
|
nextIcon: <>{t("practical.next")}</>,
|
||||||
prevIcon: <> {t("practical.prev")} </>,
|
prevIcon: <> {t("practical.prev")} </>,
|
||||||
className: "pagination_antd",
|
className: "pagination_antd",
|
||||||
showSizeChanger:false
|
showSizeChanger: false,
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ const usePagination = (data: Data) => {
|
||||||
current: data?.meta?.current_page || 1,
|
current: data?.meta?.current_page || 1,
|
||||||
pageSize: data?.meta?.per_page || 2,
|
pageSize: data?.meta?.per_page || 2,
|
||||||
total: data?.meta?.total || 0,
|
total: data?.meta?.total || 0,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -21,15 +20,14 @@ const usePagination = (data: Data) => {
|
||||||
current: data?.meta?.current_page || 1,
|
current: data?.meta?.current_page || 1,
|
||||||
pageSize: data?.meta?.per_page || 2,
|
pageSize: data?.meta?.per_page || 2,
|
||||||
total: data?.meta?.total || 0,
|
total: data?.meta?.total || 0,
|
||||||
|
|
||||||
});
|
});
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
setFilter({
|
setFilter({
|
||||||
...Filter,
|
...Filter,
|
||||||
page:page
|
page: page,
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return { pagination, handlePageChange };
|
return { pagination, handlePageChange };
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ const Layout = ({
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const { openSideBar, setOpenSideBar } = useSideBarState();
|
const { openSideBar, setOpenSideBar } = useSideBarState();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,22 @@ function NotFoundPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProtectedRouteProvider className="not_found_page">
|
<ProtectedRouteProvider className="not_found_page">
|
||||||
|
|
||||||
<div className="not_found_container">
|
<div className="not_found_container">
|
||||||
<img src="/App/Error.png" alt="Error 404" width={500} />
|
<img src="/App/Error.png" alt="Error 404" width={500} />
|
||||||
<h3>{t("practical.sorry_something_went_wrong")}</h3>
|
<h3>{t("practical.sorry_something_went_wrong")}</h3>
|
||||||
<p>{t("practical.error_404_Page_not_found._Sorry,_the_page_you_are_looking_for_does_not_exist")}</p>
|
<p>
|
||||||
<Button className="not_found_button" onClick={() => navigate("/", { replace: true })}>
|
{t(
|
||||||
|
"practical.error_404_Page_not_found._Sorry,_the_page_you_are_looking_for_does_not_exist",
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
className="not_found_button"
|
||||||
|
onClick={() => navigate("/", { replace: true })}
|
||||||
|
>
|
||||||
<FaArrowRight />
|
<FaArrowRight />
|
||||||
{t("practical.return_to_the_dashboard")}
|
{t("practical.return_to_the_dashboard")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</ProtectedRouteProvider>
|
</ProtectedRouteProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ import { ParamsEnum } from "../../../../enums/params";
|
||||||
|
|
||||||
const AddModel: React.FC = () => {
|
const AddModel: React.FC = () => {
|
||||||
const { mutate, status } = useAddArea();
|
const { mutate, status } = useAddArea();
|
||||||
const {city_id} = useParams<ParamsEnum>()
|
const { city_id } = useParams<ParamsEnum>();
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any) => {
|
||||||
mutate({
|
mutate({
|
||||||
...values,
|
...values,
|
||||||
city_id
|
city_id,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { ParamsEnum } from "../../../../enums/params";
|
||||||
const EditModel: React.FC = () => {
|
const EditModel: React.FC = () => {
|
||||||
const { mutate, status } = useUpdateArea();
|
const { mutate, status } = useUpdateArea();
|
||||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||||
const {city_id} = useParams<ParamsEnum>()
|
const { city_id } = useParams<ParamsEnum>();
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any) => {
|
||||||
const Data_to_send = { ...values, city_id };
|
const Data_to_send = { ...values, city_id };
|
||||||
mutate(Data_to_send);
|
mutate(Data_to_send);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ const Form = () => {
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField name="name" placeholder="name" label="name" />
|
<ValidationField name="name" placeholder="name" label="name" />
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const DeleteModalForm = lazy(
|
||||||
const TableHeader = () => {
|
const TableHeader = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const deleteMutation = useDeleteArea();
|
const deleteMutation = useDeleteArea();
|
||||||
const {city_id} = useParams<ParamsEnum>()
|
const { city_id } = useParams<ParamsEnum>();
|
||||||
useSetPageTitle([
|
useSetPageTitle([
|
||||||
{ name: `${t(`page_header.home`)}`, path: "/" },
|
{ name: `${t(`page_header.home`)}`, path: "/" },
|
||||||
{ name: `${t(`page_header.Area`)}`, path: `city/${city_id}` },
|
{ name: `${t(`page_header.Area`)}`, path: `city/${city_id}` },
|
||||||
|
|
@ -35,7 +35,11 @@ const TableHeader = () => {
|
||||||
ModelAbility={ModalEnum?.AREA_ADD}
|
ModelAbility={ModalEnum?.AREA_ADD}
|
||||||
canAdd={canAddArea}
|
canAdd={canAddArea}
|
||||||
/>
|
/>
|
||||||
<FilterLayout sub_children={<FilterForm />} filterTitle="table.Area" haveFilter={false} />
|
<FilterLayout
|
||||||
|
sub_children={<FilterForm />}
|
||||||
|
filterTitle="table.Area"
|
||||||
|
haveFilter={false}
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { ParamsEnum } from "../../../enums/params";
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const { filterState } = useFilterState();
|
const { filterState } = useFilterState();
|
||||||
const { Filter } = useFilterStateState();
|
const { Filter } = useFilterStateState();
|
||||||
const {city_id} = useParams<ParamsEnum>()
|
const { city_id } = useParams<ParamsEnum>();
|
||||||
const name = Filter?.name;
|
const name = Filter?.name;
|
||||||
const sort_by = Filter?.sort_by;
|
const sort_by = Filter?.sort_by;
|
||||||
const response = useGetAllArea({
|
const response = useGetAllArea({
|
||||||
|
|
@ -18,7 +18,7 @@ const App: React.FC = () => {
|
||||||
...filterState,
|
...filterState,
|
||||||
city_id,
|
city_id,
|
||||||
name,
|
name,
|
||||||
sort_by
|
sort_by,
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,8 @@ export const useColumns = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handelShow = (record: Area) => {
|
const handelShow = (record: Area) => {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(`${record?.id}`);
|
navigate(`${record?.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -53,7 +51,7 @@ export const useColumns = () => {
|
||||||
key: "name",
|
key: "name",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.name,
|
render: (_text, record) => record?.name,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ const Form = () => {
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField name="name" placeholder="name" label="name" />
|
<ValidationField name="name" placeholder="name" label="name" />
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const TableHeader = () => {
|
||||||
|
|
||||||
useSetPageTitle([
|
useSetPageTitle([
|
||||||
{ name: `${t(`page_header.home`)}`, path: "/" },
|
{ name: `${t(`page_header.home`)}`, path: "/" },
|
||||||
{name:`${t(`page_header.City`)}`, path:"City"}
|
{ name: `${t(`page_header.City`)}`, path: "City" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -33,7 +33,11 @@ const TableHeader = () => {
|
||||||
ModelAbility={ModalEnum?.CITY_ADD}
|
ModelAbility={ModalEnum?.CITY_ADD}
|
||||||
canAdd={canAddCity}
|
canAdd={canAddCity}
|
||||||
/>
|
/>
|
||||||
<FilterLayout sub_children={<FilterForm />} haveFilter={false} filterTitle="table.City" />
|
<FilterLayout
|
||||||
|
sub_children={<FilterForm />}
|
||||||
|
haveFilter={false}
|
||||||
|
filterTitle="table.City"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const App: React.FC = () => {
|
||||||
pagination: true,
|
pagination: true,
|
||||||
...filterState,
|
...filterState,
|
||||||
name,
|
name,
|
||||||
sort_by
|
sort_by,
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,8 @@ export const useColumns = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handelShow = (record: City) => {
|
const handelShow = (record: City) => {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(`${record?.id}`);
|
navigate(`${record?.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -53,10 +51,9 @@ export const useColumns = () => {
|
||||||
key: "name",
|
key: "name",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.name,
|
render: (_text, record) => record?.name,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,12 @@ const AddModel: React.FC = () => {
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any) => {
|
||||||
console.log(values?.due_to, "values?.due_to");
|
console.log(values?.due_to, "values?.due_to");
|
||||||
const due_to = values?.due_to.format("YYYY-MM-DD HH:mm:ss")
|
const due_to = values?.due_to.format("YYYY-MM-DD HH:mm:ss");
|
||||||
console.log(due_to);
|
console.log(due_to);
|
||||||
mutate({
|
mutate({
|
||||||
...values,
|
...values,
|
||||||
due_to,
|
due_to,
|
||||||
grade_id:values?.grade_id?.id
|
grade_id: values?.grade_id?.id,
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,15 @@ const EditModel: React.FC = () => {
|
||||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any) => {
|
||||||
const due_to = typeof values?.due_to === "string" ? values?.due_to : values?.due_to.format("YYYY-MM-DD HH:mm:ss")
|
const due_to =
|
||||||
const Data_to_send = { ...values , due_to, grade_id:values?.grade_id?.id ?? "" };
|
typeof values?.due_to === "string"
|
||||||
|
? values?.due_to
|
||||||
|
: values?.due_to.format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
const Data_to_send = {
|
||||||
|
...values,
|
||||||
|
due_to,
|
||||||
|
grade_id: values?.grade_id?.id ?? "",
|
||||||
|
};
|
||||||
mutate(Data_to_send);
|
mutate(Data_to_send);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,40 +6,40 @@ import { useGetAllGrade } from "../../../../api/grade";
|
||||||
const Form = ({ Hide = false }: { Hide?: boolean }) => {
|
const Form = ({ Hide = false }: { Hide?: 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?.current_page;
|
const GradePage = Grade?.meta?.current_page;
|
||||||
return (
|
return (
|
||||||
<Row className="w-100">
|
<Row className="w-100">
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField name="name" placeholder="name" label="name" />
|
<ValidationField name="name" placeholder="name" label="name" />
|
||||||
<ValidationField name="amount" type="number" placeholder="amount" label="amount" />
|
<ValidationField
|
||||||
|
name="amount"
|
||||||
|
type="number"
|
||||||
|
placeholder="amount"
|
||||||
|
label="amount"
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField
|
<ValidationField
|
||||||
name="due_to" type="Date"
|
name="due_to"
|
||||||
|
type="Date"
|
||||||
Format="YYYY-MM-DD HH:mm:ss"
|
Format="YYYY-MM-DD HH:mm:ss"
|
||||||
placeholder="due_to" label="due_to"
|
placeholder="due_to"
|
||||||
|
label="due_to"
|
||||||
showTime
|
showTime
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<ValidationField name="code" placeholder="code" label="code" />
|
<ValidationField name="code" placeholder="code" label="code" />
|
||||||
{/*
|
{/*
|
||||||
grade_id
|
grade_id
|
||||||
*/}
|
*/}
|
||||||
{!Hide &&
|
{!Hide && (
|
||||||
|
|
||||||
<ValidationField
|
<ValidationField
|
||||||
searchBy="GradeName"
|
searchBy="GradeName"
|
||||||
name="grade_id"
|
name="grade_id"
|
||||||
|
|
@ -51,9 +51,8 @@ const Form = ({Hide = false}:{Hide?:boolean }) => {
|
||||||
canChangePage={canChangeGradePage}
|
canChangePage={canChangeGradePage}
|
||||||
PageName={"GradeCurrentPage"}
|
PageName={"GradeCurrentPage"}
|
||||||
page={GradePage}
|
page={GradePage}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ export const getInitialValues = (
|
||||||
name: objectToEdit?.name ?? "",
|
name: objectToEdit?.name ?? "",
|
||||||
amount: objectToEdit?.amount ?? "",
|
amount: objectToEdit?.amount ?? "",
|
||||||
code: objectToEdit?.code ?? "",
|
code: objectToEdit?.code ?? "",
|
||||||
due_to: objectToEdit?.due_to ? dayjs(objectToEdit?.due_to,"YYYY-MM-DD HH:mm:ss") : "",
|
due_to: objectToEdit?.due_to
|
||||||
|
? dayjs(objectToEdit?.due_to, "YYYY-MM-DD HH:mm:ss")
|
||||||
|
: "",
|
||||||
grade_id: objectToEdit?.grade ?? "",
|
grade_id: objectToEdit?.grade ?? "",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -20,8 +22,12 @@ export const getValidationSchema = () => {
|
||||||
return Yup.object().shape({
|
return Yup.object().shape({
|
||||||
name: Yup.string().required("validation.required"),
|
name: Yup.string().required("validation.required"),
|
||||||
due_to: Yup.string().required("validation.required"),
|
due_to: Yup.string().required("validation.required"),
|
||||||
code: Yup.string().required("validation.required").min(6,"validation.must_be_at_least_6_characters_long").max(6,"validation.must_be_at_least_6_characters_long"),
|
code: Yup.string()
|
||||||
amount: Yup.number().required("validation.required").typeError("validation.Must_be_a_number"),
|
.required("validation.required")
|
||||||
|
.min(6, "validation.must_be_at_least_6_characters_long")
|
||||||
|
.max(6, "validation.must_be_at_least_6_characters_long"),
|
||||||
|
amount: Yup.number()
|
||||||
|
.required("validation.required")
|
||||||
|
.typeError("validation.Must_be_a_number"),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const TableHeader = () => {
|
||||||
|
|
||||||
useSetPageTitle([
|
useSetPageTitle([
|
||||||
{ name: `${t(`page_header.home`)}`, path: "/" },
|
{ name: `${t(`page_header.home`)}`, path: "/" },
|
||||||
{name:`${t(`page_header.Coupon`)}`, path:"Coupon"}
|
{ name: `${t(`page_header.Coupon`)}`, path: "Coupon" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -33,7 +33,11 @@ const TableHeader = () => {
|
||||||
ModelAbility={ModalEnum?.COUPON_ADD}
|
ModelAbility={ModalEnum?.COUPON_ADD}
|
||||||
canAdd={canAddCoupon}
|
canAdd={canAddCoupon}
|
||||||
/>
|
/>
|
||||||
<FilterLayout sub_children={<FilterForm />} haveFilter={false} filterTitle="table.Coupon" />
|
<FilterLayout
|
||||||
|
sub_children={<FilterForm />}
|
||||||
|
haveFilter={false}
|
||||||
|
filterTitle="table.Coupon"
|
||||||
|
/>
|
||||||
<Table />
|
<Table />
|
||||||
<AddModalForm />
|
<AddModalForm />
|
||||||
<EditModalForm />
|
<EditModalForm />
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const App: React.FC = () => {
|
||||||
pagination: true,
|
pagination: true,
|
||||||
...filterState,
|
...filterState,
|
||||||
name,
|
name,
|
||||||
sort_by
|
sort_by,
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,8 @@ export const useColumns = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handelShow = (record: Coupon) => {
|
const handelShow = (record: Coupon) => {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(`${record?.id}`);
|
navigate(`${record?.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -53,7 +51,7 @@ export const useColumns = () => {
|
||||||
key: "name",
|
key: "name",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.name,
|
render: (_text, record) => record?.name,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: `${t("columns.amount")}`,
|
title: `${t("columns.amount")}`,
|
||||||
|
|
@ -61,7 +59,7 @@ export const useColumns = () => {
|
||||||
key: "amount",
|
key: "amount",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.amount,
|
render: (_text, record) => record?.amount,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: `${t("columns.code")}`,
|
title: `${t("columns.code")}`,
|
||||||
|
|
@ -69,7 +67,7 @@ export const useColumns = () => {
|
||||||
key: "code",
|
key: "code",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.code,
|
render: (_text, record) => record?.code,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: `${t("columns.due_to")}`,
|
title: `${t("columns.due_to")}`,
|
||||||
|
|
@ -85,10 +83,9 @@ export const useColumns = () => {
|
||||||
key: "status",
|
key: "status",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.status,
|
render: (_text, record) => record?.status,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const AddModel: React.FC = () => {
|
||||||
|
|
||||||
mutate({
|
mutate({
|
||||||
...values,
|
...values,
|
||||||
date: dayjs(values?.date).format('YYYY-MM-DD'),
|
date: dayjs(values?.date).format("YYYY-MM-DD"),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { getInitialValues, getValidationSchema, getValidationSchemaEdit } from "./formUtil";
|
import {
|
||||||
|
getInitialValues,
|
||||||
|
getValidationSchema,
|
||||||
|
getValidationSchemaEdit,
|
||||||
|
} from "./formUtil";
|
||||||
import { ModalEnum } from "../../../../enums/Model";
|
import { ModalEnum } from "../../../../enums/Model";
|
||||||
import LayoutModel from "../../../../Layout/Dashboard/LayoutModel";
|
import LayoutModel from "../../../../Layout/Dashboard/LayoutModel";
|
||||||
import ModelForm from "./ModelForm";
|
import ModelForm from "./ModelForm";
|
||||||
|
|
@ -17,7 +21,7 @@ const EditModel: React.FC = () => {
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any) => {
|
||||||
mutate({
|
mutate({
|
||||||
...values,
|
...values,
|
||||||
date: dayjs(values?.date).format('YYYY-MM-DD'),
|
date: dayjs(values?.date).format("YYYY-MM-DD"),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,17 @@ import { Col, Row } from "reactstrap";
|
||||||
import { useGetAllReseller } from "../../../../api/reseller";
|
import { useGetAllReseller } from "../../../../api/reseller";
|
||||||
|
|
||||||
const FilterForm = () => {
|
const FilterForm = () => {
|
||||||
const {data} = useGetAllReseller()
|
const { data } = useGetAllReseller();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="description" label="description" name="description" />
|
<ValidationField
|
||||||
|
placeholder="description"
|
||||||
|
label="description"
|
||||||
|
name="description"
|
||||||
|
/>
|
||||||
<ValidationField placeholder="amount" label="amount" name="amount" />
|
<ValidationField placeholder="amount" label="amount" name="amount" />
|
||||||
<ValidationField
|
<ValidationField
|
||||||
placeholder="reseller"
|
placeholder="reseller"
|
||||||
|
|
@ -19,11 +23,11 @@ const FilterForm = () => {
|
||||||
type="Select"
|
type="Select"
|
||||||
option={data?.data?.map((e: any) => ({
|
option={data?.data?.map((e: any) => ({
|
||||||
...e,
|
...e,
|
||||||
fullName: `${e.first_name} ${e.last_name}`
|
fullName: `${e.first_name} ${e.last_name}`,
|
||||||
}))}
|
}))}
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
label: "fullName",
|
label: "fullName",
|
||||||
value: "id"
|
value: "id",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,28 @@ import ValidationField from "../../../../Components/ValidationField/ValidationFi
|
||||||
import { useGetAllReseller } from "../../../../api/reseller";
|
import { useGetAllReseller } from "../../../../api/reseller";
|
||||||
|
|
||||||
const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
|
const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
|
||||||
const {data} = useGetAllReseller()
|
const { data } = useGetAllReseller();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="w-100">
|
<Row className="w-100">
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="description" label="description" name="description" />
|
<ValidationField
|
||||||
|
placeholder="description"
|
||||||
|
label="description"
|
||||||
|
name="description"
|
||||||
|
/>
|
||||||
<ValidationField placeholder="amount" label="amount" name="amount" />
|
<ValidationField placeholder="amount" label="amount" name="amount" />
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
<ValidationField placeholder="date" label="date" name="date" type="Date"/>
|
<ValidationField
|
||||||
{isEdit ? " " :
|
placeholder="date"
|
||||||
|
label="date"
|
||||||
|
name="date"
|
||||||
|
type="Date"
|
||||||
|
/>
|
||||||
|
{isEdit ? (
|
||||||
|
" "
|
||||||
|
) : (
|
||||||
<ValidationField
|
<ValidationField
|
||||||
placeholder="reseller"
|
placeholder="reseller"
|
||||||
label="reseller"
|
label="reseller"
|
||||||
|
|
@ -21,15 +32,14 @@ const Form = ({isEdit= false}:{isEdit?:boolean}) => {
|
||||||
type="Select"
|
type="Select"
|
||||||
option={data?.data?.map((e: any) => ({
|
option={data?.data?.map((e: any) => ({
|
||||||
...e,
|
...e,
|
||||||
fullName: `${e.first_name} ${e.last_name}`
|
fullName: `${e.first_name} ${e.last_name}`,
|
||||||
}))}
|
}))}
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
label: "fullName",
|
label: "fullName",
|
||||||
value: "id"
|
value: "id",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ 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 { canAddFinancial_Collection, canAddTags } from "../../../utils/hasAbilityFn";
|
import {
|
||||||
|
canAddFinancial_Collection,
|
||||||
|
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";
|
||||||
|
|
@ -23,7 +26,10 @@ const TableHeader = () => {
|
||||||
|
|
||||||
useSetPageTitle([
|
useSetPageTitle([
|
||||||
{ name: `${t(`page_header.home`)}`, path: "/" },
|
{ name: `${t(`page_header.home`)}`, path: "/" },
|
||||||
{name:`${t(`page_header.financial_collection`)}`, path:"financial_collection"}
|
{
|
||||||
|
name: `${t(`page_header.financial_collection`)}`,
|
||||||
|
path: "financial_collection",
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const deleteMutation = useDeleteFinancialCollection();
|
const deleteMutation = useDeleteFinancialCollection();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
|
||||||
import { useFilterStateState } from "../../../zustand/Filter";
|
import { useFilterStateState } from "../../../zustand/Filter";
|
||||||
import { useGetAllFinancialCollection } from "../../../api/financial_collection";
|
import { useGetAllFinancialCollection } from "../../../api/financial_collection";
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
|
|
||||||
const { filterState } = useFilterState();
|
const { filterState } = useFilterState();
|
||||||
const { Filter } = useFilterStateState();
|
const { Filter } = useFilterStateState();
|
||||||
const name = Filter?.name;
|
const name = Filter?.name;
|
||||||
|
|
|
||||||
|
|
@ -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 { canDeleteFinancial_Collection, canDeleteTags, canEditFinancial_Collection, canEditTags } from "../../../utils/hasAbilityFn";
|
import {
|
||||||
|
canDeleteFinancial_Collection,
|
||||||
|
canDeleteTags,
|
||||||
|
canEditFinancial_Collection,
|
||||||
|
canEditTags,
|
||||||
|
} from "../../../utils/hasAbilityFn";
|
||||||
import ActionButtons from "../../../Components/Table/ActionButtons";
|
import ActionButtons from "../../../Components/Table/ActionButtons";
|
||||||
|
|
||||||
export const useColumns = () => {
|
export const useColumns = () => {
|
||||||
|
|
@ -34,21 +39,21 @@ export const useColumns = () => {
|
||||||
dataIndex: "amount",
|
dataIndex: "amount",
|
||||||
key: "amount",
|
key: "amount",
|
||||||
align: "center",
|
align: "center",
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("columns.date"),
|
title: t("columns.date"),
|
||||||
dataIndex: "date",
|
dataIndex: "date",
|
||||||
key: "date",
|
key: "date",
|
||||||
align: "center",
|
align: "center",
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("columns.description"),
|
title: t("columns.description"),
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
key: "description",
|
key: "description",
|
||||||
align: "center",
|
align: "center",
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const TableHeader = () => {
|
||||||
|
|
||||||
useSetPageTitle([
|
useSetPageTitle([
|
||||||
{ name: `${t(`page_header.home`)}`, path: "/" },
|
{ name: `${t(`page_header.home`)}`, path: "/" },
|
||||||
{name:`${t(`page_header.grade`)}`, path:"grade"}
|
{ name: `${t(`page_header.grade`)}`, path: "grade" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const App: React.FC = () => {
|
||||||
pagination: true,
|
pagination: true,
|
||||||
...filterState,
|
...filterState,
|
||||||
name: filterState.name || name,
|
name: filterState.name || name,
|
||||||
sort_by
|
sort_by,
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,8 @@ export const useColumns = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setFilter } = useFilterStateState();
|
const { setFilter } = useFilterStateState();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handelShow = (record: Grade) => {
|
const handelShow = (record: Grade) => {
|
||||||
setFilter({})
|
setFilter({});
|
||||||
navigate(`${record?.id}`);
|
navigate(`${record?.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -53,7 +51,7 @@ export const useColumns = () => {
|
||||||
key: "name",
|
key: "name",
|
||||||
align: "center",
|
align: "center",
|
||||||
render: (_text, record) => record?.name,
|
render: (_text, record) => record?.name,
|
||||||
ellipsis:true
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("columns.image"),
|
title: t("columns.image"),
|
||||||
|
|
@ -67,7 +65,6 @@ export const useColumns = () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
title: t("columns.procedure"),
|
title: t("columns.procedure"),
|
||||||
key: "actions",
|
key: "actions",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const TableHeader = () => {
|
||||||
if (status === QueryStatusEnum.SUCCESS) {
|
if (status === QueryStatusEnum.SUCCESS) {
|
||||||
handleCancel();
|
handleCancel();
|
||||||
}
|
}
|
||||||
}, [status])
|
}, [status]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
|
|
@ -50,7 +50,9 @@ const TableHeader = () => {
|
||||||
<TitleDetailsForm />
|
<TitleDetailsForm />
|
||||||
<AttachmentForm />
|
<AttachmentForm />
|
||||||
<div className="resellerButton">
|
<div className="resellerButton">
|
||||||
<button type="button" onClick={handleCancel}>{t("practical.cancel")}</button>
|
<button type="button" onClick={handleCancel}>
|
||||||
|
{t("practical.cancel")}
|
||||||
|
</button>
|
||||||
<button type="submit">
|
<button type="submit">
|
||||||
{t("practical.add")} {t("models.reseller")}
|
{t("practical.add")} {t("models.reseller")}
|
||||||
{status === QueryStatusEnum.LOADING && (
|
{status === QueryStatusEnum.LOADING && (
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ const TableHeader = () => {
|
||||||
if (status === QueryStatusEnum.SUCCESS) {
|
if (status === QueryStatusEnum.SUCCESS) {
|
||||||
handleCancel();
|
handleCancel();
|
||||||
}
|
}
|
||||||
}, [status])
|
}, [status]);
|
||||||
return (
|
return (
|
||||||
<div className="TableWithHeader">
|
<div className="TableWithHeader">
|
||||||
<Suspense fallback={<Spin />}>
|
<Suspense fallback={<Spin />}>
|
||||||
|
|
@ -51,7 +51,9 @@ const TableHeader = () => {
|
||||||
<PasswordDetailsForm />
|
<PasswordDetailsForm />
|
||||||
<AttachmentForm />
|
<AttachmentForm />
|
||||||
<div className="resellerButton">
|
<div className="resellerButton">
|
||||||
<button type="button" onClick={handleCancel}>{t("practical.cancel")}</button>
|
<button type="button" onClick={handleCancel}>
|
||||||
|
{t("practical.cancel")}
|
||||||
|
</button>
|
||||||
<button type="submit">
|
<button type="submit">
|
||||||
{t("practical.add")} {t("models.reseller")}
|
{t("practical.add")} {t("models.reseller")}
|
||||||
{status === QueryStatusEnum.LOADING && (
|
{status === QueryStatusEnum.LOADING && (
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,16 @@ const PasswordDetailsForm = () => {
|
||||||
<h4>{t("header.password")}</h4>
|
<h4>{t("header.password")}</h4>
|
||||||
</header>
|
</header>
|
||||||
<main className="main_form_body">
|
<main className="main_form_body">
|
||||||
<ValidationField name={"password"} placeholder={"_"} label={"new_password"} />
|
<ValidationField
|
||||||
<ValidationField name={"password"} placeholder={"_"} label={"submit_password"} />
|
name={"password"}
|
||||||
|
placeholder={"_"}
|
||||||
|
label={"new_password"}
|
||||||
|
/>
|
||||||
|
<ValidationField
|
||||||
|
name={"password"}
|
||||||
|
placeholder={"_"}
|
||||||
|
label={"submit_password"}
|
||||||
|
/>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { useGetRole } from "../../../../api/role";
|
||||||
const PersonalDetailsForm = ({ isEdit = false }: { isEdit?: boolean }) => {
|
const PersonalDetailsForm = ({ isEdit = false }: { isEdit?: boolean }) => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const { data } = useGetRole();
|
const { data } = useGetRole();
|
||||||
const RoleData = data?.data
|
const RoleData = data?.data;
|
||||||
|
|
||||||
const sex = [
|
const sex = [
|
||||||
{ name: "male", id: "male" },
|
{ name: "male", id: "male" },
|
||||||
|
|
@ -28,11 +28,7 @@ const PersonalDetailsForm = ({isEdit= false}:{isEdit?:boolean}) => {
|
||||||
placeholder={"_"}
|
placeholder={"_"}
|
||||||
label={"username"}
|
label={"username"}
|
||||||
/>
|
/>
|
||||||
<ValidationField
|
<ValidationField name={"name"} placeholder={"_"} label={"name"} />
|
||||||
name={"name"}
|
|
||||||
placeholder={"_"}
|
|
||||||
label={"name"}
|
|
||||||
/>
|
|
||||||
<ValidationField
|
<ValidationField
|
||||||
name={"contact_number"}
|
name={"contact_number"}
|
||||||
placeholder={"_"}
|
placeholder={"_"}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ import { useGetAllCity } from "../../../../api/City";
|
||||||
const TitleDetailsForm = () => {
|
const TitleDetailsForm = () => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const { data: city } = useGetAllCity();
|
const { data: city } = useGetAllCity();
|
||||||
const [CityId, setCityId] = useState()
|
const [CityId, setCityId] = useState();
|
||||||
console.log(city);
|
console.log(city);
|
||||||
|
|
||||||
const { data } = useGetAllArea({
|
const { data } = useGetAllArea({
|
||||||
city_id:CityId
|
city_id: CityId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -38,7 +38,6 @@ const TitleDetailsForm = () => {
|
||||||
type="Select"
|
type="Select"
|
||||||
disabled={!CityId}
|
disabled={!CityId}
|
||||||
option={data?.data}
|
option={data?.data}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
{/* <ValidationField name={"address"} placeholder={"_"} label={"address"} /> */}
|
{/* <ValidationField name={"address"} placeholder={"_"} label={"address"} /> */}
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ export const getInitialValues = (objectToEdit: Partial<any>) => {
|
||||||
contact_number: objectToEdit?.contact_number ?? null,
|
contact_number: objectToEdit?.contact_number ?? null,
|
||||||
role_id: objectToEdit?.role_id ?? null,
|
role_id: objectToEdit?.role_id ?? null,
|
||||||
password: objectToEdit?.password ?? null,
|
password: objectToEdit?.password ?? null,
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const AddModel: React.FC = () => {
|
||||||
const handleSubmit = (values: any) => {
|
const handleSubmit = (values: any) => {
|
||||||
mutate({
|
mutate({
|
||||||
...values,
|
...values,
|
||||||
grade_id:values?.grade_id?.id
|
grade_id: values?.grade_id?.id,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ const App: React.FC = () => {
|
||||||
const name = Filter?.name;
|
const name = Filter?.name;
|
||||||
const sort_by = Filter?.sort_by;
|
const sort_by = Filter?.sort_by;
|
||||||
|
|
||||||
|
|
||||||
const response = useGetAllManager({
|
const response = useGetAllManager({
|
||||||
name,
|
name,
|
||||||
sort_by,
|
sort_by,
|
||||||
|
|
@ -21,7 +20,6 @@ const App: React.FC = () => {
|
||||||
...filterState,
|
...filterState,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return <DataTable response={response} useColumns={useColumns} />;
|
return <DataTable response={response} useColumns={useColumns} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ export const useColumns = () => {
|
||||||
|
|
||||||
const handleEdit = (record: Manager) => {
|
const handleEdit = (record: Manager) => {
|
||||||
setObjectToEdit(record);
|
setObjectToEdit(record);
|
||||||
navigate(`/${ABILITIES_ENUM?.MANAGERS}/${record?.id}/edit`)
|
navigate(`/${ABILITIES_ENUM?.MANAGERS}/${record?.id}/edit`);
|
||||||
|
|
||||||
};
|
};
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
|
|
|
||||||
81
src/Pages/Admin/Notifications/AddNotification/Add/Page.tsx
Normal file
81
src/Pages/Admin/Notifications/AddNotification/Add/Page.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import useSetPageTitle from "../../../../../Hooks/useSetPageTitle";
|
||||||
|
import PageHeader from "../../../../../Layout/Dashboard/PageHeader";
|
||||||
|
import { Suspense, useEffect } from "react";
|
||||||
|
import { Spin } from "antd";
|
||||||
|
import { ModalEnum } from "../../../../../enums/Model";
|
||||||
|
import PersonalDetailsForm from "../Form/PersonalDetailsForm";
|
||||||
|
import { Formik, Form } from "formik";
|
||||||
|
import { getInitialValues, getValidationSchema } from "../Form/formUtils";
|
||||||
|
import TitleDetailsForm from "../Form/TitleDetailsForm";
|
||||||
|
import AttachmentForm from "../Form/AttachmentForm";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { QueryStatusEnum } from "../../../../../enums/QueryStatus";
|
||||||
|
import { useAddNotification } from "../../../../../api/notification";
|
||||||
|
|
||||||
|
const TableHeader = () => {
|
||||||
|
const [t] = useTranslation();
|
||||||
|
const Navigate = useNavigate();
|
||||||
|
const { mutate, isSuccess, status } = useAddNotification();
|
||||||
|
useSetPageTitle(t(`page_header.add_notification`));
|
||||||
|
const handleSubmit = (values: any) => {
|
||||||
|
const DataToSend = {
|
||||||
|
...values,
|
||||||
|
location: {
|
||||||
|
lat: values.lat,
|
||||||
|
lng: values.lng,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
mutate(DataToSend);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
if (isSuccess === true) {
|
||||||
|
console.log(1);
|
||||||
|
Navigate("/add_Notifications");
|
||||||
|
}
|
||||||
|
}, [isSuccess]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="TableWithHeader">
|
||||||
|
<Suspense fallback={<Spin />}>
|
||||||
|
<PageHeader
|
||||||
|
pageTitle="manage_notification"
|
||||||
|
ModelAbility={ModalEnum?.NOTIFICATION_ADD}
|
||||||
|
canAdd={false}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<Formik
|
||||||
|
initialValues={getInitialValues({})}
|
||||||
|
validationSchema={getValidationSchema}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{({ dirty }) => (
|
||||||
|
<Form className="Form_details_container">
|
||||||
|
<TitleDetailsForm />
|
||||||
|
<PersonalDetailsForm />
|
||||||
|
<div className="resellerButton">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => Navigate("/add_Notifications")}
|
||||||
|
>
|
||||||
|
{t("practical.cancel")}
|
||||||
|
</button>
|
||||||
|
<button type="submit" disabled={!dirty}>
|
||||||
|
{t("practical.send")} {t("models.notifications")}
|
||||||
|
{status === QueryStatusEnum.LOADING && (
|
||||||
|
<span className="Spinier_Div">
|
||||||
|
<Spin />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</div>
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableHeader;
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { FaImage } from "react-icons/fa";
|
||||||
|
import ImageBoxField from "./ImageBoxField/ImageBoxField";
|
||||||
|
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||||
|
|
||||||
|
const AttachmentForm = () => {
|
||||||
|
const [t] = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="AttachmentForm">
|
||||||
|
<header className="header_form">
|
||||||
|
<FaImage />
|
||||||
|
<h4>{t("header.attachment")}</h4>
|
||||||
|
</header>
|
||||||
|
<div className="AttachmentFormBody ">
|
||||||
|
<main className="main_form_body">
|
||||||
|
<ImageBoxField name="personal_image" />
|
||||||
|
<ImageBoxField name="id_image" />
|
||||||
|
</main>
|
||||||
|
<div className="MapField">
|
||||||
|
<ValidationField name="lat" placeholder="lat" label="lat" />
|
||||||
|
<ValidationField name="lng" placeholder="lng" label="lng" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AttachmentForm;
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from "react";
|
||||||
|
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||||
|
import { Col, Row } from "reactstrap";
|
||||||
|
|
||||||
|
const FilterForm = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<ValidationField
|
||||||
|
placeholder="first_name"
|
||||||
|
label="first_name"
|
||||||
|
name="first_name"
|
||||||
|
/>
|
||||||
|
{/* <ValidationField placeholder="last_name" label="last_name" name="last_name" /> */}
|
||||||
|
</Col>
|
||||||
|
{/* <Col>
|
||||||
|
<ValidationField placeholder="username" label="username" name="username" />
|
||||||
|
</Col> */}
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterForm;
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
.ImageBoxField {
|
||||||
|
.ImageBox {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: max(1.5px, 0.1vw) dashed #a9c3f1;
|
||||||
|
margin-block: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
z-index: 9999999 !important;
|
||||||
|
.ImageBoxIcon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.imagePreview {
|
||||||
|
max-width: 99%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 99%;
|
||||||
|
object-fit: contain;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ImageHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ImageCancelIcon {
|
||||||
|
width: 16px !important;
|
||||||
|
height: 16px !important;
|
||||||
|
}
|
||||||
|
.ImageBoxIcon {
|
||||||
|
width: 20px !important;
|
||||||
|
height: 20px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { useFormikContext } from "formik";
|
||||||
|
import { useState, useRef, useEffect } from "react";
|
||||||
|
import "./ImageBoxField.scss";
|
||||||
|
import ImageIcon from "./ImageIcon";
|
||||||
|
import ImageCancelIcon from "./ImageCancelIcon";
|
||||||
|
import { generateImagePreview } from "./generateImagePreview";
|
||||||
|
import { getNestedValue } from "../../../../../../utils/getNestedValue";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
// Helper function to generate image preview from a File
|
||||||
|
|
||||||
|
const ImageBoxField = ({ name }: any) => {
|
||||||
|
const formik = useFormikContext<any>();
|
||||||
|
const value = getNestedValue(formik.values, name);
|
||||||
|
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||||
|
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (value instanceof File) {
|
||||||
|
generateImagePreview(value, setImagePreview);
|
||||||
|
} else if (typeof value === "string") {
|
||||||
|
setImagePreview(value);
|
||||||
|
} else {
|
||||||
|
setImagePreview(null);
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
const handleFileChange = (event: any) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
generateImagePreview(file, setImagePreview);
|
||||||
|
formik.setFieldValue(name, file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleButtonClick = () => {
|
||||||
|
const fileInput = fileInputRef.current;
|
||||||
|
if (fileInput) {
|
||||||
|
fileInput.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
setImagePreview("");
|
||||||
|
formik.setFieldValue(name, "");
|
||||||
|
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.value = "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const [t] = useTranslation();
|
||||||
|
return (
|
||||||
|
<div className="ImageBoxField">
|
||||||
|
<header>{t(`input.${name}`)}</header>
|
||||||
|
<div className="ImageHeader">
|
||||||
|
{imagePreview ? (
|
||||||
|
<>
|
||||||
|
<ImageCancelIcon
|
||||||
|
onClick={handleCancel}
|
||||||
|
className="ImageCancelIcon"
|
||||||
|
/>
|
||||||
|
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="VisibleHidden">hidden</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="ImageBox">
|
||||||
|
{imagePreview ? (
|
||||||
|
<img src={imagePreview} alt="Preview" className="imagePreview" />
|
||||||
|
) : (
|
||||||
|
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
id={`file-input-${name}`}
|
||||||
|
type="file"
|
||||||
|
accept="image/png, image/jpeg, image/webp"
|
||||||
|
style={{ display: "none" }}
|
||||||
|
onChange={handleFileChange}
|
||||||
|
ref={fileInputRef}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ImageBoxField;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface ImageCancelIconProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||||
|
|
||||||
|
const ImageCancelIcon: React.FC<ImageCancelIconProps> = (props) => {
|
||||||
|
return (
|
||||||
|
<div {...props}>
|
||||||
|
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
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"
|
||||||
|
fill="#515B73"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ImageCancelIcon;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface ImageIconProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||||
|
|
||||||
|
const ImageIcon: React.FC<ImageIconProps> = (props) => {
|
||||||
|
return (
|
||||||
|
<div {...props}>
|
||||||
|
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
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;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user