This commit is contained in:
Majd_dk 2024-11-19 16:23:12 +03:00
commit 7b966d93ed
354 changed files with 12645 additions and 8885 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
VITE_BASE_URL="https://nerd-back.point-dev.net/api/"

1
.env.example Normal file
View File

@ -0,0 +1 @@
REACT_APP_BASE_URL=

1
package-lock.json generated
View File

@ -12782,7 +12782,6 @@
"version": "2.0.15",
"resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.15.tgz",
"integrity": "sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.8.1",
"qr.js": "0.0.0"

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
import { Divider } from 'antd'
import { useTranslation } from 'react-i18next'
import { Divider } from "antd";
import { useTranslation } from "react-i18next";
import { RxHome } from "react-icons/rx";
const AddressCard = ({ data }: { data: any }) => {
const { t } = useTranslation();
return (
<div className='address_card'>
<div className="address_card">
<h5>{t("practical.address")}</h5>
<Divider />
<div className="address_card_body">
@ -20,9 +20,7 @@ const AddressCard = ({ data }: { data: any }) => {
))}
</div>
</div>
)
}
export default AddressCard
);
};
export default AddressCard;

View File

@ -1,15 +1,15 @@
import { Divider } from 'antd';
import { useTranslation } from 'react-i18next'
import ImageBoxField from '../CustomFields/ImageBoxField/ImageBoxField';
import { Divider } from "antd";
import { useTranslation } from "react-i18next";
import ImageBoxField from "../CustomFields/ImageBoxField/ImageBoxField";
const AttachmentsCard = ({ data }: { data?: any }) => {
const { t } = useTranslation();
return (
<div className='attachments_card'>
<div className="attachments_card">
<h5>{t("practical.address")}</h5>
<Divider />
<div className='attachments_body'>
<div className="attachments_body">
<h5>{t("practical.id_photo")}</h5>
{/* {data?.map((address:any)=>( */}
<span>
@ -18,7 +18,7 @@ const AttachmentsCard = ({data}:{data?:any}) => {
{/* ))} */}
</div>
</div>
)
}
);
};
export default AttachmentsCard
export default AttachmentsCard;

View File

@ -1,12 +1,24 @@
import { Button, Divider } from 'antd'
import { useTranslation } from 'react-i18next'
import { canAddReSeller } from '../../utils/hasAbilityFn';
import { Button, Divider } from "antd";
import { useTranslation } from "react-i18next";
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();
return (
<div className='info_card'>
<div className="info_card">
<div className="info_card_header">
<img src="/Image/faker_user.png " alt="" />
<div className="student_name_and_sub">
@ -22,18 +34,16 @@ const InfoCard = ({ data, name, status,withButton = false,handleClick}:{ data:an
<p>{student?.value}</p>
</span>
))}
{withButton ?
canAddReSeller &&
<Button onClick={handleClick} className='info_card_button'>
{withButton
? canAddReSeller && (
<Button onClick={handleClick} className="info_card_button">
{t("practical.collecting_an_amount")}
</Button>
)
: ""}
</div>
</div>
)
}
export default InfoCard
);
};
export default InfoCard;

View File

@ -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" },
];
export const ReSellerParamInfo = [
{ 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" },
]
];
export const StudentAddressInfo = [
{ key: "address", value: "moa moamasom aoms omaosm oasm oasm oasm asm aom" },
]
];
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" },
]
];

View File

