This commit is contained in:
karimaldeen 2024-09-10 10:20:21 +03:00
parent 1a78474120
commit 398d1e8f07
139 changed files with 10033 additions and 4638 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,37 @@
.ImageBoxField{
.ImageBox{
width: 120px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
border: max(1.5px,.1vw) dashed #a9c3f1;
margin-block: 10px;
border-radius: 5px;
.ImageBoxIcon{
cursor: pointer;
}
.imagePreview{
max-width: 99%;
height: auto;
max-height: 99%;
object-fit: contain;
border-radius: 5px;
}
.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;
.ImageBoxIcon {
cursor: pointer;
}
.ImageHeader{
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
.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;
}
}
.ImageCancelIcon {
width: 16px !important;
height: 16px !important;
}
.ImageBoxIcon {
width: 20px !important;
height: 20px !important;
}
}

View File

@ -1,6 +1,6 @@
import { useFormikContext } from "formik";
import { useState, useRef, useEffect } from "react";
import './ImageBoxField.scss';
import "./ImageBoxField.scss";
import ImageIcon from "./ImageIcon";
import ImageCancelIcon from "./ImageCancelIcon";
import { getNestedValue } from "../../../utils/getNestedValue";
@ -8,21 +8,20 @@ import { generateImagePreview } from "./generateImagePreview";
// 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);
console.log(formik.values);
console.log(value,name);
console.log(formik.values);
console.log(value, name);
useEffect(() => {
if (value instanceof File) {
generateImagePreview(value, setImagePreview);
} else if (typeof value === 'string') {
setImagePreview(value);
generateImagePreview(value, setImagePreview);
} else if (typeof value === "string") {
setImagePreview(value);
} else {
setImagePreview(null);
}
@ -31,7 +30,7 @@ const ImageBoxField = ({ name }: any) => {
const handleFileChange = (event: any) => {
const file = event.target.files[0];
if (file) {
generateImagePreview(file, setImagePreview);
generateImagePreview(file, setImagePreview);
formik.setFieldValue(name, file);
}
};
@ -46,7 +45,7 @@ const ImageBoxField = ({ name }: any) => {
const handleCancel = () => {
setImagePreview("");
formik.setFieldValue(name, "");
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
@ -57,13 +56,14 @@ const ImageBoxField = ({ name }: any) => {
<div className="ImageHeader">
{imagePreview ? (
<>
<ImageCancelIcon onClick={handleCancel} className="ImageCancelIcon" />
<ImageCancelIcon
onClick={handleCancel}
className="ImageCancelIcon"
/>
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
</>
) : (
<div className="VisibleHidden">
hidden
</div>
<div className="VisibleHidden">hidden</div>
)}
</div>
<div className="ImageBox">

View File

@ -1,27 +1,18 @@
import React from 'react';
import React from "react";
interface ImageCancelIconProps extends React.HTMLAttributes<HTMLDivElement> {
}
interface ImageCancelIconProps extends React.HTMLAttributes<HTMLDivElement> {}
const ImageCancelIcon: React.FC<ImageCancelIconProps> = (props) => {
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>
);
}
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

@ -1,27 +1,18 @@
import React from 'react';
import React from "react";
interface ImageIconProps extends React.HTMLAttributes<HTMLDivElement> {
}
interface ImageIconProps extends React.HTMLAttributes<HTMLDivElement> {}
const ImageIcon: React.FC<ImageIconProps> = (props) => {
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>
);
}
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;

View File

@ -1,7 +1,10 @@
export const generateImagePreview = (file: File, setImagePreview: (result: string) => void) => {
const reader = new FileReader();
reader.onloadend = () => {
setImagePreview(reader.result as string);
};
reader.readAsDataURL(file);
};
export const generateImagePreview = (
file: File,
setImagePreview: (result: string) => void,
) => {
const reader = new FileReader();
reader.onloadend = () => {
setImagePreview(reader.result as string);
};
reader.readAsDataURL(file);
};

View File

@ -1,36 +1,33 @@
import React, { useState, useMemo } from 'react';
import { Select, Spin } from 'antd';
import { useTranslation } from 'react-i18next';
import { useDebounce } from '../../utils/useDebounce';
import { useGetAllTag } from '../../api/tags';
import { useFormikContext } from 'formik';
import React, { useState, useMemo } from "react";
import { Select, Spin } from "antd";
import { useTranslation } from "react-i18next";
import { useDebounce } from "../../utils/useDebounce";
import { useGetAllTag } from "../../api/tags";
import { useFormikContext } from "formik";
const SelectTag: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>('');
const [fieldValue, setFieldValue] = useState<string>('');
const formik = useFormikContext<any>()
const [searchValue, setSearchValue] = useState<string>("");
const [fieldValue, setFieldValue] = useState<string>("");
const formik = useFormikContext<any>();
const handleChange = (value: string[]) => {
console.log(value);
formik.setFieldValue("tags",value)
setSearchValue('');
setFieldValue('');
formik.setFieldValue("tags", value);
setSearchValue("");
setFieldValue("");
};
const handleSearch = useDebounce((value: string) => {
setSearchValue(value);
});
const handleFieldChange = (value: string) => {
setFieldValue(value);
};
const handleBlur = () => {
setSearchValue('');
setFieldValue('');
setSearchValue("");
setFieldValue("");
};
const { data, isLoading } = useGetAllTag({
@ -39,38 +36,38 @@ const SelectTag: React.FC = () => {
const [t] = useTranslation();
const options = data?.data ?? []
const additionalData = options?.length < 1 && searchValue.length > 1 && !isLoading ? [{id:`${searchValue}`,name:searchValue}] :[];
const options = data?.data ?? [];
const additionalData =
options?.length < 1 && searchValue.length > 1 && !isLoading
? [{ id: `${searchValue}`, name: searchValue }]
: [];
return (
<div className='SelectTag'>
<label htmlFor="">
{t("models.tag")}
</label>
<Select
mode="multiple"
allowClear
style={{ width: '100%' ,height:"40px"}}
placeholder=""
fieldNames={{ label: 'name', value: 'id' }}
onChange={handleChange}
options={[...options,...additionalData]}
filterOption={false}
loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
onSearch={(value) => {
handleSearch(value);
handleFieldChange(value);
}}
searchValue={fieldValue}
onDropdownVisibleChange={(open) => {
if (!open) {
handleBlur();
}
}}
value={formik?.values?.tags ?? []}
/>
<div className="SelectTag">
<label htmlFor="">{t("models.tag")}</label>
<Select
mode="multiple"
allowClear
style={{ width: "100%", height: "40px" }}
placeholder=""
fieldNames={{ label: "name", value: "id" }}
onChange={handleChange}
options={[...options, ...additionalData]}
filterOption={false}
loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
onSearch={(value) => {
handleSearch(value);
handleFieldChange(value);
}}
searchValue={fieldValue}
onDropdownVisibleChange={(open) => {
if (!open) {
handleBlur();
}
}}
value={formik?.values?.tags ?? []}
/>
</div>
);
};

View File

@ -11,14 +11,14 @@ interface Props {
options: Option[];
placeholder: string;
onSelect?: (option: Option) => void;
withIcon?:boolean
withIcon?: boolean;
}
const SearchFieldWithSelect: React.FC<Props> = ({
options,
placeholder,
onSelect,
withIcon=false
withIcon = false,
}) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState<Option | null>(null);
@ -60,8 +60,8 @@ const SearchFieldWithSelect: React.FC<Props> = ({
return (
<div ref={node} className={`search-field ${isOpen ? "open" : ""}`}>
<div className="search-header" onClick={toggleDropdown}>
{withIcon && <IoSearch className="search__icon" />}
{withIcon && <IoSearch className="search__icon" />}
{/* <p className="search__input_text">{placeholder}</p> */}
<input
type="text"

View File

@ -1,54 +1,58 @@
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Divider, Select } from 'antd';
import SearchFieldWithSelect from '../../Components/DataTable/SearchFieldWithSelect';
import { translateOptions } from '../../utils/translatedOptions';
import { search_array } from '../../Routes';
import { useFilterStateState } from '../../zustand/Filter';
import { useSearchParams } from 'react-router-dom';
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Divider, Select } from "antd";
import SearchFieldWithSelect from "../../Components/DataTable/SearchFieldWithSelect";
import { translateOptions } from "../../utils/translatedOptions";
import { search_array } from "../../Routes";
import { useFilterStateState } from "../../zustand/Filter";
import { useSearchParams } from "react-router-dom";
import { TbReorder } from "react-icons/tb";
const OrderBySelect = () => {
const {t} = useTranslation();
const { Filter, setFilter } = useFilterStateState();
const [searchParams, setSearchParams] = useSearchParams();
const type_param = searchParams.get('type');
const [type, setType] = useState(type_param);
const translateArray = translateOptions(search_array, t);
const handleChange = (value: string) => {
const newArray = Filter?.filter((item: any) => item.select !== true);
setFilter([
...newArray,
{ name: value, index: Filter.length, select: true },
]);
if (type_param) {
searchParams.delete('type');
setSearchParams(searchParams);
}
setType(value);
};
const { t } = useTranslation();
const { Filter, setFilter } = useFilterStateState();
const [searchParams, setSearchParams] = useSearchParams();
// send this with api request
// type: type,
// page: currentPage,
const type_param = searchParams.get("type");
const [type, setType] = useState(type_param);
const translateArray = translateOptions(search_array, t);
const handleChange = (value: string) => {
const newArray = Filter?.filter((item: any) => item.select !== true);
setFilter([
...newArray,
{ name: value, index: Filter.length, select: true },
]);
if (type_param) {
searchParams.delete("type");
setSearchParams(searchParams);
}
setType(value);
};
// send this with api request
// type: type,
// page: currentPage,
return (
<div className='order_by_filter'>
<Select
className='order_by_select'
style={{ width: 200 }}
size="large"
placeholder={<div><TbReorder className='addition_select_icon'/> {t("ترتيب حسب")} </div>}
onChange={handleChange}
options={[
{ value: "تصاعديا", label: t("تصاعديا") },
{ value: "تنازليا", label: t("تنازليا") },
{ value: "شوهدت مؤخرا", label: t("شوهدت مؤخرا") },
{ value: "وصلت مؤخرا", label: t("وصلت مؤخرا") },
]}
/>
<div className="order_by_filter">
<Select
className="order_by_select"
style={{ width: 200 }}
size="large"
placeholder={
<div>
<TbReorder className="addition_select_icon" /> {t("ترتيب حسب")}{" "}
</div>
}
onChange={handleChange}
options={[
{ value: "تصاعديا", label: t("تصاعديا") },
{ value: "تنازليا", label: t("تنازليا") },
{ value: "شوهدت مؤخرا", label: t("شوهدت مؤخرا") },
{ value: "وصلت مؤخرا", label: t("وصلت مؤخرا") },
]}
/>
</div>
)
}
);
};
export default OrderBySelect
export default OrderBySelect;

View File

@ -1,55 +1,54 @@
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Divider, Select } from 'antd';
import SearchFieldWithSelect from '../../Components/DataTable/SearchFieldWithSelect';
import { translateOptions } from '../../utils/translatedOptions';
import { search_array } from '../../Routes';
import { useFilterStateState } from '../../zustand/Filter';
import { useSearchParams } from 'react-router-dom';
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Divider, Select } from "antd";
import SearchFieldWithSelect from "../../Components/DataTable/SearchFieldWithSelect";
import { translateOptions } from "../../utils/translatedOptions";
import { search_array } from "../../Routes";
import { useFilterStateState } from "../../zustand/Filter";
import { useSearchParams } from "react-router-dom";
const PaginationColumn = () => {
const { t } = useTranslation();
const { Filter, setFilter } = useFilterStateState();
const [searchParams, setSearchParams] = useSearchParams();
const {t} = useTranslation();
const { Filter, setFilter } = useFilterStateState();
const [searchParams, setSearchParams] = useSearchParams();
const type_param = searchParams.get('type');
const [type, setType] = useState(type_param);
const translateArray = translateOptions(search_array, t);
const handleChange = (value: string) => {
const newArray = Filter?.filter((item: any) => item.select !== true);
setFilter([
...newArray,
{ name: value, index: Filter.length, select: true },
]);
if (type_param) {
searchParams.delete('type');
setSearchParams(searchParams);
}
setType(value);
};
const type_param = searchParams.get("type");
const [type, setType] = useState(type_param);
const translateArray = translateOptions(search_array, t);
const handleChange = (value: string) => {
const newArray = Filter?.filter((item: any) => item.select !== true);
setFilter([
...newArray,
{ name: value, index: Filter.length, select: true },
]);
if (type_param) {
searchParams.delete("type");
setSearchParams(searchParams);
}
setType(value);
};
// send this with api request
// type: type,
// page: currentPage,
// send this with api request
// type: type,
// page: currentPage,
return (
<div className='pagination_column'>
<Select
className='pagination_select'
style={{ width: 70 }}
size="large"
defaultValue={"10"}
placeholder={"10"}
onChange={handleChange}
options={[
{ value: "10", label: t("10") },
{ value: "20", label: t("20") },
{ value: "50", label: t("50") },
{ value: "100", label: t("100") },
]}
/>
<div className="pagination_column">
<Select
className="pagination_select"
style={{ width: 70 }}
size="large"
defaultValue={"10"}
placeholder={"10"}
onChange={handleChange}
options={[
{ value: "10", label: t("10") },
{ value: "20", label: t("20") },
{ value: "50", label: t("50") },
{ value: "100", label: t("100") },
]}
/>
</div>
)
}
);
};
export default PaginationColumn
export default PaginationColumn;

View File

@ -26,11 +26,28 @@ const NavBarRightSide = () => {
};
return (
<article>
<span className="header_icons">
<TooltipComp note="change_language" color="#E0E0E0" icon={<TbWorld size={25}/>}/>
<TooltipComp note="add" color="#E0E0E0" icon={<CiCirclePlus size={25}/>}/>
<TooltipComp className="NotificationsIcon" note="notification" color="#E0E0E0" icon={< > <IoIosNotificationsOutline size={25} /> </>}/>
<TooltipComp
note="change_language"
color="#E0E0E0"
icon={<TbWorld size={25} />}
/>
<TooltipComp
note="add"
color="#E0E0E0"
icon={<CiCirclePlus size={25} />}
/>
<TooltipComp
className="NotificationsIcon"
note="notification"
color="#E0E0E0"
icon={
<>
{" "}
<IoIosNotificationsOutline size={25} />{" "}
</>
}
/>
</span>
<div className="header_profile">
{/* <span>

View File

@ -1,12 +1,21 @@
import React from 'react'
import React from "react";
import { Tooltip } from "antd";
import { ModalEnum } from '../../../enums/Model';
import { useTranslation } from 'react-i18next';
import { CiCirclePlus } from 'react-icons/ci';
import useModalHandler from '../../../utils/useModalHandler';
const TooltipComp = ({note,color,icon,className=""}:{note:string,color:string,icon:any,className?:string}) => {
import { ModalEnum } from "../../../enums/Model";
import { useTranslation } from "react-i18next";
import { CiCirclePlus } from "react-icons/ci";
import useModalHandler from "../../../utils/useModalHandler";
const TooltipComp = ({
note,
color,
icon,
className = "",
}: {
note: string;
color: string;
icon: any;
className?: string;
}) => {
const [t] = useTranslation();
const { handel_open_model } = useModalHandler();
@ -15,21 +24,15 @@ const TooltipComp = ({note,color,icon,className=""}:{note:string,color:string,ic
};
return (
<div className={className}>
<Tooltip
placement="top"
title={
<div onClick={handleEdit}>
{t(`header.${note}`)}
</div>
}
color={color}
>
<div className={`gear `}>
{icon}
</div>
</Tooltip>
<Tooltip
placement="top"
title={<div onClick={handleEdit}>{t(`header.${note}`)}</div>}
color={color}
>
<div className={`gear `}>{icon}</div>
</Tooltip>
</div>
)
}
);
};
export default TooltipComp
export default TooltipComp;

View File

@ -21,17 +21,23 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
>
<i>{item.icon}</i>
{/* Conditionally render the text based on sidebar width */}
<span style={{ display: isOpen === false ? 'none' : 'inline' }}>
<span style={{ display: isOpen === false ? "none" : "inline" }}>
{t(item.text)}
</span>
{item?.children && (
<>
{isDropdownOpen ? (
<div className="DropDownIcon" onClick={() => handleDropdown(index)}>
<div
className="DropDownIcon"
onClick={() => handleDropdown(index)}
>
<MdExpandLess />
</div>
) : (
<div className="DropDownIcon" onClick={() => handleDropdown(index)}>
<div
className="DropDownIcon"
onClick={() => handleDropdown(index)}
>
<MdExpandMore />
</div>
)}
@ -47,11 +53,11 @@ export const MenuItem = ({ item, location, index, isOpen }: any) => {
item={childItem}
location={location}
index={childIndex}
isOpen={isOpen}
isOpen={isOpen}
/>
))}
</div>
)}
</>
);
};
};

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,15 @@
import React from 'react';
import Lottie from 'lottie-react'; // Default import
import animationData from './Loading.json'; // Import your Lottie JSON animation
import React from "react";
import Lottie from "lottie-react"; // Default import
import animationData from "./Loading.json"; // Import your Lottie JSON animation
const LoadingLottie = () => {
return (
<div className="cc">
<Lottie animationData={animationData} loop={true} style={{ width: 300, height: 300 }} />
<Lottie
animationData={animationData}
loop={true}
style={{ width: 300, height: 300 }}
/>
</div>
);
};

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,15 @@
import React from 'react';
import Lottie from 'lottie-react'; // Default import
import animationData from './NotFound.json'; // Import your Lottie JSON animation
import React from "react";
import Lottie from "lottie-react"; // Default import
import animationData from "./NotFound.json"; // Import your Lottie JSON animation
const NotFoundLottie = () => {
return (
<div className="cc">
<Lottie animationData={animationData} loop={true} style={{ width: 300, height: 300 }} />
<Lottie
animationData={animationData}
loop={true}
style={{ width: 300, height: 300 }}
/>
</div>
);
};