@ -14,7 +14,7 @@ const ImageBoxField = ({ name }: any) => {
const value = getNestedValue(formik?.values, name);
const [imagePreview, setImagePreview] = useState<string | null>(null);
const fileInputRef = useRef<HTMLInputElement | null>(null);
const [t] = useTranslation()
const [t] = useTranslation();
useEffect(() => {
if (value instanceof File) {
generateImagePreview(value, setImagePreview);
@ -32,8 +32,8 @@ const ImageBoxField = ({ name }: any) => {
const maxSize = 2 * 1024 * 1024;
if (file.size > maxSize) {
alert(t('validation.File_size_exceeds_2_MB_limit.'));
event.target.value = '';
alert(t("validation.File_size_exceeds_2_MB_limit."));
event.target.value = "";
return;
}

View File

@ -9,8 +9,9 @@ import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
// Helper function to generate image preview from a File
const ImageBoxFieldMemo = memo(({ form,field }: any) => {
const {values,setFieldValue} = form
const ImageBoxFieldMemo = memo(
({ form, field }: any) => {
const { values, setFieldValue } = form;
const { name } = field;
const value = getNestedValue(values, name);
const [imagePreview, setImagePreview] = useState<string | null>(null);
@ -33,8 +34,8 @@ import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
const maxSize = 2 * 1024 * 1024;
if (file.size > maxSize) {
alert(t('validation.File_size_exceeds_2_MB_limit.'));
event.target.value = '';
alert(t("validation.File_size_exceeds_2_MB_limit."));
event.target.value = "";
return;
}
@ -98,8 +99,10 @@ import { areFieldPropsEqual } from "../../../utils/areFieldPropsEqual";
/>
</div>
);
}, (prevProps, nextProps) => {
return areFieldPropsEqual(prevProps, nextProps)
});
},
(prevProps, nextProps) => {
return areFieldPropsEqual(prevProps, nextProps);
},
);
export default ImageBoxFieldMemo;

View File

@ -1,7 +1,6 @@
import React from 'react';
import { BlockMath } from 'react-katex';
import 'katex/dist/katex.min.css';
import React from "react";
import { BlockMath } from "react-katex";
import "katex/dist/katex.min.css";
const LatexPreview = ({ latex }: { latex: string }) => {
// console.log(latex);
@ -10,13 +9,7 @@ const LatexPreview = ({ latex }: { latex: string }) => {
return (
<div>
<BlockMath>
{latex}
</BlockMath>
<BlockMath>{latex}</BlockMath>
</div>
);
};

View File

@ -9,19 +9,19 @@ const SelectTag: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>("");
const [fieldValue, setFieldValue] = useState<string>("");
const [NewAdditionalData, setNewAdditionalData] = useState({})
const [NewAdditionalData, setNewAdditionalData] = useState({});
const formik = useFormikContext<any>();
const handleChange = (value: any, option: any) => {
console.log(option);
console.log(value);
const newSelectedOption = option?.pop()
const newSelectedOption = option?.pop();
console.log(newSelectedOption);
const newObject = {
id: newSelectedOption?.id,
name:newSelectedOption?.name
}
setNewAdditionalData(newObject)
name: newSelectedOption?.name,
};
setNewAdditionalData(newObject);
formik.setFieldValue("tags", value);
setSearchValue("");
setFieldValue("");
@ -34,7 +34,6 @@ const SelectTag: React.FC = () => {
});
const handleFieldChange = (value: string) => {
setFieldValue(value);
};
@ -48,12 +47,10 @@ const SelectTag: React.FC = () => {
});
const [t] = useTranslation();
const initialData = formik?.values?.tags?.filter((item:any)=>{
return item?.id
}) ?? []
const initialData =
formik?.values?.tags?.filter((item: any) => {
return item?.id;
}) ?? [];
const options = data?.data ?? [];
const additionalData =
@ -64,17 +61,20 @@ const SelectTag: React.FC = () => {
const value =
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(
new Map(
AllOptions
.filter(item => Object.keys(item).length > 0) // Filter out empty objects
.map(item => [item.id, item]) // Create [id, item] pairs to ensure uniqueness
).values()
AllOptions.filter((item) => Object.keys(item).length > 0) // Filter out empty objects
.map((item) => [item.id, item]), // Create [id, item] pairs to ensure uniqueness
).values(),
);
return (
<div className="SelectTag">
<label htmlFor="">{t("models.tag")}</label>

View File

@ -14,12 +14,13 @@ const SelectTagV2: React.FC = () => {
const { data, isLoading } = useGetAllTag({ name: searchValue });
const { t } = useTranslation();
// Get selected tags from Formik
const CurrentTags = formik.values.tags ?? []; // Assuming tags are stored as array of objects
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) => {
// console.log(option,"option");
@ -51,7 +52,6 @@ const SelectTagV2: React.FC = () => {
console.log(additionalData);
return (
<div className="SelectTag">
<label>{t("models.tag")}</label>
@ -77,7 +77,6 @@ const SelectTagV2: React.FC = () => {
}
}}
value={NewShapeTags}
/>
</div>
);

View File

@ -23,7 +23,6 @@ const SearchField: React.FC<Props> = ({ placeholder, searchBy }) => {
const handleInputChangeWithDebounce = useDebounce((value: string) => {
if (Number(page) > 1) {
}
setFilter({
[searchBy]: value,

View File

@ -58,7 +58,7 @@ const SearchFieldWithSelect: React.FC<Props> = ({
const filteredOptions = options.filter((option) =>
option.label.toLowerCase().includes(searchTerm.toLowerCase()),
);
const Type = localStorage.getItem('type');
const Type = localStorage.getItem("type");
return (
<div ref={node} className={`search-field ${isOpen ? "open" : ""}`}>
<div className="search-header" onClick={toggleDropdown}>
@ -87,7 +87,7 @@ const SearchFieldWithSelect: React.FC<Props> = ({
<div>{option.label}</div>
{/* {withIcon && <IoSearch className="search__icon" />} */}
</div>
)
);
})}
</div>
</div>

View File

@ -10,13 +10,12 @@ const PaginationColumn = () => {
const navigate = useNavigate();
const { Filter, setFilter } = useFilterStateState();
const handleChange = (value: string) => {
navigate(`?per_page=${value}`);
setFilter({
per_page:value
})
per_page: value,
});
};
return (

View File

@ -1,5 +1,5 @@
import React, { useCallback, useState } from "react";
import '../styles/index.scss';
import "../styles/index.scss";
import CustomInput from "../design-system/CustomInput";
import { Button } from "antd";
import { useTranslation } from "react-i18next";
@ -24,22 +24,23 @@ const useFilter = () => {
};
const FilterBody = ({ children }: IFilterBody) => {
const [values, setValues] = useState({ name1: '', name2: '' });
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const [values, setValues] = useState({ name1: "", name2: "" });
const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setValues((prev) => ({ ...prev, [name]: value }));
}, []);
},
[],
);
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log(values, "values");
};
const [t] = useTranslation()
const [t] = useTranslation();
return (
<div className={`filter_body ${isBodyVisible ? 'visible' : 'hidden'}`}>
<div className={`filter_body ${isBodyVisible ? "visible" : "hidden"}`}>
<form onSubmit={handleSubmit}>
{children}
<CustomInput
@ -52,8 +53,10 @@ const useFilter = () => {
value={values.name2}
onChange={handleChange}
/>
<Button block htmlType="submit" type="primary" > {t("practical.submit")} </Button>
<Button block htmlType="submit" type="primary">
{" "}
{t("practical.submit")}{" "}
</Button>
</form>
</div>
);

View File

@ -1,5 +1,5 @@
import { Input } from 'antd';
import React from 'react';
import { Input } from "antd";
import React from "react";
interface CustomInputProps {
name: string;
@ -7,16 +7,11 @@ interface CustomInputProps {
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
return (
<Input
type="text"
name={name}
value={value}
onChange={onChange}
/>
return <Input type="text" name={name} value={value} onChange={onChange} />;
},
);
});
export default CustomInput;

View File

@ -1,13 +1,15 @@
.filter_body {
max-height: 0;
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;
transform: translateY(-20px);
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.filter_body.visible {
@ -30,4 +32,3 @@
width: 70%;
padding: 50px;
}

View File

@ -1,23 +1,29 @@
import { Modal } from 'antd'
import TextArea from 'antd/es/input/TextArea'
import { useFormikContext } from 'formik';
import React, { useState } from 'react'
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
import { useTranslation } from 'react-i18next';
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
import { Modal } from "antd";
import TextArea from "antd/es/input/TextArea";
import { useFormikContext } from "formik";
import React, { useState } from "react";
import { convertMathMLToLaTeX } from "../../utils/convertMathMLToLaTeX";
import { useTranslation } from "react-i18next";
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 {values,setFieldValue,getFieldProps} = useFormikContext<any>()
const { values, setFieldValue, getFieldProps } = useFormikContext<any>();
const currentValue = getFieldProps(name).value
const currentValue = getFieldProps(name).value;
const handleOk = () => {
const oldValue = currentValue ?? "";
const newLatex = convertMathMLToLaTeX(Latex);
@ -25,35 +31,39 @@ const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen,setCurren
if (newLatex) {
setFieldValue(name, oldValue + " $$ " + newLatex + " $$ ");
setCurrentValue(oldValue + " $$ " +newLatex +" $$ ")
setLatex("")
setCurrentValue(oldValue + " $$ " + newLatex + " $$ ");
setLatex("");
setIsModalOpen(false);
} else {
setFieldValue(name, oldValue + " $$ " + Latex + " $$ ");
setCurrentValue(oldValue + " $$ " +Latex +" $$ ")
setLatex("")
setCurrentValue(oldValue + " $$ " + Latex + " $$ ");
setLatex("");
setIsModalOpen(false);
}
};
const handleCancel = () => {
setIsModalOpen(false);
setLatex("")
setLatex("");
};
const handleChangeInputLatex = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const newValue = e.target.value;
setLatex(newValue)
setLatex(newValue);
};
const [t] = useTranslation()
const [t] = useTranslation();
return (
<Modal footer={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
<div className='latexModal'>
<label className='mb-3'> {t("header.past_your_MMl_text")} </label>
<Modal
footer={false}
open={isModalOpen}
onOk={handleOk}
onCancel={handleCancel}
>
<div className="latexModal">
<label className="mb-3"> {t("header.past_your_MMl_text")} </label>
<TextArea
size="large"
showCount
@ -67,17 +77,13 @@ const AddLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen,setCurren
<div className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")}
</div>
<div
className="add_button"
onClick={handleOk}
>
<div className="add_button" onClick={handleOk}>
{t(`practical.${"add"}`)}
</div>
</div>
</div>
</Modal>
);
};
)
}
export default AddLaTexModal
export default AddLaTexModal;

View File

@ -1,22 +1,27 @@
import { Modal } from 'antd'
import TextArea from 'antd/es/input/TextArea'
import { useFormikContext } from 'formik';
import React, { useState } from 'react'
import { convertMathMLToLaTeX } from '../../utils/convertMathMLToLaTeX';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
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,
import { Modal } from "antd";
import TextArea from "antd/es/input/TextArea";
import { useFormikContext } from "formik";
import React, { useState } from "react";
import { convertMathMLToLaTeX } from "../../utils/convertMathMLToLaTeX";
import { useTranslation } from "react-i18next";
import { toast } from "react-toastify";
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 {values} = useFormikContext<any>()
const [Value, setValue] = useState(Latex?.text ?? Latex)
const { values } = useFormikContext<any>();
const [Value, setValue] = useState(Latex?.text ?? Latex);
const handleOk = () => {
console.log(1);
@ -31,18 +36,16 @@ const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
if (newLatex) {
const newArray = Preview?.map((item: any, index: number) => {
if(item?.key)
return item
})
if (item?.key) return item;
});
} else {
toast.error(t("validation.that_is_not_a_valid_mml"))
toast.error(t("validation.that_is_not_a_valid_mml"));
}
};
const handleCancel = () => {
setIsModalOpen(false);
setLatex("")
setLatex("");
};
const handleChangeInputLatex = (
@ -50,15 +53,19 @@ const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
) => {
const newValue = e.target.value;
console.log(newValue, "newValue");
setValue(newValue)
setValue(newValue);
};
const [t] = useTranslation()
const [t] = useTranslation();
return (
<Modal footer={false} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
<div className='latexModal'>
<label className='mb-3'> {t("header.past_your_MMl_text")} </label>
<Modal
footer={false}
open={isModalOpen}
onOk={handleOk}
onCancel={handleCancel}
>
<div className="latexModal">
<label className="mb-3"> {t("header.past_your_MMl_text")} </label>
<TextArea
size="large"
showCount
@ -66,24 +73,19 @@ const EditLaTexModal = ({name,setLatex,Latex,setIsModalOpen,isModalOpen}:{
autoSize={{ minRows: 4, maxRows: 10 }}
style={{ height: "400px" }}
onChange={handleChangeInputLatex}
value={Value
}
value={Value}
/>
<div className="buttons">
<div className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")}
</div>
<div
className="add_button"
onClick={handleOk}
>
<div className="add_button" onClick={handleOk}>
{t(`practical.${"edit"}`)}
</div>
</div>
</div>
</Modal>
);
};
)
}
export default EditLaTexModal
export default EditLaTexModal;

View File

@ -1,20 +1,20 @@
import TextArea from 'antd/es/input/TextArea';
import React, { Suspense, useEffect, useState } from 'react';
import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
import LatexPreview from '../CustomFields/MathComponent';
import { Checkbox } from 'antd';
import { CheckboxProps } from 'antd/lib';
import { useTranslation } from 'react-i18next';
import { FaPlus } from 'react-icons/fa';
import { useObjectToEdit } from '../../zustand/ObjectToEditState';
import SpinContainer from '../Layout/SpinContainer';
import { areFieldPropsEqual } from './areFieldPropsEqual';
import TextArea from "antd/es/input/TextArea";
import React, { Suspense, useEffect, useState } from "react";
import { parseTextAndLatex } from "../../utils/parseTextAndLatex";
import LatexPreview from "../CustomFields/MathComponent";
import { Checkbox } from "antd";
import { CheckboxProps } from "antd/lib";
import { useTranslation } from "react-i18next";
import { FaPlus } from "react-icons/fa";
import { useObjectToEdit } from "../../zustand/ObjectToEditState";
import SpinContainer from "../Layout/SpinContainer";
import { areFieldPropsEqual } from "./areFieldPropsEqual";
const AddLazyModal = React.lazy(() => import("./AddLaTexModal"));
const EditLazyModal = React.lazy(() => import("./EditLaTexModal"));
const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...props }) => {
const LaTeXInputMemo: React.FC<any> = React.memo(
({ field, form, label, ...props }) => {
const { name, value } = field;
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 Preview = parseTextAndLatex(value ?? "");
const onPreviewChange: CheckboxProps['onChange'] = (e) => {
const onPreviewChange: CheckboxProps["onChange"] = (e) => {
setShowPreview(e.target.checked);
};
@ -44,62 +43,65 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
// setIsEditModalOpen(true);
};
const [curCentValue, setCurrentValue] = useState(value)
const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setCurrentValue(e.target.value)
const [curCentValue, setCurrentValue] = useState(value);
const handleChangeInput = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
setCurrentValue(e.target.value);
};
const onBlur = () => {
if (curCentValue !== value) {
setFieldValue(name, curCentValue);
}
}
};
useEffect(() => {
if (Success) {
setCurrentValue(null)
setCurrentValue(null);
}
}, [Success])
}, [Success]);
useEffect(() => {
if (value) {
setCurrentValue(value)
setCurrentValue(value);
}
}, [value])
}, [value]);
const isError = !!touched?.[name] && !!errors?.[name];
const errorMessage = isError ? errors?.[name] as string ?? "" : "" ;
const errorMessage = isError ? ((errors?.[name] as string) ?? "") : "";
console.log(values);
let metaName = name.substring(0, name.lastIndexOf('.'));
if (metaName.includes('.') || metaName.includes('[')) { metaName += ".meta";} else {metaName += "meta"}
let metaName = name.substring(0, name.lastIndexOf("."));
if (metaName.includes(".") || metaName.includes("[")) {
metaName += ".meta";
} else {
metaName += "meta";
}
const meta = getFieldProps(metaName).value;
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 = () => {
if (Dir === "ltr") {
setDir("rtl")
setFieldValue(metaName,{...(meta ?? {}), direction:"rtl"})
setDir("rtl");
setFieldValue(metaName, { ...(meta ?? {}), direction: "rtl" });
} else {
setDir("ltr")
setFieldValue(metaName,{...(meta ?? {}), direction:"ltr"})
}
setDir("ltr");
setFieldValue(metaName, { ...(meta ?? {}), direction: "ltr" });
}
};
return (
<div className='LaTeXInput'>
<div className="LaTeXInput">
<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>
<div className='LaTeXInputArea'>
<div className="LaTeXInputArea">
<TextArea
size="large"
showCount
@ -112,30 +114,39 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
dir={Dir}
{...props}
/>
<div className='LaTeXInputOptions'>
<Checkbox onChange={handleChangeDirection} checked={direction === "ltr"} >{t("header.change_direction")}</Checkbox>
<div className="LaTeXInputOptions">
<Checkbox
onChange={handleChangeDirection}
checked={direction === "ltr"}
>
{t("header.change_direction")}
</Checkbox>
{ShowLatexOption && (
<>
<Checkbox onChange={onPreviewChange}>{t("header.show_preview")}</Checkbox>
<button type='button' className='addMML' onClick={showModal}>
<Checkbox onChange={onPreviewChange}>
{t("header.show_preview")}
</Checkbox>
<button type="button" className="addMML" onClick={showModal}>
<FaPlus /> {t("MML")}
</button>
</>
)}
</div>
{showPreview && (
<div className='showPreviewInput'>
<div className="showPreviewInput">
{Preview?.map((item: any, index: number) => {
if (item?.isLatex) {
console.log(item?.text);
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} />
</span>
);
@ -147,14 +158,28 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
</div>
<Suspense fallback={<SpinContainer />}>
<AddLazyModal name={name} Latex={Latex} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} setLatex={setLatex} setCurrentValue={setCurrentValue} />
<EditLazyModal name={name} Latex={Latex} isModalOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} setLatex={setLatex} />
<AddLazyModal
name={name}
Latex={Latex}
isModalOpen={isModalOpen}
setIsModalOpen={setIsModalOpen}
setLatex={setLatex}
setCurrentValue={setCurrentValue}
/>
<EditLazyModal
name={name}
Latex={Latex}
isModalOpen={isEditModalOpen}
setIsModalOpen={setIsEditModalOpen}
setLatex={setLatex}
/>
</Suspense>
</div>
);
}, (prevProps, nextProps) => {
return areFieldPropsEqual(prevProps, nextProps)
});
},
(prevProps, nextProps) => {
return areFieldPropsEqual(prevProps, nextProps);
},
);
export default LaTeXInputMemo;

View File