View File

@ -48,11 +48,7 @@ const ActionButtons: React.FC<ActionButtonsProps> = ({
{canDelete && (
// <Tooltip placement="top" title={t(deleteTooltipTitle)} color="#E0E0E0">
<GoTrash
onClick={onDelete}
size={22}
style={{ color: "#A098AE" }}
/>
<GoTrash onClick={onDelete} size={22} style={{ color: "#A098AE" }} />
// </Tooltip>
)}
{canShow && (

View File

@ -102,8 +102,7 @@ const SearchField = ({
};
console.log(AllPagesOption);
console.log(option,"option");
console.log(option, "option");
return (
<div className="ValidationField w-100">

View File

@ -53,7 +53,7 @@ const SelectField = ({
onChange={onChange || SelectableChange}
showSearch={false}
id={name}
fieldNames={{label:"name",value:"id"}}
fieldNames={{ label: "name", value: "id" }}
{...props}
/>
</ValidationFieldContainer>

View File

@ -21,13 +21,12 @@
}
}
//// upload
.ant-upload-select {
width: 100%;
}
.ant-btn-default{
.ant-btn-default {
padding: 7px 11px;
height: var(--fieldHeight);
display: flex;
@ -35,39 +34,34 @@
align-items: center;
}
//// number input
///
.ant-input-number-affix-wrapper-lg{
///
.ant-input-number-affix-wrapper-lg {
width: 100%;
}
.ValidationFieldCheckbox{
.ValidationFieldCheckbox {
// background-color: red;
}
/// input hight
.ant-form-item-control-input-content{
/// input hight
.ant-form-item-control-input-content {
height: var(--fieldHeight);
}
//// date picker
.ant-picker-large{
.ant-picker-large {
height: var(--fieldHeight);
}
/// text area
///
/// text area
///
.ValidationFieldTextArea{
.ant-form-item-control-input-content{
.ValidationFieldTextArea {
.ant-form-item-control-input-content {
min-height: 120px;
}
}
.ant-input-textarea-affix-wrapper.ant-input-affix-wrapper {
height: 120px;
}
.ant-input-textarea-affix-wrapper.ant-input-affix-wrapper {
height: 120px;
}

View File

@ -27,10 +27,10 @@ const Header = () => {
return (
<header className="exercise_add_header mb-4">
<article>
<img src="/Icon/QuestionIcon.svg" alt="" />
<div>
{t("practical.add")} {t("models.exercise")}{" "}
</div>
<img src="/Icon/QuestionIcon.svg" alt="" />
<div>
{t("practical.add")} {t("models.exercise")}{" "}
</div>
</article>
<div>
<GoArrowSwitch onClick={handleChange} className="m-2" />

View File

@ -68,9 +68,9 @@ const DeleteModels: React.FC<ModalFormProps> = ({
open={isOpen === ModelEnum}
onCancel={handleCancel}
>
<header>{t("practical.delete_this_item")}
<MdCancel onClick={handleCancel}/>
<header>
{t("practical.delete_this_item")}
<MdCancel onClick={handleCancel} />
</header>
<main className="main_modal">

View File

@ -1,62 +1,70 @@
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Divider } from 'antd';
import SearchFieldWithSelect from '../../Components/DataTable/SearchFieldWithSelect';
import { translateOptions } from '../../utils/translatedOptions';
import { search_array } from '../../Routes';
import PaginationColumn from '../../Components/Filter/PaginationColumn';
import OrderBySelect from '../../Components/Filter/OrderBySelect';
import LayoutFilterModal from './LayoutFilterModal';
import { BiFilterAlt } from 'react-icons/bi';
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Divider } from "antd";
import SearchFieldWithSelect from "../../Components/DataTable/SearchFieldWithSelect";
import { translateOptions } from "../../utils/translatedOptions";
import { search_array } from "../../Routes";
import PaginationColumn from "../../Components/Filter/PaginationColumn";
import OrderBySelect from "../../Components/Filter/OrderBySelect";
import LayoutFilterModal from "./LayoutFilterModal";
import { BiFilterAlt } from "react-icons/bi";
import { MdKeyboardArrowDown } from "react-icons/md";
import SearchField from '../../Components/DataTable/SearchField';
import SearchField from "../../Components/DataTable/SearchField";
const FilterLayout = ({filterTitle, sub_children}:{filterTitle:string,sub_children:any}) => {
const {t} = useTranslation();
const FilterLayout = ({
filterTitle,
sub_children,
}: {
filterTitle: string;
sub_children: any;
}) => {
const { t } = useTranslation();
const translateArray = translateOptions(search_array, t);
const [isOpen, setIsOpen ] = useState(false);
const [isOpen, setIsOpen] = useState(false);
// send this with api request
// type: type,
// page: currentPage,
return (
<div className='filter_header'>
<div className='filter_header_top'>
<h4>{t(filterTitle)}</h4>
<div className='filter_and_order_by'>
<span>
<LayoutFilterModal
ModelClassName='filter_model_direction'
children={<div className='model_sub_children'>{sub_children}</div>}
isOpen={isOpen} setIsOpen={setIsOpen}
/>
<div className='filter_button' onClick={()=> setIsOpen(true)}>
<span>
<BiFilterAlt className='addition_select_icon'/>
{t("ترتيب حسب")}
</span>
<MdKeyboardArrowDown/>
</div>
</span>
<span><OrderBySelect/></span>
</div>
</div>
<Divider/>
<div className="filter_header_bottom">
<span>
<p>{t("صف لكل صفحة")}</p>
<PaginationColumn/>
<p>{t("ادخالات")}</p>
</span>
<div className="header_search">
<SearchField
searchBy=''
placeholder={t("practical.search_here")}
/>
</div>
</div>
</div>
)
}
export default FilterLayout
return (
<div className="filter_header">
<div className="filter_header_top">
<h4>{t(filterTitle)}</h4>
<div className="filter_and_order_by">
<span>
<LayoutFilterModal
ModelClassName="filter_model_direction"
children={
<div className="model_sub_children">{sub_children}</div>
}
isOpen={isOpen}
setIsOpen={setIsOpen}
/>
<div className="filter_button" onClick={() => setIsOpen(true)}>
<span>
<BiFilterAlt className="addition_select_icon" />
{t("ترتيب حسب")}
</span>
<MdKeyboardArrowDown />
</div>
</span>
<span>
<OrderBySelect />
</span>
</div>
</div>
<Divider />
<div className="filter_header_bottom">
<span>
<p>{t("صف لكل صفحة")}</p>
<PaginationColumn />
<p>{t("ادخالات")}</p>
</span>
<div className="header_search">
<SearchField searchBy="" placeholder={t("practical.search_here")} />
</div>
</div>
</div>
);
};
export default FilterLayout;

View File

@ -16,8 +16,8 @@ interface LayoutFilterModalProps {
ModelClassName?: string;
width?: string;
isLoading?: boolean;
isOpen:any,
setIsOpen:any
isOpen: any;
setIsOpen: any;
}
const LayoutFilterModal = ({
@ -30,7 +30,7 @@ const LayoutFilterModal = ({
width = "28vw",
isLoading = false,
setIsOpen,
isOpen
isOpen,
}: LayoutFilterModalProps) => {
const { setObjectToEdit } = useObjectToEdit();
// useEffect(() => {
@ -46,9 +46,9 @@ const LayoutFilterModal = ({
setObjectToEdit({});
};
const handleOpen = () => {
setIsOpen(true)
setObjectToEdit({})
}
setIsOpen(true);
setObjectToEdit({});
};
const [t] = useTranslation();
return (
@ -62,28 +62,30 @@ const LayoutFilterModal = ({
onOk={handleOpen}
onCancel={handleCancel}
mask={false}
style={{position:"absolute",top:"31.4%",left:"16.7%"}}
style={{ position: "absolute", top: "31.4%", left: "16.7%" }}
>
<FormikForm
handleSubmit={handleSubmit}
initialValues={getInitialValues}
validationSchema={getValidationSchema}
>
<header>
{t("models.filter")}
</header>
<Divider/>
<header>{t("models.filter")}</header>
<Divider />
<main className="main_modal">
{isLoading ? <SpinContainer /> : children}
<Divider/>
<Divider />
<div className="buttons">
<div className="back_button pointer" style={{width:"7vw"}} onClick={handleCancel}>
<div
className="back_button pointer"
style={{ width: "7vw" }}
onClick={handleCancel}
>
{t("practical.reset")}
</div>
<button
className="add_button"
style={{width:"7vw"}}
style={{ width: "7vw" }}
// disabled={status === QueryStatusEnum.LOADING}
type="submit"
>

View File

@ -75,13 +75,13 @@ const LayoutModel = ({
{t(`practical.${isAddModal ? "add" : "edit"}`)}{" "}
{t(`models.${modelTitle}`)}{" "}
</span>
<MdCancel onClick={handleCancel}/>
<MdCancel onClick={handleCancel} />
</header>
<Divider/>
<Divider />
<main className="main_modal">
{isLoading ? <SpinContainer /> : children}
<Divider/>
<Divider />
<div className="buttons">
<div className="back_button pointer" onClick={handleCancel}>
{t("practical.cancel")}

View File

@ -16,17 +16,17 @@ const PageHeader = ({
ModelAbility,
pageTitle,
openModel = true,
locationToNavigate
}:{
canAdd:any,
ModelAbility:any,
pageTitle:string,
openModel?:boolean,
locationToNavigate?: string | any
locationToNavigate,
}: {
canAdd: any;
ModelAbility: any;
pageTitle: string;
openModel?: boolean;
locationToNavigate?: string | any;
}) => {
const navigate = useNavigate();
const { handel_open_model } = useModalHandler();
const {t} = useTranslation();
const { t } = useTranslation();
const { PageTitle } = usePageTitleState((state) => state);
const PrevPath = getPrevPathRoute(location.pathname);
@ -36,29 +36,34 @@ const PageHeader = ({
}
navigate(deletePathSegments(location.pathname, PrevPath));
};
const handleNavigateToPage = (location:string) => {
navigate(location)
}
const handleNavigateToPage = (location: string) => {
navigate(location);
};
return (
<div className="page_header">
<header className="d-flex justify-content-between">
<span className="page_header_links" onClick={handelNavigate}>
<h1 className="page_title">{t(`sidebar.${pageTitle}`)}</h1>
<span className="page_links"><MdOutlineArrowForwardIos /> {PageTitle}</span>
<span className="page_links">
<MdOutlineArrowForwardIos /> {PageTitle}
</span>
</span>
{canAdd && (
<div className="Selects">
<button
onClick={() => openModel ? handel_open_model(ModelAbility): handleNavigateToPage(locationToNavigate)}
className="add_button"
>
<BsPlusCircleFill />
{t(`models.${pageTitle}`)}
</button>
</div>
)}
</header>
{canAdd && (
<div className="Selects">
<button
onClick={() =>
openModel
? handel_open_model(ModelAbility)
: handleNavigateToPage(locationToNavigate)
}
className="add_button"
>
<BsPlusCircleFill />
{t(`models.${pageTitle}`)}
</button>
</div>
)}
</header>
</div>
);
};

View File

@ -1,13 +1,12 @@
import React, { lazy, Suspense } from "react";
import {
useAddKeyToData,
Table,
useTranslation,
usePagination,
} from ".";
import { useAddKeyToData, Table, useTranslation, usePagination } from ".";
import { DataTableProps } from "../../../types/Table";
const NotFoundLottie = React.lazy(() => import("../../../Components/Lottie/NotFound/NotFoundLottie"));
const LoadingLottie = React.lazy(() => import("../../../Components/Lottie/Loading/LoadingLottie"));
const NotFoundLottie = React.lazy(
() => import("../../../Components/Lottie/NotFound/NotFoundLottie"),
);
const LoadingLottie = React.lazy(
() => import("../../../Components/Lottie/Loading/LoadingLottie"),
);
const DataTable: React.FC<DataTableProps> = ({
response,
@ -27,38 +26,36 @@ const DataTable: React.FC<DataTableProps> = ({
return (
<Table
style={{minHeight:"300px"}}
style={{ minHeight: "300px" }}
columns={columns}
dataSource={dataSource}
rowClassName={(record, index) => getRowClassName(record, index)}
className="DataTable"
loading={{
spinning: isLoading || isRefetching,
indicator:<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense> ,
indicator: (
<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense>
),
size: "large",
}}
locale={{
emptyText: (
isLoading || isRefetching ?
<></>
:
<Suspense fallback={<></>}>
<NotFoundLottie
/>
</Suspense>
),
emptyText:
isLoading || isRefetching ? (
<></>
) : (
<Suspense fallback={<></>}>
<NotFoundLottie />
</Suspense>
),
}}
pagination={{
...pagination,
onChange: handlePageChange,
nextIcon:<>{t("practical.next")}</>,
prevIcon:<> {t("practical.prev")} </>,
className:"pagination_antd"
nextIcon: <>{t("practical.next")}</>,
prevIcon: <> {t("practical.prev")} </>,
className: "pagination_antd",
}}
{...props}
/>

View File

@ -3,9 +3,4 @@ import { useAddKeyToData } from "../../../Hooks/useAddKeyToData";
import usePagination from "../usePagination";
import { useTranslation } from "react-i18next";
export {
Table,
useAddKeyToData,
usePagination,
useTranslation,
};
export { Table, useAddKeyToData, usePagination, useTranslation };

View File

@ -10,12 +10,14 @@ const Layout = ({
children: React.ReactNode;
className?: string;
}) => {
const [isOpen, setIsOpen] = useState(true);
const [isOpen, setIsOpen] = useState(true);
return (
<ProtectedRouteProvider className="Layout">
<main className={`${className} ${isOpen ?"Layout_Body":"Layout_Body side_bar_close" }`}>
<NavBar isOpen={isOpen}/>
<main
className={`${className} ${isOpen ? "Layout_Body" : "Layout_Body side_bar_close"}`}
>
<NavBar isOpen={isOpen} />
<div className="Layout_Children">{children}</div>
</main>
<SideBar isOpen={isOpen} setIsOpen={setIsOpen} />

View File

@ -15,7 +15,7 @@ import { useTranslation } from "react-i18next";
// Lazy load the ChangePasswordModel
const ChangePasswordModel = lazy(() => import("./model/AddModel"));
const NavBar = ({isOpen}:{isOpen:boolean}) => {
const NavBar = ({ isOpen }: { isOpen: boolean }) => {
const { PageTitle } = usePageTitleState((state) => state);
const location = useLocation();
const navigate = useNavigate();
@ -33,17 +33,17 @@ const NavBar = ({isOpen}:{isOpen:boolean}) => {
return (
<div className="NavBar">
<Suspense fallback={<></>}>
{/* <span className="navbar_link" onClick={handelNavigate}>
{/* <span className="navbar_link" onClick={handelNavigate}>
<MdOutlineArrowForwardIos /> {PageTitle}
</span> */}
<div className="header_search">
<SearchFieldWithSelect
options={translateArray}
placeholder={t("practical.search_here")}
withIcon
/>
</div>
<NavBarRightSide />
<div className="header_search">
<SearchFieldWithSelect
options={translateArray}
placeholder={t("practical.search_here")}
withIcon
/>
</div>
<NavBarRightSide />
<ChangePasswordModel />
</Suspense>
</div>

View File

@ -13,7 +13,13 @@ import { CiMenuBurger, CiSettings } from "react-icons/ci";
import { IoIosMenu } from "react-icons/io";
import { HiMenuAlt2, HiMenuAlt3 } from "react-icons/hi";
const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
const SideBar = ({
isOpen,
setIsOpen,
}: {
isOpen: boolean;
setIsOpen: any;
}) => {
const location = useLocation();
const navigate = useNavigate();
const { logout } = useAuthState();
@ -21,35 +27,38 @@ const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
const branch_name = getLocalStorage(BRANCH_OBJECT_KEY)?.name;
const toggleSidebar = () => {
setIsOpen((prev: boolean) => prev === true ? false : true);
setIsOpen((prev: boolean) => (prev === true ? false : true));
};
return (
<div className={isOpen ? "side_bar" :"side_bar side_bar_closed"} >
<div className={isOpen ? "side_bar" : "side_bar side_bar_closed"}>
<div className="side_bar_header">
<img src={isOpen ? "/App/Logo.png" : "/App/Logo2.png"} alt="" />
<HiMenuAlt3 onClick={toggleSidebar} />
<HiMenuAlt3 onClick={toggleSidebar} />
</div>
{/* <Divider /> */}
<HiMenuAlt2 className="side_bar_close_menu" style={isOpen? {display:"none"}: {display:"inline"}} onClick={toggleSidebar} />
{/* <Divider /> */}
<HiMenuAlt2
className="side_bar_close_menu"
style={isOpen ? { display: "none" } : { display: "inline" }}
onClick={toggleSidebar}
/>
<div className="side_bar_links">
<p>{t("sidebar.main_menu")}</p>
{menuItems.map((item, index) => {
const useAbility = hasAbility(item.abilities, item.abilities_value);
if (!useAbility) {
return <React.Fragment key={index}></React.Fragment>;
}
return (
<MenuItem
key={index}
item={item}
location={location}
index={index}
isOpen={isOpen}
/>
);
})}
{menuItems.map((item, index) => {
const useAbility = hasAbility(item.abilities, item.abilities_value);
if (!useAbility) {
return <React.Fragment key={index}></React.Fragment>;
}
return (
<MenuItem
key={index}
item={item}
location={location}
index={index}
isOpen={isOpen}
/>
);
})}
</div>
<div className="side_bar_setting">
<p>{t("sidebar.setting")}</p>
@ -58,11 +67,12 @@ const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
<span>{t("sidebar.setting")}</span>
</div>
<div
className="logout_button"
className="logout_button"
onClick={() => {
logout();
navigate("/auth");
}}>
logout();
navigate("/auth");
}}
>
<MdLogout />
<span>{t("sidebar.logout")}</span>
</div>
@ -72,5 +82,3 @@ const SideBar = ({isOpen,setIsOpen}:{isOpen:boolean,setIsOpen:any}) => {
};
export default SideBar;

View File

@ -32,7 +32,7 @@ const EditModel: React.FC = () => {
getInitialValues={getInitialValues(objectToEdit)}
getValidationSchema={getValidationSchema}
isAddModal={false}
width="500px"
width="500px"
>
<ModelForm />
</LayoutModel>

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -52,13 +52,15 @@ const TableHeader = () => {
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
<PageHeader
pageTitle="curriculum"
ModelAbility={ModalEnum?.CURRICULUM_ADD}
canAdd={canAddCurriculum}/>
ModelAbility={ModalEnum?.CURRICULUM_ADD}
canAdd={canAddCurriculum}
/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.curriculum"/>
sub_children={<FilterForm />}
filterTitle="sidebar.curriculum"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -54,15 +54,15 @@ export const useColumns = () => {
{
// canAddCurriculum ? (
// <button
// onClick={() => handel_open_model(ModalEnum?.CURRICULUM_ADD)}
// className="add_button"
// >
// {t("practical.add")} {t("models.curriculum")} <FaPlus />
// </button>
// ) : (
// ""
// ),
// <button
// onClick={() => handel_open_model(ModalEnum?.CURRICULUM_ADD)}
// className="add_button"
// >
// {t("practical.add")} {t("models.curriculum")} <FaPlus />
// </button>
// ) : (
// ""
// ),
title: t("columns.procedure"),
key: "actions",
align: "center",

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -25,14 +25,15 @@ const TableHeader = () => {
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="grade"
ModelAbility={ModalEnum?.GRADE_ADD}
canAdd={canAddGrade}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.grade"/>
<PageHeader
pageTitle="grade"
ModelAbility={ModalEnum?.GRADE_ADD}
canAdd={canAddGrade}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.grade"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -64,16 +64,16 @@ export const useColumns = () => {
},
{
// canAddGrade ? (
// <button
// onClick={() => handel_open_model(ModalEnum?.GRADE_ADD)}
// className="add_button"
// >
// {t("practical.add")} {t("models.grade")} <FaPlus />
// </button>
// ) : (
// <button
// onClick={() => handel_open_model(ModalEnum?.GRADE_ADD)}
// className="add_button"
// >
// {t("practical.add")} {t("models.grade")} <FaPlus />
// </button>
// ) : (
// ""
// ),
title: t("columns.procedure"),
key: "actions",
align: "center",

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -13,7 +13,9 @@ import FilterForm from "./Model/FilterForm";
const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
const DeleteModalForm = lazy(
() => import("../../../Layout/Dashboard/DeleteModels"),
);
const SearchField = lazy(
() => import("../../../Components/DataTable/SearchField"),
);
@ -21,25 +23,25 @@ const SearchField = lazy(
const TableHeader = () => {
const { handel_open_model } = useModalHandler();
const [t] = useTranslation();
useSetPageTitle(
t(`page_header.report`),
);
useSetPageTitle(t(`page_header.report`));
const deleteMutation = useDeleteTag();
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="report"
ModelAbility={ModalEnum?.REPORT_ADD}
canAdd={canAddReport}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.report"/>
<PageHeader
pageTitle="report"
ModelAbility={ModalEnum?.REPORT_ADD}
canAdd={canAddReport}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.report"
/>
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.REPORT_DELETE}
/>
/>
<AddModalForm />
<EditModalForm />
</Suspense>

View File

@ -13,11 +13,11 @@ export const useColumns = () => {
const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record:any) => {
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.REPORT_DELETE);
};
const handleEdit = (record:any) => {
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.REPORT_EDIT);
};

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -4,7 +4,11 @@ import { ModalEnum } from "../../../enums/Model";
import { useTranslation } from "react-i18next";
import { lazy, Suspense } from "react";
import { Spin } from "antd";
import { canAddReport, canAddReseller, canAddTags } from "../../../utils/hasAbilityFn";
import {
canAddReport,
canAddReseller,
canAddTags,
} from "../../../utils/hasAbilityFn";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { useDeleteTag } from "../../../api/tags";
import PageHeader from "../../../Layout/Dashboard/PageHeader";
@ -13,7 +17,9 @@ import FilterForm from "./Model/FilterForm";
const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
const DeleteModalForm = lazy(
() => import("../../../Layout/Dashboard/DeleteModels"),
);
const SearchField = lazy(
() => import("../../../Components/DataTable/SearchField"),
);
@ -21,25 +27,25 @@ const SearchField = lazy(
const TableHeader = () => {
const { handel_open_model } = useModalHandler();
const [t] = useTranslation();
useSetPageTitle(
t(`page_header.reseller`),
);
useSetPageTitle(t(`page_header.reseller`));
const deleteMutation = useDeleteTag();
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="reseller"
ModelAbility={ModalEnum?.RESELLER_ADD}
canAdd={canAddReseller}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.reseller"/>
<PageHeader
pageTitle="reseller"
ModelAbility={ModalEnum?.RESELLER_ADD}
canAdd={canAddReseller}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.reseller"
/>
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.RESELLER_DELETE}
/>
/>
<AddModalForm />
<EditModalForm />
</Suspense>

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 { canDeleteReseller, canDeleteUser, canEditReseller, canEditUser } from "../../../utils/hasAbilityFn";
import {
canDeleteReseller,
canDeleteUser,
canEditReseller,
canEditUser,
} from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons";
export const useColumns = () => {
@ -13,11 +18,11 @@ export const useColumns = () => {
const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record:any) => {
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.RESELLER_DELETE);
};
const handleEdit = (record:any) => {
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.RESELLER_EDIT);
};

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -5,37 +5,52 @@ import { useValidationValidationParamState } from "../../../../Components/Valida
const Form = ({ isEdit = false }: { isEdit?: 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?.currentPage;
const sex = [
{name:"male" , id :"male"},
{name:"female" , id :"female"}
]
{ name: "male", id: "male" },
{ name: "female", id: "female" },
];
return (
<Row className="w-100">
<Col>
<ValidationField name="first_name" placeholder="first_name" label="first_name" />
<ValidationField name="last_name" placeholder="last_name" label="last_name" />
<ValidationField name="username" placeholder="username" label="username" />
{!isEdit &&
<ValidationField name="password" placeholder="password" label="password" />
}
<ValidationField
name="first_name"
placeholder="first_name"
label="first_name"
/>
<ValidationField
name="last_name"
placeholder="last_name"
label="last_name"
/>
<ValidationField
name="username"
placeholder="username"
label="username"
/>
{!isEdit && (
<ValidationField
name="password"
placeholder="password"
label="password"
/>
)}
</Col>
<Col>
<ValidationField name="phone_number" placeholder="contact_number1" label="contact_number1" />
<ValidationField
name="phone_number"
placeholder="contact_number1"
label="contact_number1"
/>
<ValidationField
searchBy="GradeName"
name="grade_id"
@ -46,10 +61,8 @@ const Form = ({ isEdit = false }: { isEdit?: boolean }) => {
canChangePage={canChangeGradePage}
PageName={"GradeCurrentPage"}
page={GradePage}
/>
<ValidationField type="Select" name="sex" option={sex} />
</Col>
</Row>
);

View File

@ -11,10 +11,9 @@ export const getInitialValues = (
// address: objectToEdit?.address ?? "",
// birthday: objectToEdit?.birthday ?? "",
// city: objectToEdit?.city ?? "",
grade_id: objectToEdit?.grade_id ,
grade_id: objectToEdit?.grade_id,
// image: objectToEdit?.image ?? "",
sex: objectToEdit?.sex ,
sex: objectToEdit?.sex,
};
};

View File

@ -25,13 +25,15 @@ const TableHeader = () => {
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="student"
ModelAbility={ModalEnum?.STUDENT_ADD}
canAdd={canAddStudent}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="table.student"/>
<PageHeader
pageTitle="student"
ModelAbility={ModalEnum?.STUDENT_ADD}
canAdd={canAddStudent}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="table.student"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -10,4 +10,3 @@ const App: React.FC = () => {
};
export default App;

View File

@ -64,7 +64,6 @@ export const useColumns = () => {
align: "center",
render: (_text, record) => record?.sex,
},
{
title: "",

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -8,7 +8,7 @@ const Form = () => {
<Col>
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<div>
<DynamicTags />
</div>

View File

@ -13,7 +13,9 @@ import FilterForm from "./Model/FilterForm";
const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
const DeleteModalForm = lazy(
() => import("../../../Layout/Dashboard/DeleteModels"),
);
const SearchField = lazy(
() => import("../../../Components/DataTable/SearchField"),
);
@ -21,25 +23,25 @@ const SearchField = lazy(
const TableHeader = () => {
const { handel_open_model } = useModalHandler();
const [t] = useTranslation();
useSetPageTitle(
t(`page_header.tags`),
);
useSetPageTitle(t(`page_header.tags`));
const deleteMutation = useDeleteTag();
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="tags"
ModelAbility={ModalEnum?.TAGS_ADD}
canAdd={canAddTags}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.tags"/>
<PageHeader
pageTitle="tags"
ModelAbility={ModalEnum?.TAGS_ADD}
canAdd={canAddTags}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.tags"
/>
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.TAGS_DELETE}
/>
/>
<AddModalForm />
<EditModalForm />
</Suspense>

View File

@ -13,11 +13,11 @@ export const useColumns = () => {
const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record:any) => {
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.TAGS_DELETE);
};
const handleEdit = (record:any) => {
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.TAGS_EDIT);
};

View File

@ -16,9 +16,12 @@ import { useParams } from "react-router-dom";
import { ParamsEnum } from "../../../enums/params";
import { useGetAllUnit, useUpdateUnitOrder } from "../../../api/unit";
const NotFoundLottie = React.lazy(() => import("../../../Components/Lottie/NotFound/NotFoundLottie"));
const LoadingLottie = React.lazy(() => import("../../../Components/Lottie/Loading/LoadingLottie" ));
const NotFoundLottie = React.lazy(
() => import("../../../Components/Lottie/NotFound/NotFoundLottie"),
);
const LoadingLottie = React.lazy(
() => import("../../../Components/Lottie/Loading/LoadingLottie"),
);
import { useTranslation } from "react-i18next";
import { useColumns } from "./useTableColumns";
@ -52,7 +55,6 @@ export const DragHandleUnit: React.FC = () => {
);
};
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
"data-row-key": string;
}
@ -96,7 +98,7 @@ const DrapableTable: React.FC = () => {
response?.data?.data?.map((item: any, index: number) => ({
id: item.id, // Ensure this is a unique identifier
order: index + 1, // Assign order based on index
...item
...item,
})) ?? [];
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
@ -107,39 +109,42 @@ const DrapableTable: React.FC = () => {
setDataSource(sortedData);
}, [response?.data?.data]);
const {mutate:orderUnit} = useUpdateUnitOrder({},{
retry:false
})
const { mutate: orderUnit } = useUpdateUnitOrder(
{},
{
retry: false,
},
);
const onDragEnd = ({ active, over }: DragEndEvent) => {
if (active.id !== over?.id) {
setDataSource((prevState) => {
const activeIndex = prevState.findIndex(
(record) => record.id === active.id,
);
const overIndex = prevState.findIndex(
//@ts-ignore
//@ts-ignore
(record) => record.id === over.id,
);
// Move the items in the array
const newState = arrayMove(prevState, activeIndex, overIndex);
const orderedNewState = newState.map((item, index) => ({
...item,
order: index + 1, // Update the order based on the new index
}));
const orderedNewState = newState.map((item, index) => ({
...item,
order: index + 1, // Update the order based on the new index
}));
// Update the order based on the new positions
const orderedNewStateWithNewChape = orderedNewState?.map((item:any)=>{
return {
"unit_id":item?.id,
"order":item?.order
}
})
orderUnit({units: orderedNewStateWithNewChape, _method:"PUT"})
return orderedNewState
const orderedNewStateWithNewChape = orderedNewState?.map(
(item: any) => {
return {
unit_id: item?.id,
order: item?.order,
};
},
);
orderUnit({ units: orderedNewStateWithNewChape, _method: "PUT" });
return orderedNewState;
});
}
};
@ -147,11 +152,11 @@ const DrapableTable: React.FC = () => {
return index % 2 === 0 ? "even-row" : "odd-row";
};
const isLoading = response?.isLoading;
const [t] = useTranslation()
const [t] = useTranslation();
const columns = useColumns();
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order) ;
console.log(sortedDataSource,"sortedDataSource");
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order);
console.log(sortedDataSource, "sortedDataSource");
return (
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
<SortableContext
@ -161,32 +166,30 @@ const DrapableTable: React.FC = () => {
<Table
rowKey="id"
components={{ body: { row: Row } }}
//@ts-ignore
//@ts-ignore
columns={columns}
dataSource={sortedDataSource}
dataSource={sortedDataSource}
pagination={false}
rowClassName={(record, index) => getRowClassName(record, index)}
className="DataTable"
loading={{
spinning: isLoading,
indicator:<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense> ,
size: "large",
}}
locale={{
emptyText: (
isLoading ?
<></>
:
<Suspense fallback={<></>}>
<NotFoundLottie
/>
</Suspense>
),
}}
rowClassName={(record, index) => getRowClassName(record, index)}
className="DataTable"
loading={{
spinning: isLoading,
indicator: (
<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense>
),
size: "large",
}}
locale={{
emptyText: isLoading ? (
<></>
) : (
<Suspense fallback={<></>}>
<NotFoundLottie />
</Suspense>
),
}}
/>
</SortableContext>
</DndContext>

View File

@ -34,7 +34,6 @@ const AddModel: React.FC = () => {
handleSubmit={handleSubmit}
getInitialValues={getInitialValues({})}
getValidationSchema={getValidationSchema}
>
<ModelForm />
</LayoutModel>

View File

@ -27,7 +27,6 @@ const EditModel: React.FC = () => {
getInitialValues={getInitialValues(objectToEdit)}
getValidationSchema={getValidationSchema}
isAddModal={false}
>
<ModelForm />
</LayoutModel>

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -5,8 +5,8 @@ import { enumToArray } from "../../../../api/utils/enumToArray";
const Form = () => {
const termsArray = enumToArray(TermEnum);
console.log(termsArray);
console.log(termsArray);
return (
<Row className="w-100">
<Col>

View File

@ -60,13 +60,15 @@ const TableHeader = () => {
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="unit"
ModelAbility={ModalEnum?.UNIT_ADD}
canAdd={canAddUnit}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.unit"/>
<PageHeader
pageTitle="unit"
ModelAbility={ModalEnum?.UNIT_ADD}
canAdd={canAddUnit}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.unit"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -42,7 +42,12 @@ export const useColumns = () => {
const [t] = useTranslation();
const columns: TableColumnsType<Unit> = [
{ key: "sort", align: "center", width: 80, render: () => <DragHandleUnit /> },
{
key: "sort",
align: "center",
width: 80,
render: () => <DragHandleUnit />,
},
{
title: t("columns.id"),
@ -68,7 +73,6 @@ export const useColumns = () => {
},
{
title: t("columns.procedure"),
key: "actions",
align: "center",

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -5,10 +5,13 @@ const Form = () => {
return (
<Row className="w-100">
<Col>
<ValidationField placeholder="name" label="name" name="name" type="Number" />
<ValidationField
placeholder="name"
label="name"
name="name"
type="Number"
/>
</Col>
</Row>
);
};

View File

@ -2,7 +2,7 @@ import { ModalEnum } from "../../../enums/Model";
import { useTranslation } from "react-i18next";
import { lazy, Suspense } from "react";
import { Spin } from "antd";
import { canAddUser } from "../../../utils/hasAbilityFn";
import { canAddUser } from "../../../utils/hasAbilityFn";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { useDeleteTag } from "../../../api/tags";
import PageHeader from "../../../Layout/Dashboard/PageHeader";
@ -11,29 +11,31 @@ import FilterForm from "./Model/FilterForm";
const Table = lazy(() => import("./Table"));
const AddModalForm = lazy(() => import("./Model/AddModel"));
const EditModalForm = lazy(() => import("./Model/EditModel"));
const DeleteModalForm = lazy(() => import("../../../Layout/Dashboard/DeleteModels"));
const DeleteModalForm = lazy(
() => import("../../../Layout/Dashboard/DeleteModels"),
);
const TableHeader = () => {
const [t] = useTranslation();
useSetPageTitle(
t(`page_header.user`),
);
useSetPageTitle(t(`page_header.user`));
const deleteMutation = useDeleteTag();
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="user"
ModelAbility={ModalEnum?.USER_ADD}
canAdd={canAddUser}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.user"/>
<PageHeader
pageTitle="user"
ModelAbility={ModalEnum?.USER_ADD}
canAdd={canAddUser}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.user"
/>
<Table />
<DeleteModalForm
deleteMutation={deleteMutation}
ModelEnum={ModalEnum?.USER_DELETE}
/>
/>
<AddModalForm />
<EditModalForm />
</Suspense>

View File

@ -10,7 +10,6 @@ const App: React.FC = () => {
const response = useGetAllUser({
name: searchQuery,
pagination: true,
});
return <DataTable response={response} useColumns={useColumns} />;

View File

@ -13,11 +13,11 @@ export const useColumns = () => {
const { setIsOpen } = useModalState((state) => state);
const { setObjectToEdit } = useObjectToEdit((state) => state);
const handelDelete = (record:any) => {
const handelDelete = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.USER_DELETE);
};
const handleEdit = (record:any) => {
const handleEdit = (record: any) => {
setObjectToEdit(record);
setIsOpen(ModalEnum?.USER_EDIT);
};

View File

@ -16,10 +16,12 @@ import { useParams } from "react-router-dom";
import { ParamsEnum } from "../../../enums/params";
import { useGetAllLesson, useUpdateLessonOrder } from "../../../api/lesson";
const NotFoundLottie = React.lazy(() => import("../../../Components/Lottie/NotFound/NotFoundLottie"));
const LoadingLottie = React.lazy(() => import("../../../Components/Lottie/Loading/LoadingLottie" ));
const NotFoundLottie = React.lazy(
() => import("../../../Components/Lottie/NotFound/NotFoundLottie"),
);
const LoadingLottie = React.lazy(
() => import("../../../Components/Lottie/Loading/LoadingLottie"),
);
import { useTranslation } from "react-i18next";
import { useColumns } from "./useTableColumns";
@ -53,7 +55,6 @@ export const DragHandleLesson: React.FC = () => {
);
};
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
"data-row-key": string;
}
@ -90,14 +91,17 @@ const Row: React.FC<RowProps> = (props) => {
const DrapableTable: React.FC = () => {
const { subject_id } = useParams<ParamsEnum>();
const response = useGetAllLesson({ subject_id: subject_id, pagination: false });
const response = useGetAllLesson({
subject_id: subject_id,
pagination: false,
});
// Assuming the response contains a unique id for each item
const data =
response?.data?.data?.map((item: any, index: number) => ({
id: item.id, // Ensure this is a unique identifier
order: index + 1, // Assign order based on index
...item
...item,
})) ?? [];
const [dataSource, setDataSource] = React.useState<DataType[]>(data);
@ -108,48 +112,48 @@ const DrapableTable: React.FC = () => {
setDataSource(sortedData);
}, [response?.data?.data]);
const {mutate:orderLesson} = useUpdateLessonOrder()
const { mutate: orderLesson } = useUpdateLessonOrder();
const onDragEnd = ({ active, over }: DragEndEvent) => {
if (active.id !== over?.id) {
setDataSource((prevState) => {
const activeIndex = prevState.findIndex(
(record) => record.id === active.id,
);
const overIndex = prevState.findIndex(
//@ts-ignore
//@ts-ignore
(record) => record.id === over.id,
);
// Move the items in the array
const newState = arrayMove(prevState, activeIndex, overIndex);
const orderedNewState = newState.map((item, index) => ({
...item,
order: index + 1, // Update the order based on the new index
}));
const orderedNewState = newState.map((item, index) => ({
...item,
order: index + 1, // Update the order based on the new index
}));
// Update the order based on the new positions
const orderedNewStateWithNewChape = orderedNewState?.map((item:any)=>{
return {
"lesson_id":item?.id,
"order":item?.order
}
})
orderLesson({lessons: orderedNewStateWithNewChape, _method:"PUT"})
return orderedNewState
const orderedNewStateWithNewChape = orderedNewState?.map(
(item: any) => {
return {
lesson_id: item?.id,
order: item?.order,
};
},
);
orderLesson({ lessons: orderedNewStateWithNewChape, _method: "PUT" });
return orderedNewState;
});
}
};
const getRowClassName = (record: any, index: number): string => {
return index % 2 === 0 ? "even-row" : "odd-row";
};
const [t] = useTranslation()
const [t] = useTranslation();
const columns = useColumns();
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order) ;
console.log(sortedDataSource,"sortedDataSource");
const isLoading = response?.isLoading
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order);
console.log(sortedDataSource, "sortedDataSource");
const isLoading = response?.isLoading;
return (
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
<SortableContext
@ -159,32 +163,30 @@ const DrapableTable: React.FC = () => {
<Table
rowKey="id"
components={{ body: { row: Row } }}
//@ts-ignore
//@ts-ignore
columns={columns}
dataSource={sortedDataSource}
dataSource={sortedDataSource}
pagination={false}
rowClassName={(record, index) => getRowClassName(record, index)}
className="DataTable"
loading={{
spinning: isLoading,
indicator:<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense> ,
size: "large",
}}
locale={{
emptyText: (
isLoading ?
<></>
:
<Suspense fallback={<></>}>
<NotFoundLottie
/>
</Suspense>
),
}}
rowClassName={(record, index) => getRowClassName(record, index)}
className="DataTable"
loading={{
spinning: isLoading,
indicator: (
<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense>
),
size: "large",
}}
locale={{
emptyText: isLoading ? (
<></>
) : (
<Suspense fallback={<></>}>
<NotFoundLottie />
</Suspense>
),
}}
/>
</SortableContext>
</DndContext>

View File

@ -43,7 +43,7 @@ const ModalForm: React.FC = () => {
getInitialValues={getInitialValues(objectToEdit)}
getValidationSchema={getValidationSchema}
isAddModal={false}
width="500px"
width="500px"
>
<ModelForm />
</LayoutModel>

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -68,13 +68,15 @@ const TableHeader = () => {
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="lesson"
ModelAbility={ModalEnum?.LESSON_ADD}
canAdd={canAddLesson}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.lesson"/>
<PageHeader
pageTitle="lesson"
ModelAbility={ModalEnum?.LESSON_ADD}
canAdd={canAddLesson}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.lesson"
/>
<Table />
<AddModalForm />
<EditModalForm />

View File

@ -38,7 +38,12 @@ export const useColumns = () => {
const [t] = useTranslation();
const columns: TableColumnsType<Lesson> = [
{ key: "sort", align: "center", width: 80, render: () => <DragHandleLesson /> },
{
key: "sort",
align: "center",
width: 80,
render: () => <DragHandleLesson />,
},
{
title: t("columns.id"),
dataIndex: "id",
@ -55,15 +60,15 @@ export const useColumns = () => {
},
{
// canAddLesson ? (
// <button
// onClick={() => handel_open_model(ModalEnum?.LESSON_ADD)}
// className="add_button"
// >
// {t("practical.add")} {t("models.lesson")} <FaPlus />
// </button>
// ) : (
// ""
// ),
// <button
// onClick={() => handel_open_model(ModalEnum?.LESSON_ADD)}
// className="add_button"
// >
// {t("practical.add")} {t("models.lesson")} <FaPlus />
// </button>
// ) : (
// ""
// ),
title: t("columns.procedure"),
key: "actions",
align: "end",

View File

@ -125,52 +125,52 @@ const AddPage: React.FC = () => {
Questions?.map((item: Question) => {
const tags = processTags(item);
console.log(item);
const answers = item?.answers?.map((item:any,index:number)=>{
const answers = item?.answers?.map((item: any, index: number) => {
return {
order:index,
...item
}
})
order: index,
...item,
};
});
console.log(answers);
mutate({
mutate({
...item,
parent_id: newBseQuestionId,
subject_id: subject_id,
tags,
lessons_ids: [lesson_id],
answers
answers,
});
});
console.log(newBseQuestionId, "newBseQuestionId");
});
} else {
const tags = processTags(DataToSend);
const answers = values?.answers?.map((item:any,index:number)=>{
const answers = values?.answers?.map((item: any, index: number) => {
return {
order:index,
...item
}
})
order: index,
...item,
};
});
const NewQuestion = {
...values,
subject_id: subject_id,
tags,
lessons_ids: [lesson_id],
canAnswersBeShuffled,
answers
}
console.clear()
console.log(NewQuestion,"NewQuestion");
answers,
};
console.clear();
console.log(NewQuestion, "NewQuestion");
mutate(NewQuestion);
}
};
const navigate = useNavigate();
// console.log(SavedQuestionData);
// useEffect(() => {
// if (
// isSuccessAsync &&
@ -191,12 +191,12 @@ const AddPage: React.FC = () => {
// let cleanedAnswers = cleanObject(SavedQuestionData);
// let noChange = hasItems(cleanedAnswers);
// console.log(SavedQuestionData);
// useSaveOnDisconnect(noChange, QUESTION_OBJECT_KEY, SavedQuestionData);
// const SavedData = getLocalStorageQuestions(QUESTION_OBJECT_KEY);
// console.log(SavedData);
const handleCancel = () => {
navigate(-1);
// if (!noChange) {
@ -206,7 +206,7 @@ const AddPage: React.FC = () => {
// }
};
if (isBseQuestion ) {
if (isBseQuestion) {
return (
<div className="exercise_add">
<FormikForm

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -31,31 +31,36 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
<TextField
className="textarea_exercise"
placeholder={"choice"}
label2={t(`input.choice`) + ` ` +`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
label2={
t(`input.choice`) +
` ` +
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
}
name={index}
id={`choice_${index + 1}`}
type="TextArea"
/>
<ImageBoxField name={`answers.${index}.content_image`} />
<div className="answer_status">
<ImageBoxField name={`answers.${index}.content_image`} />
<CheckboxField
className=""
label="The_correct_answer"
name={index}
type="Checkbox"
/>
<p className="delete_question_options">
{t("header.delete_choice")}
<GoTrash className="trash_icon" onClick={handleDeleteChoice} size={17} />
</p>
</div>
<div className="answer_status">
<CheckboxField
className=""
label="The_correct_answer"
name={index}
type="Checkbox"
/>
<p className="delete_question_options">
{t("header.delete_choice")}
<GoTrash
className="trash_icon"
onClick={handleDeleteChoice}
size={17}
/>
</p>
</div>
</div>
<div className="exercise_form_width">
<ValidationField
className=" "
placeholder="_"

View File

@ -37,32 +37,30 @@ const Choices = () => {
<Droppable droppableId="choices">
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{formik?.values?.answers?.map(
(item: Choice, index: number) => {
// Use a unique identifier for draggableId
const draggableId = item.name
? item.name.toString()
: `item-${index}`;
{formik?.values?.answers?.map((item: Choice, index: number) => {
// Use a unique identifier for draggableId
const draggableId = item.name
? item.name.toString()
: `item-${index}`;
return (
<Draggable
key={draggableId}
draggableId={draggableId}
index={index}
>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<ChoiceFields index={index} data={item} />
</div>
)}
</Draggable>
);
},
)}
return (
<Draggable
key={draggableId}
draggableId={draggableId}
index={index}
>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<ChoiceFields index={index} data={item} />
</div>
)}
</Draggable>
);
})}
{provided.placeholder} {/* Placeholder for spacing */}
</div>
)}

View File

@ -106,8 +106,8 @@ const Form = () => {
<Choices parent_index={parent_index} />
{formik?.values?.Questions?.[parent_index]?.answers
?.length < 5 && (
{formik?.values?.Questions?.[parent_index]?.answers?.length <
5 && (
<p className="add_new_button">
<FaCirclePlus
onClick={() => handleAddChoice(parent_index)}

View File

@ -16,10 +16,9 @@ const CheckboxField = ({
const formik = useFormikContext<any>();
const [t] = useTranslation();
const CheckboxhandleChange = (value: any) => {
const allAreZero = formik?.values?.Questions?.[
parent_index
]?.answers?.some((item: any) => item.isCorrect === 1);
const allAreZero = formik?.values?.Questions?.[parent_index]?.answers?.some(
(item: any) => item.isCorrect === 1,
);
if (allAreZero) {
formik?.values?.Questions?.[parent_index]?.answers.forEach(
(item: any, index: number) => {

View File

@ -27,8 +27,7 @@ const ChoiceFields = ({
const [t] = useTranslation();
const handleDeleteChoice = () => {
const arrayLength =
formik.values.Questions?.[parent_index].answers?.length;
const arrayLength = formik.values.Questions?.[parent_index].answers?.length;
console.log(arrayLength);
@ -42,46 +41,49 @@ const ChoiceFields = ({
const updatedAnswers = formik.values.Questions?.[
parent_index
].answers.filter((_: any, i: any) => i !== index);
formik.setFieldValue(
`Questions[${parent_index}].answers`,
updatedAnswers,
);
formik.setFieldValue(`Questions[${parent_index}].answers`, updatedAnswers);
};
return (
<>
<div className="ChoiceFields">
<TextField
className="textarea_exercise"
placeholder={"choice"}
label2={t(`input.choice`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
name={index}
parent_index={parent_index}
type="TextArea"
/>
<>
<div className="ChoiceFields">
<TextField
className="textarea_exercise"
placeholder={"choice"}
label2={
t(`input.choice`) +
` ` +
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
}
name={index}
parent_index={parent_index}
type="TextArea"
/>
<ImageBoxField name={`Questions.${parent_index}.answers.${index}.answer_image`} />
<div className="answer_status">
<ImageBoxField
name={`Questions.${parent_index}.answers.${index}.answer_image`}
/>
<CheckboxField
className=""
label="The_correct_answer"
name={index}
type="Checkbox"
parent_index={parent_index}
/>
<p className="delete_question_options">
{t("header.delete_choice")}
<GoTrash className="trash_icon" onClick={handleDeleteChoice} size={17} />
</p>
</div>
</div>
<div className="answer_status">
<CheckboxField
className=""
label="The_correct_answer"
name={index}
type="Checkbox"
parent_index={parent_index}
/>
<p className="delete_question_options">
{t("header.delete_choice")}
<GoTrash
className="trash_icon"
onClick={handleDeleteChoice}
size={17}
/>
</p>
</div>
</div>
<div className="exercise_form_width">
<ValidationField
<div className="exercise_form_width">
<ValidationField
className=" "
placeholder="_"
name={`Questions.${parent_index}.answers.${index}.hint`}
@ -89,8 +91,8 @@ const ChoiceFields = ({
type="text"
style={{ width: "100%" }}
/>
</div>
</>
</div>
</>
);
};

View File

@ -10,14 +10,16 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
const handleDragEnd = (result: any) => {
// Check if the item was dropped outside the list
console.log(1);
console.log(result.destination);
console.log(result.destination);
if (!result.destination) return;
console.log(formik?.values?.Questions?.[parent_index]?.answers);
// Create a new array from the current answers
const items = Array.from(formik?.values?.Questions?.[parent_index]?.answers);
const items = Array.from(
formik?.values?.Questions?.[parent_index]?.answers,
);
console.log(items);
// Remove the item from the original position
const [reorderedItem] = items.splice(result.source.index, 1);
@ -26,8 +28,8 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
items.splice(result.destination.index, 0, reorderedItem);
// Update the order keys based on the new indices
console.log(items,"items");
console.log(items, "items");
const updatedItems = items.map((item, index) => ({
...(item ?? {}),
order: index + 1, // Update order to be 1-based index
@ -46,8 +48,8 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{(
(formik?.values as any)?.Questions?.[parent_index]
?.answers || []
(formik?.values as any)?.Questions?.[parent_index]?.answers ||
[]
).map((item: Choice, index: number) => {
const draggableId = item.name
? item.name.toString()

View File

@ -17,8 +17,8 @@ const File = ({
const { formik, t, isError, errorMsg } = useFormField(newName, props);
let imageUrl =
formik?.values?.Questions?.[parent_index]?.answers[name]
?.answer_image ?? null;
formik?.values?.Questions?.[parent_index]?.answers[name]?.answer_image ??
null;
// console.log(imageUrl);
const fileList: UploadFile[] = useMemo(() => {

View File

@ -28,9 +28,9 @@ const HintField = ({
return (
<div className={`ValidationField w-100 ${className ?? ""} `}>
<label htmlFor={name} className="text">
{label2 ? label2 : t(`input.${label ? label : name}`)}
</label>
<label htmlFor={name} className="text">
{label2 ? label2 : t(`input.${label ? label : name}`)}
</label>
<Form.Item
hasFeedback
validateStatus={isError ? "error" : ""}

View File

@ -102,8 +102,8 @@ const Form = () => {
</div>
{(
(formik?.values as any)?.Questions?.[parent_index]
?.answers || []
(formik?.values as any)?.Questions?.[parent_index]?.answers ||
[]
).map((item: Choice, index: number) => {
return (
<ChoiceFields
@ -114,8 +114,8 @@ const Form = () => {
/>
);
})}
{formik?.values?.Questions?.[parent_index]?.answers
?.length < 5 && (
{formik?.values?.Questions?.[parent_index]?.answers?.length <
5 && (
<p className="add_new_button">
<FaCirclePlus
onClick={() => handleAddChoice(parent_index)}

View File

@ -72,9 +72,13 @@ const Form = () => {
return (
<Row className="w-100 exercise_form_container">
<div className="exercise_form">
<ValidationField className="textarea_exercise" name="content" label="main_question" type="TextArea" />
<ImageBoxField name="image" />
<ValidationField
className="textarea_exercise"
name="content"
label="main_question"
type="TextArea"
/>
<ImageBoxField name="image" />
<div></div>
</div>
@ -94,8 +98,8 @@ const Form = () => {
<Choices parent_index={parent_index} />
{formik?.values?.Questions?.[parent_index]?.answers
?.length < 5 && (
{formik?.values?.Questions?.[parent_index]?.answers?.length <
5 && (
<p className="add_new_button">
<FaCirclePlus
onClick={() => handleAddChoice(parent_index)}
@ -105,19 +109,17 @@ const Form = () => {
</p>
)}
<div className="exercise_form_width">
<ValidationField
className=" "
placeholder="_"
name={`answers.${parent_index}.hint`}
label="hint_question"
type="text"
style={{ width: "100%" }}
/>
<MaltySelectTag parent_index={parent_index} />
</div>
<div className="exercise_form_width">
<ValidationField
className=" "
placeholder="_"
name={`answers.${parent_index}.hint`}
label="hint_question"
type="text"
style={{ width: "100%" }}
/>
<MaltySelectTag parent_index={parent_index} />
</div>
</div>
);
},

View File

@ -23,12 +23,12 @@ const HintField = ({
// console.log('Change:', e.target.value);
formik.setFieldValue(newName, e.target.value);
};
return (
<div className={`ValidationField w-100 ${className ?? ""} `}>
<label htmlFor={name} className="text">
{label2 ? label2 : t(`input.${label ? label : name}`)}
</label>
<label htmlFor={name} className="text">
{label2 ? label2 : t(`input.${label ? label : name}`)}
</label>
<Form.Item
hasFeedback
validateStatus={isError ? "error" : ""}

View File

@ -36,34 +36,35 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
return (
<>
<div className="exercise_forms">
<div className="ChoiceFields">
<TextField
className="textarea_exercise"
placeholder={"question"}
label2={t(`input.question`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
name={index}
id={`question_${index + 1}`}
type="TextArea"
/>
<div className="exercise_forms">
<div className="ChoiceFields">
<TextField
className="textarea_exercise"
placeholder={"question"}
label2={
t(`input.question`) +
` ` +
`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`
}
name={index}
id={`question_${index + 1}`}
type="TextArea"
/>
<ImageBoxField name={`Questions.${index}.image`} />
<div className="answer_status">
<p className="delete_question_options">
{t("header.delete_question")}
<GoTrash className="trash_icon" onClick={handleDeleteQuestion} size={17} />
</p>
<ImageBoxField name={`Questions.${index}.image`} />
<div className="answer_status">
<p className="delete_question_options">
{t("header.delete_question")}
<GoTrash
className="trash_icon"
onClick={handleDeleteQuestion}
size={17}
/>
</p>
</div>
</div>
</div>
</div>
</>
);
};

View File

@ -1,35 +1,32 @@
import React, { useState, useMemo } from 'react';
import { Select, Spin } from 'antd';
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { useDebounce } from '../../../../../../utils/useDebounce';
import { useGetAllTag } from '../../../../../../api/tags';
import React, { useState, useMemo } from "react";
import { Select, Spin } from "antd";
import { useTranslation } from "react-i18next";
import { useFormikContext } from "formik";
import { useDebounce } from "../../../../../../utils/useDebounce";
import { useGetAllTag } from "../../../../../../api/tags";
const MaltySelectTag = ({parent_index}:{parent_index:number}) => {
const [searchValue, setSearchValue] = useState<string>('');
const [fieldValue, setFieldValue] = useState<string>('');
const MaltySelectTag = ({ parent_index }: { parent_index: number }) => {
const [searchValue, setSearchValue] = useState<string>("");
const [fieldValue, setFieldValue] = useState<string>("");
const formik = useFormikContext<any>();
const values = formik?.values?.Questions?.[parent_index]?.tags;
const handleChange = (value: string[]) => {
formik.setFieldValue(`Questions.[${parent_index}].tags`,value)
setSearchValue('');
setFieldValue('');
formik.setFieldValue(`Questions.[${parent_index}].tags`, value);
setSearchValue("");
setFieldValue("");
};
const handleSearch = useDebounce((value: string) => {
setSearchValue(value);
});
const handleFieldChange = (value: string) => {
setFieldValue(value);
};
const handleBlur = () => {
setSearchValue('');
setFieldValue('');
setSearchValue("");
setFieldValue("");
};
const { data, isLoading } = useGetAllTag({
@ -38,38 +35,38 @@ const MaltySelectTag = ({parent_index}:{parent_index:number}) => {
const [t] = useTranslation();
const options = data?.data ?? []
const additionalData = options?.length < 1 && searchValue.length > 1 && !isLoading ? [{id:`new_${searchValue}`,name:searchValue}] :[];
const options = data?.data ?? [];
const additionalData =
options?.length < 1 && searchValue.length > 1 && !isLoading
? [{ id: `new_${searchValue}`, name: searchValue }]
: [];
return (
<div className='SelectTag'>
<label htmlFor="">
{t("models.tag")}
</label>
<Select
mode="multiple"
allowClear
style={{ width: '100%' ,height:"40px"}}
placeholder=""
fieldNames={{ label: 'name', value: 'id' }}
onChange={handleChange}
options={[...options,...additionalData]}
filterOption={false}
loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
onSearch={(value) => {
handleSearch(value);
handleFieldChange(value);
}}
searchValue={fieldValue}
onDropdownVisibleChange={(open) => {
if (!open) {
handleBlur();
}
}}
value={values ?? []}
/>
<div className="SelectTag">
<label htmlFor="">{t("models.tag")}</label>
<Select
mode="multiple"
allowClear
style={{ width: "100%", height: "40px" }}
placeholder=""
fieldNames={{ label: "name", value: "id" }}
onChange={handleChange}
options={[...options, ...additionalData]}
filterOption={false}
loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
onSearch={(value) => {
handleSearch(value);
handleFieldChange(value);
}}
searchValue={fieldValue}
onDropdownVisibleChange={(open) => {
if (!open) {
handleBlur();
}
}}
value={values ?? []}
/>
</div>
);
};

View File

@ -26,8 +26,8 @@ const Form = () => {
}, [Success]);
useEffect(() => {
console.log(formik.values,"formik.values");
console.log(formik.values, "formik.values");
setSavedQuestionData(formik.values);
}, [formik?.values]);
@ -42,15 +42,20 @@ const Form = () => {
]);
};
console.log(formik?.values);
console.log(formik?.values);
return (
<Row className="w-100 exercise_form_container">
<div className="exercise_form">
<ValidationField className="textarea_exercise" name="content" label="answer_content" type="TextArea" />
<ValidationField
className="textarea_exercise"
name="content"
label="answer_content"
type="TextArea"
/>
<ImageBoxField name="content_image" />
</div>
<Choices />
{formik?.values?.answers?.length < 5 && (
<p className="add_new_button">
@ -60,8 +65,7 @@ const Form = () => {
)}
<div className="exercise_form_width">
<ValidationField
<ValidationField
className=" "
placeholder="_"
name="hint"

View File

@ -8,7 +8,7 @@ export const getInitialValues = (objectToEdit: Question): any => {
return { ...item, key: index };
});
console.log(objectToEdit);
return {
id: objectToEdit?.id ?? null,
content: objectToEdit?.content ?? "",
@ -47,7 +47,7 @@ export const getInitialValuesBase = (objectToEdit: Question): any => {
name: tag?.name,
key: `${tag?.id}_key_${tag?.name}`,
}));
return {
...item,
canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ? 1 : 0,
@ -96,7 +96,7 @@ export const getValidationSchemaBase = () => {
export function processTags(DataToSend: any) {
console.log(DataToSend?.tags);
const oldTags = DataToSend?.tags
?.map((item: any, index: number) => {
if (typeof item === "number") {
@ -108,16 +108,16 @@ export function processTags(DataToSend: any) {
const newTags = DataToSend?.tags
?.map((item: any, index: number) => {
console.log(item);
if (typeof item === "string" && item !== "") {
console.log(item);
return { name: item };
}
})
.filter((item: any) => item !== undefined);
console.log(newTags);
console.log(oldTags);
console.log(newTags);
console.log(oldTags);
return { new: newTags, old: oldTags };
}

View File

@ -74,15 +74,17 @@ const TableHeader = () => {
return (
<div className="TableWithHeader">
<Suspense fallback={<Spin />}>
<PageHeader
pageTitle="question"
ModelAbility={ModalEnum?.QUESTION_ACCEPT}
canAdd={canAddQuestion}
locationToNavigate={`${ABILITIES_ENUM?.QUESTION}/add`}
openModel={false}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.question"/>
<PageHeader
pageTitle="question"
ModelAbility={ModalEnum?.QUESTION_ACCEPT}
canAdd={canAddQuestion}
locationToNavigate={`${ABILITIES_ENUM?.QUESTION}/add`}
openModel={false}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.question"
/>
<Table />
</Suspense>
<DeleteModels

View File

@ -67,12 +67,12 @@ export const useColumns = () => {
render: (text, record) =>
record?.canAnswersBeShuffled ? t("practical.yes") : t("practical.no"),
},
{
title: '#',
title: "#",
key: "actions",
align: "center",
render: (_text, record, index) => {
return (
<ActionButtons

View File

@ -1,5 +1,5 @@
import React from 'react'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import React from "react";
import ValidationField from "../../../../Components/ValidationField/ValidationField";
import { Col, Row } from "reactstrap";
const FilterForm = () => {
@ -7,19 +7,16 @@ const FilterForm = () => {
<div>
<Row>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
<Col>
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
<ValidationField placeholder="name" label="name" name="name" />
</Col>
</Row>
</div>
)
}
);
};
export default FilterForm
export default FilterForm;

View File

@ -42,13 +42,15 @@ const TableWithHeader = () => {
return (
<div className="TableWithHeader">
<PageHeader
pageTitle="subjects"
ModelAbility={ModalEnum?.SUBJECT_ADD}
canAdd={canAddSubject}/>
<FilterLayout
sub_children={<FilterForm/>}
filterTitle="sidebar.subjects"/>
<PageHeader
pageTitle="subjects"
ModelAbility={ModalEnum?.SUBJECT_ADD}
canAdd={canAddSubject}
/>
<FilterLayout
sub_children={<FilterForm />}
filterTitle="sidebar.subjects"
/>
<Table />
<AddModalForm />

View File

@ -7,7 +7,11 @@ import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import ActionButtons from "../../../../Components/Table/ActionButtons";
import { canDeleteSubject, canEditSubject, canShowSubject } from "../../../../utils/hasAbilityFn";
import {
canDeleteSubject,
canEditSubject,
canShowSubject,
} from "../../../../utils/hasAbilityFn";
import { ABILITIES_ENUM } from "../../../../enums/abilities";
import { Subject } from "../../../../types/Subject";

View File

@ -55,11 +55,7 @@ const FormField = ({ isLoading }: FormFieldType) => {
/>
</div>
<button
disabled={isLoading}
type="submit"
className="auth_submit_button"
>
<button disabled={isLoading} type="submit" className="auth_submit_button">
{t("practical.login")}
</button>
</Form>

View File

@ -19,26 +19,23 @@ const LoginForm = () => {
};
const { login } = useAuthState();
const LoginData = {
...data,
} as any;
const LocalType = getLocalStorage(USER_KEY)?.type ?? false ;
const LocalType = getLocalStorage(USER_KEY)?.type ?? false;
useEffect(() => {
if(isSuccess){
login(LoginData?.data as any)
if (isSuccess) {
login(LoginData?.data as any);
}
}, [isSuccess])
useEffect(() => {
if(LocalType ){
window.location.href = ("/")
}
}, [LocalType])
}, [isSuccess]);
useEffect(() => {
if (LocalType) {
window.location.href = "/";
}
}, [LocalType]);
return (
<div className="LoginForm">

View File

@ -9,7 +9,7 @@ const Auth = () => {
<div className="Auth">
<div className="In_Auth">
{/* <header> */}
{/* <h1>{t("header.Welcome")}</h1>
{/* <h1>{t("header.Welcome")}</h1>
<p>{t("header.Enter your email and password to log in")}</p> */}
{/* </header> */}
<LoginForm />

View File

@ -7,11 +7,7 @@ const Dummy = () => {
const [t] = useTranslation();
useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
return (
<div className="DummyHomePage">
</div>
);
return <div className="DummyHomePage"></div>;
};
export default Dummy;

View File

@ -12,8 +12,12 @@ const Unit = React.lazy(() => import("./Pages/Admin/Unit/Page"));
const Lesson = React.lazy(() => import("./Pages/Admin/lesson/Page"));
const Question = React.lazy(() => import("./Pages/Admin/question/Page"));
const AddQuestionPage = React.lazy(() => import("./Pages/Admin/question/AddPage"));
const EditQuestionPage = React.lazy(() => import("./Pages/Admin/question/EditPage"));
const AddQuestionPage = React.lazy(
() => import("./Pages/Admin/question/AddPage"),
);
const EditQuestionPage = React.lazy(
() => import("./Pages/Admin/question/EditPage"),
);
const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
const Student = React.lazy(() => import("./Pages/Admin/Student/Page"));
@ -27,7 +31,7 @@ export const menuItems: TMenuItem[] = [
{
header: "page_header.dashboard",
element: <Dummy />,
icon: <TbCategory />,
icon: <TbCategory />,
text: "sidebar.dashboard",
path: "/",
abilities: ABILITIES_ENUM?.PASS,

View File

@ -48,7 +48,6 @@
}
}
.pagination_antd{
.pagination_antd {
margin-inline: 16px !important;
}
}

Some files were not shown because too many files have changed in this diff Show More