@ -1,10 +1,7 @@
// utilityFunctions.ts
import { FieldProps } from 'formik';
import { FieldProps } from "formik";
export const areFieldPropsEqual = (
prevProps: any,
nextProps: any
): boolean => {
export const areFieldPropsEqual = (prevProps: any, nextProps: any): boolean => {
const prevError = prevProps.form.errors[prevProps.field.name];
const nextError = nextProps.form.errors[nextProps.field.name];
@ -14,7 +11,5 @@ export const areFieldPropsEqual = (
const prevValue = prevProps.field.value;
const nextValue = nextProps.field.value;
return (
false
);
return false;
};

View File

@ -38,7 +38,7 @@ const NavBarRightSide = () => {
icon={<CiCirclePlus size={25} />}
/>
<TooltipComp
onClick={()=>(Navigate('/notifications'))}
onClick={() => Navigate("/notifications")}
className="NotificationsIcon"
note="notification"
color="#E0E0E0"
@ -57,7 +57,9 @@ const NavBarRightSide = () => {
</span> */}
<Image
// onClick={()=>(Navigate('/profile'))}
src="/Image/faker_user.png" alt="Profile" />
src="/Image/faker_user.png"
alt="Profile"
/>
</div>
</article>
);

View File

@ -16,7 +16,7 @@ const TooltipComp = ({
color: string;
icon: any;
className?: string;
onClick?:() => void
onClick?: () => void;
}) => {
const [t] = useTranslation();
const { handel_open_model } = useModalHandler();

View File

@ -16,9 +16,9 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handleNavigate = () => {
setFilter({})
navigate(item.path || "/")
}
setFilter({});
navigate(item.path || "/");
};
return (
<>
@ -26,11 +26,7 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
className={`link ${isActive ? "active" : ""} ${item?.children && "DropDownLink"}`}
onClick={() => handleNavigate()}
>
<Tooltip
placement="topLeft"
title={t(item?.text)}
color={'#E0E0E0'}
>
<Tooltip placement="topLeft" title={t(item?.text)} color={"#E0E0E0"}>
<i>{item.icon}</i>
</Tooltip>
{/* Conditionally render the text based on sidebar width */}

View File

@ -10,6 +10,7 @@ export const renderRoutesRecursively = (routes: TMenuItem[]) =>
if (!useAbility) {
return false;
}
return (
<React.Fragment key={route.path}>
<Route path={route.path} element={RenderRouteElement(route)} />

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Switch } from 'antd';
import React from "react";
import { Switch } from "antd";
export interface SwitchProps {
onChange?: (checked: any, event: any) => any;
checked?: boolean;
@ -11,14 +11,14 @@ const onSwitchChange = (checked: boolean) => {
const SwitchButton = ({ onChange, checked }: SwitchProps) => {
return (
<Switch
className='switch_button'
className="switch_button"
defaultChecked
onChange={(checked: any, event: any) =>
onChange ? onChange(checked, event) : onSwitchChange(checked)
}
// checked={checked}
/>
)
}
);
};
export default SwitchButton;

View File

@ -7,7 +7,6 @@ import { BsEyeFill } from "react-icons/bs";
import { GoTrash } from "react-icons/go";
import { BsQrCode } from "react-icons/bs";
interface ActionButtonsProps {
canEdit?: boolean;
canDelete?: boolean;
@ -19,7 +18,7 @@ interface ActionButtonsProps {
onShow?: () => void;
index?: number;
className?: string;
canShowQr?:boolean
canShowQr?: boolean;
onShoqQr?: () => void;
}

View File

@ -1,11 +1,12 @@
import React from 'react';
import QRCode from 'react-qr-code';
import React from "react";
import QRCode from "react-qr-code";
const QRCodeGenerator = ({url}:any) => {
const QRCodeGenerator = ({ url, serial }: any) => {
const qrValue = `${url}/${serial}`;
console.log(qrValue);
return (
<div style={{display:'flex',justifyContent:'center'}} >
<QRCode value={url} size={230} type='link' />
<div style={{ display: "flex", justifyContent: "center" }}>
<QRCode value={qrValue} size={230} type="link" />
</div>
);
};

View File

@ -1,18 +1,24 @@
import { Button } from 'antd'
import { useTranslation } from 'react-i18next'
import { Button } from "antd";
import { useTranslation } from "react-i18next";
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();
return (
<div>
<Button className=' setting_edit_button' onClick={onClick}>
<Button className=" setting_edit_button" onClick={onClick}>
<CiEdit />
{t(`header.edit`) ?? (`header.${buttonName}`)}
{t(`header.edit`) ?? `header.${buttonName}`}
</Button>
</div>
)
}
);
};
export default EditSettingButton
export default EditSettingButton;

View File

@ -1,13 +1,23 @@
import { Button } from 'antd'
import { useTranslation } from 'react-i18next'
import { Button } from "antd";
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();
return (
<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>
)
}
);
};
export default SecuritySettingButton
export default SecuritySettingButton;

View 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;

View File

@ -1,15 +1,23 @@
import { Button } from 'antd';
import { useTranslation } from 'react-i18next';
import { Button } from "antd";
import { useTranslation } from "react-i18next";
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();
return (
<Button className='trash_button' onClick={onClick}>
<Button className="trash_button" onClick={onClick}>
{icon ? <HiOutlineTrash /> : ""}
{t(`header.${name}`)}
</Button>
)
}
);
};
export default TrashButton
export default TrashButton;

View File

@ -34,7 +34,6 @@ interface FormikFormProps extends Omit<FormikConfig<any>, OmitFormikProps> {
setIsOpen: any;
}
const useFilter = () => {
const { setIsOpen, isOpen } = useModalState((state) => state);
const { filterState, setFilterState, clearFilterState } = useFilterState();

View File

@ -53,13 +53,12 @@ const File = ({
const maxSize = 2 * 1024 * 1024; // 2 MB in bytes
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 true; // Allow the file to be uploaded
};
return (
<div className={`ValidationField upload_image_button ${className ?? ""} `}>
<label htmlFor={name} className="text">
@ -76,7 +75,6 @@ const File = ({
customRequest={customRequest}
className={` w-100`}
id={name}
>
<Button
className={isError ? "isError w-100 " : " w-100"}

View File

@ -52,7 +52,6 @@ const SearchField = ({
if (isMulti) {
formik?.setFieldValue(name, option ?? []);
} else {
formik?.setFieldValue(name, option ?? {});
}
@ -96,7 +95,8 @@ const SearchField = ({
const handleScroll = (event: any) => {
const target = event.target;
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) {
console.log("Scrolled to the last option!");
@ -109,9 +109,11 @@ const SearchField = ({
console.log(AllPagesOption);
console.log(option, "option");
const value = isMulti ? formik.values[name]?.map((item:any)=>{
return item?.name ?? item
}) : formik.values[name]?.["name"] ?? ""
const value = isMulti
? formik.values[name]?.map((item: any) => {
return item?.name ?? item;
})
: (formik.values[name]?.["name"] ?? "");
console.log(value);
return (

View File

@ -47,7 +47,6 @@ const TextField = ({
showCount
maxLength={1000}
autoSize={{ minRows: 4, maxRows: 10 }}
onChange={onChange || TextFilehandleChange}
id={name}
{...props}

View File

@ -49,10 +49,7 @@ const TextFieldMML = ({
onChange={onChange || TextFilehandleChange}
id={name}
{...props}
/>
</ValidationFieldContainer>
</div>
);

View File

@ -23,5 +23,5 @@ export {
SearchField,
TextField,
DropFile,
TextAreaMML
TextAreaMML,
};

View File

@ -68,8 +68,6 @@
height: 120px;
}
//// malty select
///
.ant-select-multiple {

View File

@ -1,5 +1,4 @@
export const translateOptions = (options: any, t: any) => {
return options?.map((opt: any) => ({
...opt,
label: t(`${opt?.label}`),

View File

@ -40,9 +40,14 @@ export type SearchFieldProps = BaseFieldProps &
type DateFieldProps = BaseFieldProps & {
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";
showTime?:boolean
showTime?: boolean;
};
type FileFieldProps = BaseFieldProps & {

View File

@ -12,22 +12,28 @@ import { LocalStorageEnum } from "../../enums/LocalStorageEnum";
const Header = () => {
const [t] = useTranslation();
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 isEdited = () => {
if (isBseQuestion || values?.isBase === 1) {
const content = !values?.content;
const content_image = !values?.content_image;
const Questions = values?.Questions?.length <= 1 && values?.Questions?.[0]?.answers?.length === 0 ;
const defaultQuestionHint = Object.keys(values?.Questions?.[0] ?? {})?.length <= 1
const Questions =
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) {
return false
return false;
}
} else {
const content = !values?.content;
@ -36,11 +42,11 @@ const Header = () => {
const answers = !(values?.answers?.length > 0);
const tags = !(values?.tags?.length > 0);
if (content && content_image && hint && answers && tags) {
return false
return false;
}
}
return true
}
return true;
};
const handleChange = () => {
if (isBseQuestion) {
@ -52,11 +58,10 @@ const Header = () => {
}
};
const confirm: PopconfirmProps['onConfirm'] = (e) => {
const confirm: PopconfirmProps["onConfirm"] = (e) => {
setTimeout(() => {
handleChange();
}, 500);
};
const content = (
@ -73,21 +78,24 @@ const Header = () => {
</div>
);
const onChangeHint: CheckboxProps['onChange'] = (e) => {
const onChangeHint: CheckboxProps["onChange"] = (e) => {
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);
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
localStorage?.setItem(
LocalStorageEnum.LATEX_OPTION_INPUT,
e.target.checked ? "true" : "false",
);
};
const contentSetting = (
<div>
<Checkbox checked={ShowHint} onChange={onChangeHint}>
{t("header.show_hint")}
</Checkbox>
@ -95,11 +103,9 @@ const Header = () => {
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
{t("header.show_MMl")}
</Checkbox>
</div>
);
return (
<header className="exercise_add_header mb-4">
<article>
@ -112,48 +118,35 @@ const Header = () => {
</div>
</article>
<div>
<div className="question_header_setting">
<Popover trigger="click" content={contentSetting}>
<SettingFilled />
</Popover>
</div>
{
isEdited() ?
{isEdited() ? (
<Popconfirm
title={t("header.this_will_un_do_all_your_changes")}
okText={t("practical.yes")}
cancelText={t("practical.no")}
onConfirm={()=>{confirm()}}
onConfirm={() => {
confirm();
}}
defaultOpen={false}
>
<GoArrowSwitch className="m-2" />
{isBseQuestion || values?.isBase === 1
? t("header.malty_exercise")
: t("header.exercise")}
</Popconfirm>
:
) : (
<>
<GoArrowSwitch onClick={() => confirm()} className="m-2" />
{isBseQuestion || values?.isBase === 1
? t("header.malty_exercise")
: t("header.exercise")}
</>
}
)}
</div>
</header>
);

View File

@ -28,7 +28,7 @@ const useFormField = (name: string, props?: any) => {
const errorMsg =
!!isError && meta.error
? t(meta.error.toString())
: Validation[name as any] ?? "";
: (Validation[name as any] ?? "");
return { Field, field, meta, formik, isError, errorMsg, t };
};

View File

@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
const [t] = useTranslation();
@ -10,7 +10,7 @@ const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
// Prevent default action and stop the event
event.preventDefault();
// 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)
document.querySelectorAll('a').forEach(link => {
link.addEventListener('click', handleNavigation);
document.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", handleNavigation);
});
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
window.removeEventListener("beforeunload", handleBeforeUnload);
// Clean up event listeners
document.querySelectorAll('a').forEach(link => {
link.removeEventListener('click', handleNavigation);
document.querySelectorAll("a").forEach((link) => {
link.removeEventListener("click", handleNavigation);
});
};
}, [unsavedChanges, t]);

View File

@ -1,13 +1,13 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useState } from "react";
export const useWindowResize = () => {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
window.addEventListener('resize', handleResize);
window.addEventListener("resize", handleResize);
// Cleanup function to remove the event listener
return () => {
window.removeEventListener('resize', handleResize);
window.removeEventListener("resize", handleResize);
};
}, [windowWidth]);
@ -16,5 +16,4 @@ export const useWindowResize = () => {
};
return { windowWidth, handleResize };
}
};

View File

@ -18,7 +18,7 @@ const FilterLayout = ({
width = "500px",
haveFilter = true,
haveOrder = true,
haveSearch = true
haveSearch = true,
}: {
filterTitle: string;
sub_children?: any;
@ -26,7 +26,7 @@ const FilterLayout = ({
width?: string;
haveFilter?: boolean;
haveOrder?: boolean;
haveSearch?:boolean
haveSearch?: boolean;
}) => {
const { t } = useTranslation();
const translateArray = translateOptions(search_array, t);
@ -49,8 +49,7 @@ const FilterLayout = ({
<div className="model_sub_children">{sub_children}</div>
<FilterSubmit />
</FilterBody>
{haveFilter &&
{haveFilter && (
<div className="filter_button" onClick={() => setIsOpen(true)}>
<span>
<BiFilterAlt className="addition_select_icon" />
@ -58,12 +57,10 @@ const FilterLayout = ({
</span>
<MdKeyboardArrowDown />
</div>
}
)}
</span>
<span>
{haveOrder && <OrderBySelect />}
</span>
<span>{haveOrder && <OrderBySelect />}</span>
</div>
</div>
@ -77,7 +74,12 @@ const FilterLayout = ({
</span>
<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>

View File

@ -29,7 +29,6 @@ const FormikFormModel: React.FC<FormikFormProps> = ({
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(formik) => {
useEffect(() => {

View File

@ -22,7 +22,7 @@ interface LayoutModalProps {
width?: string;
isLoading?: boolean;
buttonTitle?: string;
initialButtonName?:boolean
initialButtonName?: boolean;
}
const LayoutModel = ({
@ -70,7 +70,6 @@ const LayoutModel = ({
open={isOpen === ModelEnum}
onCancel={handleCancel}
>
<Formik
enableReinitialize={true}
initialValues={getInitialValues}
@ -85,8 +84,8 @@ const LayoutModel = ({
}
}, [isOpen]);
return <Form className="w-100">
return (
<Form className="w-100">
<header>
<span>
{t(`practical.${isAddModal ? "add" : "edit"}`)}{" "}
@ -100,18 +99,22 @@ const LayoutModel = ({
<Divider />
<div className="buttons">
<Button className="back_button pointer" onClick={handleCancel}>
<Button
className="back_button pointer"
onClick={handleCancel}
>
{t("practical.cancel")}
</Button>
<Button
className="add_button"
disabled={status === QueryStatusEnum.LOADING || !formik.dirty}
disabled={
status === QueryStatusEnum.LOADING || !formik.dirty
}
htmlType="submit"
>
{
initialButtonName ? t(`practical.${isAddModal ? "add" : "edit"}`)
: t(`practical.${buttonTitle}`)
}
{initialButtonName
? t(`practical.${isAddModal ? "add" : "edit"}`)
: t(`practical.${buttonTitle}`)}
{status === QueryStatusEnum.LOADING && (
<span className="Spinier_Div">
<Spin />
@ -120,8 +123,8 @@ const LayoutModel = ({
</Button>
</div>
</main>
</Form>;
</Form>
);
}}
</Formik>
</Modal>

View File

@ -1,4 +1,3 @@
import { BsPlusCircleFill } from "react-icons/bs";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
@ -14,7 +13,8 @@ const PageHeader = ({
pageTitle,
openModel = true,
locationToNavigate,
addModal = true
addModal = true,
modelButtonTitle = "add",
}: {
canAdd?: any;
ModelAbility?: any;
@ -22,6 +22,7 @@ const PageHeader = ({
openModel?: boolean;
locationToNavigate?: string | any;
addModal?: boolean;
modelButtonTitle?: string;
}) => {
const navigate = useNavigate();
const { handel_open_model } = useModalHandler();
@ -31,9 +32,8 @@ const PageHeader = ({
const { setFilter } = useFilterStateState();
const handleNavigateToPage = (location: string) => {
setFilter({})
setFilter({});
navigate(location);
};
console.log();
@ -46,7 +46,8 @@ const PageHeader = ({
<PageTitleComponent />
</span>
</span>
{ addModal ? canAdd && (
{addModal
? canAdd && (
<div className="Selects">
<button
onClick={() =>
@ -57,10 +58,11 @@ const PageHeader = ({
className="add_button"
>
<BsPlusCircleFill />
{t(`practical.add`)}
{t(`practical.${modelButtonTitle}`)}
</button>
</div>
) :""}
)
: ""}
</header>
</div>
);

View File

@ -1,36 +1,38 @@
import React from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import { usePageTitleState } from '../../zustand/PageTitleState'
import { useFilterStateState } from '../../zustand/Filter'
import React from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { usePageTitleState } from "../../zustand/PageTitleState";
import { useFilterStateState } from "../../zustand/Filter";
const PageTitleComponent = () => {
const {PageTitle} = usePageTitleState()
const navigate = useNavigate()
const location = useLocation()
const { PageTitle } = usePageTitleState();
const navigate = useNavigate();
const location = useLocation();
const { setFilter } = useFilterStateState();
const handleNavigate = (path: string) => {
const currentPath = location.pathname;
const newPath = currentPath?.split(path)?.[0] + path;
if (newPath !== currentPath) {
setFilter({})
navigate(newPath)
}
setFilter({});
navigate(newPath);
}
};
return (
<div className='PageTitle'>
<div className="PageTitle">
{(Array.isArray(PageTitle) ? PageTitle : [])?.map((item, index) => {
const lastItem = PageTitle?.length - 1 === index
const lastItem = PageTitle?.length - 1 === index;
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 ? "" : "/"}
</div>
)
);
})}
</div>
)
}
);
};
export default PageTitleComponent
export default PageTitleComponent;

View File

@ -21,7 +21,6 @@ const QrCodeModels: React.FC<ModalFormProps> = ({
const { objectToEdit, setObjectToEdit } = useObjectToEdit();
const handleCancel = () => {
setIsOpen("");
setObjectToEdit({});

View File

@ -25,10 +25,10 @@ const DataTable: React.FC<DataTableProps> = ({
const isRefetching = response?.isRefetching;
const isLoading = response?.isLoading;
const dataLength = data?.length;
const {setDataTableLength} = useDataTableState()
const { setDataTableLength } = useDataTableState();
useEffect(() => {
setDataTableLength(dataLength)
}, [dataLength])
setDataTableLength(dataLength);
}, [dataLength]);
return (
<Table
@ -63,10 +63,8 @@ const DataTable: React.FC<DataTableProps> = ({
nextIcon: <>{t("practical.next")}</>,
prevIcon: <> {t("practical.prev")} </>,
className: "pagination_antd",
showSizeChanger:false
showSizeChanger: false,
}}
{...props}
/>
);

View File

@ -13,7 +13,6 @@ const usePagination = (data: Data) => {
current: data?.meta?.current_page || 1,
pageSize: data?.meta?.per_page || 2,
total: data?.meta?.total || 0,
});
useEffect(() => {
@ -21,15 +20,14 @@ const usePagination = (data: Data) => {
current: data?.meta?.current_page || 1,
pageSize: data?.meta?.per_page || 2,
total: data?.meta?.total || 0,
});
}, [data]);
const handlePageChange = (page: number) => {
setFilter({
...Filter,
page:page
})
page: page,
});
};
return { pagination, handlePageChange };

View File

@ -11,7 +11,6 @@ const Layout = ({
children: React.ReactNode;
className?: string;
}) => {
const { openSideBar, setOpenSideBar } = useSideBarState();
return (

View File

@ -10,17 +10,22 @@ function NotFoundPage() {
return (
<ProtectedRouteProvider className="not_found_page">
<div className="not_found_container">
<img src="/App/Error.png" alt="Error 404" width={500} />
<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>
<Button className="not_found_button" onClick={() => navigate("/", { replace: true })}>
<p>
{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 />
{t("practical.return_to_the_dashboard")}
</Button>
</div>
</ProtectedRouteProvider>
);
}

View File

@ -10,11 +10,11 @@ import { ParamsEnum } from "../../../../enums/params";
const AddModel: React.FC = () => {
const { mutate, status } = useAddArea();
const {city_id} = useParams<ParamsEnum>()
const { city_id } = useParams<ParamsEnum>();
const handleSubmit = (values: any) => {
mutate({
...values,
city_id
city_id,
});
};
return (

View File

@ -12,7 +12,7 @@ import { ParamsEnum } from "../../../../enums/params";
const EditModel: React.FC = () => {
const { mutate, status } = useUpdateArea();
const { objectToEdit } = useObjectToEdit((state) => state);
const {city_id} = useParams<ParamsEnum>()
const { city_id } = useParams<ParamsEnum>();
const handleSubmit = (values: any) => {
const Data_to_send = { ...values, city_id };
mutate(Data_to_send);

View File

@ -7,7 +7,6 @@ const Form = () => {
<Col>
<ValidationField name="name" placeholder="name" label="name" />
</Col>
</Row>
);
};

View File

@ -21,7 +21,7 @@ const DeleteModalForm = lazy(
const TableHeader = () => {
const [t] = useTranslation();
const deleteMutation = useDeleteArea();
const {city_id} = useParams<ParamsEnum>()
const { city_id } = useParams<ParamsEnum>();
useSetPageTitle([
{ name: `${t(`page_header.home`)}`, path: "/" },
{ name: `${t(`page_header.Area`)}`, path: `city/${city_id}` },
@ -35,7 +35,11 @@ const TableHeader = () => {
ModelAbility={ModalEnum?.AREA_ADD}
canAdd={canAddArea}
/>
<FilterLayout sub_children={<FilterForm />} filterTitle="table.Area" haveFilter={false} />
<FilterLayout
sub_children={<FilterForm />}
filterTitle="table.Area"
haveFilter={false}
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -10,7 +10,7 @@ import { ParamsEnum } from "../../../enums/params";
const App: React.FC = () => {
const { filterState } = useFilterState();
const { Filter } = useFilterStateState();
const {city_id} = useParams<ParamsEnum>()
const { city_id } = useParams<ParamsEnum>();
const name = Filter?.name;
const sort_by = Filter?.sort_by;
const response = useGetAllArea({
@ -18,7 +18,7 @@ const App: React.FC = () => {
...filterState,
city_id,
name,
sort_by
sort_by,
});
return <DataTable response={response} useColumns={useColumns} />;

View File

@ -21,10 +21,8 @@ export const useColumns = () => {
const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handelShow = (record: Area) => {
setFilter({})
setFilter({});
navigate(`${record?.id}`);
};
@ -53,7 +51,7 @@ export const useColumns = () => {
key: "name",
align: "center",
render: (_text, record) => record?.name,
ellipsis:true
ellipsis: true,
},
{
title: t("columns.procedure"),

View File

@ -7,7 +7,6 @@ const Form = () => {
<Col>
<ValidationField name="name" placeholder="name" label="name" />
</Col>
</Row>
);
};

View File

@ -22,7 +22,7 @@ const TableHeader = () => {
useSetPageTitle([
{ name: `${t(`page_header.home`)}`, path: "/" },
{name:`${t(`page_header.City`)}`, path:"City"}
{ name: `${t(`page_header.City`)}`, path: "City" },
]);
return (
@ -33,7 +33,11 @@ const TableHeader = () => {
ModelAbility={ModalEnum?.CITY_ADD}
canAdd={canAddCity}
/>
<FilterLayout sub_children={<FilterForm />} haveFilter={false} filterTitle="table.City" />
<FilterLayout
sub_children={<FilterForm />}
haveFilter={false}
filterTitle="table.City"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -14,7 +14,7 @@ const App: React.FC = () => {
pagination: true,
...filterState,
name,
sort_by
sort_by,
});
return <DataTable response={response} useColumns={useColumns} />;

View File

@ -21,10 +21,8 @@ export const useColumns = () => {
const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handelShow = (record: City) => {
setFilter({})
setFilter({});
navigate(`${record?.id}`);
};
@ -53,10 +51,9 @@ export const useColumns = () => {
key: "name",
align: "center",
render: (_text, record) => record?.name,
ellipsis:true
ellipsis: true,
},
{
title: t("columns.procedure"),
key: "actions",
align: "center",

View File

@ -13,14 +13,12 @@ const AddModel: React.FC = () => {
const handleSubmit = (values: any) => {
console.log(values?.due_to, "values?.due_to");
const due_to = values?.due_to.format("YYYY-MM-DD HH:mm:ss")
const due_to = values?.due_to.format("YYYY-MM-DD HH:mm:ss");
console.log(due_to);
mutate({
...values,
due_to,
grade_id:values?.grade_id?.id
grade_id: values?.grade_id?.id,
});
};
return (

View File

@ -12,8 +12,15 @@ const EditModel: React.FC = () => {
const { objectToEdit } = useObjectToEdit((state) => state);
const handleSubmit = (values: any) => {
const due_to = typeof values?.due_to === "string" ? values?.due_to : values?.due_to.format("YYYY-MM-DD HH:mm:ss")
const Data_to_send = { ...values , due_to, grade_id:values?.grade_id?.id ?? "" };
const due_to =
typeof values?.due_to === "string"
? values?.due_to
: values?.due_to.format("YYYY-MM-DD HH:mm:ss");
const Data_to_send = {
...values,
due_to,
grade_id: values?.grade_id?.id ?? "",
};
mutate(Data_to_send);
};

View File

@ -6,40 +6,40 @@ import { useGetAllGrade } from "../../../../api/grade";
const Form = ({ Hide = false }: { Hide?: boolean }) => {
const { ValidationParamState } = useValidationValidationParamState();
const {
GradeName, GradeCurrentPage,
} = ValidationParamState;
const { GradeName, GradeCurrentPage } = ValidationParamState;
const { data: Grade, isLoading: isLoadingGrade } = useGetAllGrade({
name: GradeName,
page: GradeCurrentPage
page: GradeCurrentPage,
});
const GradeOption = Grade?.data ?? []
const GradeOption = Grade?.data ?? [];
const canChangeGradePage = !!Grade?.links?.next;
const GradePage = Grade?.meta?.current_page;
return (
<Row className="w-100">
<Col>
<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>
<ValidationField
name="due_to" type="Date"
name="due_to"
type="Date"
Format="YYYY-MM-DD HH:mm:ss"
placeholder="due_to" label="due_to"
placeholder="due_to"
label="due_to"
showTime
/>
<ValidationField name="code" placeholder="code" label="code" />
{/*
grade_id
*/}
{!Hide &&
{!Hide && (
<ValidationField
searchBy="GradeName"
name="grade_id"
@ -51,9 +51,8 @@ const Form = ({Hide = false}:{Hide?:boolean }) => {
canChangePage={canChangeGradePage}
PageName={"GradeCurrentPage"}
page={GradePage}
/>
}
)}
</Col>
</Row>
);

View File

@ -10,7 +10,9 @@ export const getInitialValues = (
name: objectToEdit?.name ?? "",
amount: objectToEdit?.amount ?? "",
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 ?? "",
};
};
@ -20,8 +22,12 @@ export const getValidationSchema = () => {
return Yup.object().shape({
name: Yup.string().required("validation.required"),
due_to: Yup.string().required("validation.required"),
code: Yup.string().required("validation.required").min(6,"validation.must_be_at_least_6_characters_long").max(6,"validation.must_be_at_least_6_characters_long"),
amount: Yup.number().required("validation.required").typeError("validation.Must_be_a_number"),
code: Yup.string()
.required("validation.required")
.min(6, "validation.must_be_at_least_6_characters_long")
.max(6, "validation.must_be_at_least_6_characters_long"),
amount: Yup.number()
.required("validation.required")
.typeError("validation.Must_be_a_number"),
});
};

View File

@ -22,7 +22,7 @@ const TableHeader = () => {
useSetPageTitle([
{ name: `${t(`page_header.home`)}`, path: "/" },
{name:`${t(`page_header.Coupon`)}`, path:"Coupon"}
{ name: `${t(`page_header.Coupon`)}`, path: "Coupon" },
]);
return (
@ -33,7 +33,11 @@ const TableHeader = () => {
ModelAbility={ModalEnum?.COUPON_ADD}
canAdd={canAddCoupon}
/>
<FilterLayout sub_children={<FilterForm />} haveFilter={false} filterTitle="table.Coupon" />
<FilterLayout
sub_children={<FilterForm />}
haveFilter={false}
filterTitle="table.Coupon"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -14,7 +14,7 @@ const App: React.FC = () => {
pagination: true,
...filterState,
name,
sort_by
sort_by,
});
return <DataTable response={response} useColumns={useColumns} />;

View File

@ -21,10 +21,8 @@ export const useColumns = () => {
const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handelShow = (record: Coupon) => {
setFilter({})
setFilter({});
navigate(`${record?.id}`);
};
@ -53,7 +51,7 @@ export const useColumns = () => {
key: "name",
align: "center",
render: (_text, record) => record?.name,
ellipsis:true
ellipsis: true,
},
{
title: `${t("columns.amount")}`,
@ -61,7 +59,7 @@ export const useColumns = () => {
key: "amount",
align: "center",
render: (_text, record) => record?.amount,
ellipsis:true
ellipsis: true,
},
{
title: `${t("columns.code")}`,
@ -69,7 +67,7 @@ export const useColumns = () => {
key: "code",
align: "center",
render: (_text, record) => record?.code,
ellipsis:true
ellipsis: true,
},
{
title: `${t("columns.due_to")}`,
@ -85,10 +83,9 @@ export const useColumns = () => {
key: "status",
align: "center",
render: (_text, record) => record?.status,
ellipsis:true
ellipsis: true,
},
{
title: t("columns.procedure"),
key: "actions",
align: "center",

View File

@ -17,7 +17,7 @@ const AddModel: React.FC = () => {
mutate({
...values,
date: dayjs(values?.date).format('YYYY-MM-DD'),
date: dayjs(values?.date).format("YYYY-MM-DD"),
});
};
return (

View File

@ -1,5 +1,9 @@
import React from "react";
import { getInitialValues, getValidationSchema, getValidationSchemaEdit } from "./formUtil";
import {
getInitialValues,
getValidationSchema,
getValidationSchemaEdit,
} from "./formUtil";
import { ModalEnum } from "../../../../enums/Model";
import LayoutModel from "../../../../Layout/Dashboard/LayoutModel";
import ModelForm from "./ModelForm";
@ -17,7 +21,7 @@ const EditModel: React.FC = () => {
const handleSubmit = (values: any) => {
mutate({
...values,
date: dayjs(values?.date).format('YYYY-MM-DD'),
date: dayjs(values?.date).format("YYYY-MM-DD"),
});
};
return (

View File

@ -4,13 +4,17 @@ import { Col, Row } from "reactstrap";
import { useGetAllReseller } from "../../../../api/reseller";
const FilterForm = () => {
const {data} = useGetAllReseller()
const { data } = useGetAllReseller();
return (
<div>
<Row>
<Col>
<ValidationField placeholder="description" label="description" name="description" />
<ValidationField
placeholder="description"
label="description"
name="description"
/>
<ValidationField placeholder="amount" label="amount" name="amount" />
<ValidationField
placeholder="reseller"
@ -19,11 +23,11 @@ const FilterForm = () => {
type="Select"
option={data?.data?.map((e: any) => ({
...e,
fullName: `${e.first_name} ${e.last_name}`
fullName: `${e.first_name} ${e.last_name}`,
}))}
fieldNames={{
label: "fullName",
value: "id"
value: "id",
}}
/>
</Col>

View File

@ -3,17 +3,28 @@ import ValidationField from "../../../../Components/ValidationField/ValidationFi
import { useGetAllReseller } from "../../../../api/reseller";
const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
const {data} = useGetAllReseller()
const { data } = useGetAllReseller();
return (
<Row className="w-100">
<Col>
<ValidationField placeholder="description" label="description" name="description" />
<ValidationField
placeholder="description"
label="description"
name="description"
/>
<ValidationField placeholder="amount" label="amount" name="amount" />
</Col>
<Col>
<ValidationField placeholder="date" label="date" name="date" type="Date"/>
{isEdit ? " " :
<ValidationField
placeholder="date"
label="date"
name="date"
type="Date"
/>
{isEdit ? (
" "
) : (
<ValidationField
placeholder="reseller"
label="reseller"
@ -21,15 +32,14 @@ const Form = ({isEdit= false}:{isEdit?:boolean}) => {
type="Select"
option={data?.data?.map((e: any) => ({
...e,
fullName: `${e.first_name} ${e.last_name}`
fullName: `${e.first_name} ${e.last_name}`,
}))}
fieldNames={{
label: "fullName",
value: "id"
value: "id",
}}
/>
}
)}
</Col>
</Row>
);

View File

@ -4,7 +4,10 @@ import { ModalEnum } from "../../../enums/Model";
import { useTranslation } from "react-i18next";
import { lazy, Suspense } from "react";
import { Spin } from "antd";
import { canAddFinancial_Collection, canAddTags } from "../../../utils/hasAbilityFn";
import {
canAddFinancial_Collection,
canAddTags,
} from "../../../utils/hasAbilityFn";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { useDeleteTag } from "../../../api/tags";
import PageHeader from "../../../Layout/Dashboard/PageHeader";
@ -23,7 +26,10 @@ const TableHeader = () => {
useSetPageTitle([
{ 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();

View File

@ -5,7 +5,6 @@ import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
import { useFilterStateState } from "../../../zustand/Filter";
import { useGetAllFinancialCollection } from "../../../api/financial_collection";
const App: React.FC = () => {
const { filterState } = useFilterState();
const { Filter } = useFilterStateState();
const name = Filter?.name;

View File

@ -4,7 +4,12 @@ import { ModalEnum } from "../../../enums/Model";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { useModalState } from "../../../zustand/Modal";
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";
export const useColumns = () => {
@ -34,21 +39,21 @@ export const useColumns = () => {
dataIndex: "amount",
key: "amount",
align: "center",
ellipsis:true
ellipsis: true,
},
{
title: t("columns.date"),
dataIndex: "date",
key: "date",
align: "center",
ellipsis:true
ellipsis: true,
},
{
title: t("columns.description"),
dataIndex: "description",
key: "description",
align: "center",
ellipsis:true
ellipsis: true,
},
{
title: t("columns.procedure"),

View File

@ -22,7 +22,7 @@ const TableHeader = () => {
useSetPageTitle([
{ name: `${t(`page_header.home`)}`, path: "/" },
{name:`${t(`page_header.grade`)}`, path:"grade"}
{ name: `${t(`page_header.grade`)}`, path: "grade" },
]);
return (

View File

@ -15,7 +15,7 @@ const App: React.FC = () => {
pagination: true,
...filterState,
name: filterState.name || name,
sort_by
sort_by,
});
return <DataTable response={response} useColumns={useColumns} />;

View File

@ -21,10 +21,8 @@ export const useColumns = () => {
const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handelShow = (record: Grade) => {
setFilter({})
setFilter({});
navigate(`${record?.id}`);
};
@ -53,7 +51,7 @@ export const useColumns = () => {
key: "name",
align: "center",
render: (_text, record) => record?.name,
ellipsis:true
ellipsis: true,
},
{
title: t("columns.image"),
@ -67,7 +65,6 @@ export const useColumns = () => {
},
},
{
title: t("columns.procedure"),
key: "actions",
align: "center",

View File

@ -29,7 +29,7 @@ const TableHeader = () => {
if (status === QueryStatusEnum.SUCCESS) {
handleCancel();
}
}, [status])
}, [status]);
return (
<div className="TableWithHeader">
@ -50,7 +50,9 @@ const TableHeader = () => {
<TitleDetailsForm />
<AttachmentForm />
<div className="resellerButton">
<button type="button" onClick={handleCancel}>{t("practical.cancel")}</button>
<button type="button" onClick={handleCancel}>
{t("practical.cancel")}
</button>
<button type="submit">
{t("practical.add")} {t("models.reseller")}
{status === QueryStatusEnum.LOADING && (

View File

@ -30,7 +30,7 @@ const TableHeader = () => {
if (status === QueryStatusEnum.SUCCESS) {
handleCancel();
}
}, [status])
}, [status]);
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
@ -51,7 +51,9 @@ const TableHeader = () => {
<PasswordDetailsForm />
<AttachmentForm />
<div className="resellerButton">
<button type="button" onClick={handleCancel}>{t("practical.cancel")}</button>
<button type="button" onClick={handleCancel}>
{t("practical.cancel")}
</button>
<button type="submit">
{t("practical.add")} {t("models.reseller")}
{status === QueryStatusEnum.LOADING && (

View File

@ -12,9 +12,16 @@ const PasswordDetailsForm = () => {
<h4>{t("header.password")}</h4>
</header>
<main className="main_form_body">
<ValidationField name={"password"} placeholder={"_"} label={"new_password"} />
<ValidationField name={"password"} placeholder={"_"} label={"submit_password"} />
<ValidationField
name={"password"}
placeholder={"_"}
label={"new_password"}
/>
<ValidationField
name={"password"}
placeholder={"_"}
label={"submit_password"}
/>
</main>
</div>
);

View File

@ -10,7 +10,7 @@ import { useGetRole } from "../../../../api/role";
const PersonalDetailsForm = ({ isEdit = false }: { isEdit?: boolean }) => {
const [t] = useTranslation();
const { data } = useGetRole();
const RoleData = data?.data
const RoleData = data?.data;
const sex = [
{ name: "male", id: "male" },
@ -28,11 +28,7 @@ const PersonalDetailsForm = ({isEdit= false}:{isEdit?:boolean}) => {
placeholder={"_"}
label={"username"}
/>
<ValidationField
name={"name"}
placeholder={"_"}
label={"name"}
/>
<ValidationField name={"name"} placeholder={"_"} label={"name"} />
<ValidationField
name={"contact_number"}
placeholder={"_"}

View File

@ -9,11 +9,11 @@ import { useGetAllCity } from "../../../../api/City";
const TitleDetailsForm = () => {
const [t] = useTranslation();
const { data: city } = useGetAllCity();
const [CityId, setCityId] = useState()
const [CityId, setCityId] = useState();
console.log(city);
const { data } = useGetAllArea({
city_id:CityId
city_id: CityId,
});
return (
@ -38,7 +38,6 @@ const TitleDetailsForm = () => {
type="Select"
disabled={!CityId}
option={data?.data}
/>
{/* <ValidationField name={"address"} placeholder={"_"} label={"address"} /> */}
</main>

View File

@ -10,7 +10,6 @@ export const getInitialValues = (objectToEdit: Partial<any>) => {
contact_number: objectToEdit?.contact_number ?? null,
role_id: objectToEdit?.role_id ?? null,
password: objectToEdit?.password ?? null,
};
};

View File

@ -12,7 +12,7 @@ const AddModel: React.FC = () => {
const handleSubmit = (values: any) => {
mutate({
...values,
grade_id:values?.grade_id?.id
grade_id: values?.grade_id?.id,
});
};
return (

View File

@ -13,7 +13,6 @@ const App: React.FC = () => {
const name = Filter?.name;
const sort_by = Filter?.sort_by;
const response = useGetAllManager({
name,
sort_by,
@ -21,7 +20,6 @@ const App: React.FC = () => {
...filterState,
});
return <DataTable response={response} useColumns={useColumns} />;
};

View File

@ -34,8 +34,7 @@ export const useColumns = () => {
const handleEdit = (record: Manager) => {
setObjectToEdit(record);
navigate(`/${ABILITIES_ENUM?.MANAGERS}/${record?.id}/edit`)
navigate(`/${ABILITIES_ENUM?.MANAGERS}/${record?.id}/edit`);
};
const [t] = useTranslation();

View 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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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