Compare commits

..

3 Commits

Author SHA1 Message Date
karimaldeen
251359e935 add validation question 2024-09-16 12:34:01 +03:00
karimaldeen
458319b49f fix page 2024-09-16 12:14:19 +03:00
karimaldeen
0b44bc69fb fix image 2mb and add delete ask 2024-09-16 12:01:35 +03:00
20 changed files with 244 additions and 50 deletions

View File

@ -5,6 +5,7 @@ import ImageIcon from "./ImageIcon";
import ImageCancelIcon from "./ImageCancelIcon"; import ImageCancelIcon from "./ImageCancelIcon";
import { getNestedValue } from "../../../utils/getNestedValue"; import { getNestedValue } from "../../../utils/getNestedValue";
import { generateImagePreview } from "./generateImagePreview"; import { generateImagePreview } from "./generateImagePreview";
import { useTranslation } from "react-i18next";
// Helper function to generate image preview from a File // Helper function to generate image preview from a File
@ -13,7 +14,7 @@ const ImageBoxField = ({ name }: any) => {
const value = getNestedValue(formik?.values, name); const value = getNestedValue(formik?.values, name);
const [imagePreview, setImagePreview] = useState<string | null>(null); const [imagePreview, setImagePreview] = useState<string | null>(null);
const fileInputRef = useRef<HTMLInputElement | null>(null); const fileInputRef = useRef<HTMLInputElement | null>(null);
const [t] = useTranslation()
useEffect(() => { useEffect(() => {
if (value instanceof File) { if (value instanceof File) {
generateImagePreview(value, setImagePreview); generateImagePreview(value, setImagePreview);
@ -26,6 +27,19 @@ const ImageBoxField = ({ name }: any) => {
const handleFileChange = (event: any) => { const handleFileChange = (event: any) => {
const file = event.target.files[0]; const file = event.target.files[0];
if (file) {
const maxSize = 2 * 1024 * 1024;
if (file.size > maxSize) {
alert(t('validation.File_size_exceeds_2_MB_limit.'));
event.target.value = '';
return;
}
// Process the file
console.log('File selected:', file);
}
if (file) { if (file) {
generateImagePreview(file, setImagePreview); generateImagePreview(file, setImagePreview);
formik.setFieldValue(name, file); formik.setFieldValue(name, file);

View File

@ -1,14 +1,62 @@
import React from "react"; import React, { useCallback, useState } from "react";
import '../styles/index.scss';
import CustomInput from "../design-system/CustomInput";
import { Button } from "antd";
import { useTranslation } from "react-i18next";
interface IFilterBody { interface IFilterBody {
children: React.ReactNode; children: React.ReactNode;
} }
const useFilter = () => { const useFilter = () => {
const FilterButton = () => { const [isBodyVisible, setIsBodyVisible] = useState(true);
return <div>FilterButton</div>;
const toggleBodyVisibility = () => {
setIsBodyVisible((prev) => !prev);
}; };
const FilterButton = () => {
return (
<button onClick={toggleBodyVisibility}>
{isBodyVisible ? "Hide Filter" : "Show Filter"}
</button>
);
};
const FilterBody = ({ children }: IFilterBody) => { const FilterBody = ({ children }: IFilterBody) => {
return <div>FilterBody</div>; const [values, setValues] = useState({ name1: '', name2: '' });
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setValues((prev) => ({ ...prev, [name]: value }));
}, []);
const handleSubmit = (event:React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log(values,"values");
};
const [t] = useTranslation()
return (
<div className={`filter_body ${isBodyVisible ? 'visible' : 'hidden'}`}>
<form onSubmit={handleSubmit} >
{children}
<CustomInput
name="name1"
value={values.name1}
onChange={handleChange}
/>
<CustomInput
name="name2"
value={values.name2}
onChange={handleChange}
/>
<Button block htmlType="submit" type="primary" > {t("practical.submit")} </Button>
</form>
</div>
);
}; };
return { return {

View File

@ -0,0 +1,22 @@
import { Input } from 'antd';
import React from 'react';
interface CustomInputProps {
name: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}
const CustomInput: React.FC<CustomInputProps> = React.memo(({ name, value, onChange }) => {
console.log(`Rendering ${name}`); // For debugging purposes
return (
<Input
type="text"
name={name}
value={value}
onChange={onChange}
/>
);
});
export default CustomInput;

View File

@ -0,0 +1,33 @@
.filter_body {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out, opacity 0.3s ease-out, transform 0.3s ease-out;
opacity: 0;
transform: translateY(-20px);
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.filter_body.visible {
max-height: 200px;
opacity: 1;
transform: translateY(0);
}
.filter_body.hidden {
max-height: 0;
opacity: 0;
transform: translateY(-20px);
}
.DummyHomePage {
display: flex;
flex-direction: column;
align-items: center;
gap: 40px;
width: 70%;
padding: 50px;
}

View File

@ -37,19 +37,14 @@ interface FormikFormProps extends Omit<FormikConfig<any>, OmitFormikProps> {
setIsOpen: any; setIsOpen: any;
} }
interface SubmitButtonProps extends Omit<ButtonProps, "loading"> {}
const useFilter = () => { const useFilter = () => {
const { setIsOpen, isOpen } = useModalState((state) => state); const { setIsOpen, isOpen } = useModalState((state) => state);
const { filterState, setFilterState, clearFilterState } = useFilterState(); const { filterState, setFilterState, clearFilterState } = useFilterState();
const [t] = useTranslation(); const [t] = useTranslation();
const [formValues, setFormValues] = useState({}); const [formValues, setFormValues] = useState({});
const formik = useFormikContext();
// Define the type for the callback // Define the type for the callback
type SubmitCallback = () => void; type SubmitCallback = () => void;
// console.log(formik?.values);
// console.log(InitialValue);
const FilterButton = () => { const FilterButton = () => {
const handleState = () => { const handleState = () => {
if (isOpen === ModalEnum?.FILTER) { if (isOpen === ModalEnum?.FILTER) {

View File

@ -48,6 +48,18 @@ const File = ({
const customRequest = async ({ onSuccess, no_label, label_icon }: any) => { const customRequest = async ({ onSuccess, no_label, label_icon }: any) => {
onSuccess(); onSuccess();
}; };
const beforeUpload = (file: File) => {
const maxSize = 2 * 1024 * 1024; // 2 MB in bytes
if (file.size > maxSize) {
alert(t('validation.File_size_exceeds_2_MB_limit.'));
return Upload.LIST_IGNORE; // Prevent the file from being uploaded
}
return true; // Allow the file to be uploaded
};
return ( return (
<div className={`ValidationField upload_image_button ${className ?? ""} `}> <div className={`ValidationField upload_image_button ${className ?? ""} `}>
<label htmlFor={name} className="text"> <label htmlFor={name} className="text">
@ -55,6 +67,7 @@ const File = ({
</label> </label>
<Upload <Upload
beforeUpload={beforeUpload} // Set the beforeUpload function
disabled={isDisabled} disabled={isDisabled}
listType="picture" listType="picture"
maxCount={1} maxCount={1}
@ -63,6 +76,7 @@ const File = ({
customRequest={customRequest} customRequest={customRequest}
className={` w-100`} className={` w-100`}
id={name} id={name}
> >
<Button <Button
className={isError ? "isError w-100 " : " w-100"} className={isError ? "isError w-100 " : " w-100"}

View File

@ -24,8 +24,6 @@ const DeleteModels: React.FC<ModalFormProps> = ({
const { mutate, isLoading, isSuccess } = deleteMutation; const { mutate, isLoading, isSuccess } = deleteMutation;
const { objectToEdit, setObjectToEdit } = useObjectToEdit(); const { objectToEdit, setObjectToEdit } = useObjectToEdit();
console.log(objectToEdit?.key);
console.log(inputValue);
const iaDisabled = idVerify const iaDisabled = idVerify
? Number(objectToEdit?.id) !== Number(inputValue) || isLoading ? Number(objectToEdit?.id) !== Number(inputValue) || isLoading

View File

@ -15,16 +15,20 @@ import {
import ActionButtons from "../../../Components/Table/ActionButtons"; import ActionButtons from "../../../Components/Table/ActionButtons";
import ColumnsImage from "../../../Components/Columns/ColumnsImage"; import ColumnsImage from "../../../Components/Columns/ColumnsImage";
import { Grade } from "../../../types/Grade"; import { Grade } from "../../../types/Grade";
import { CiImageOff } from "react-icons/ci"; import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
import { isValidImage } from "../../../utils/isValidImage"; import { useFilterStateState } from "../../../zustand/Filter";
export const useColumns = () => { export const useColumns = () => {
const { handel_open_model } = useModalHandler(); const { handel_open_model } = useModalHandler();
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate(); const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handelShow = (record: Grade) => { const handelShow = (record: Grade) => {
setFilter({})
navigate(`${record?.id}`); navigate(`${record?.id}`);
}; };

View File

@ -11,11 +11,13 @@ import {
canEditQuestion, canEditQuestion,
} from "../../../utils/hasAbilityFn"; } from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons"; import ActionButtons from "../../../Components/Table/ActionButtons";
import { useFilterStateState } from "../../../zustand/Filter";
export const useColumns = () => { export const useColumns = () => {
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate(); const navigate = useNavigate();
const { setIsOpen } = useModalState((state) => state); const { setIsOpen } = useModalState((state) => state);
const { setFilter } = useFilterStateState();
const handelDelete = (data: any) => { const handelDelete = (data: any) => {
setObjectToEdit(data); setObjectToEdit(data);
@ -28,6 +30,8 @@ export const useColumns = () => {
const unit = lesson?.unit; const unit = lesson?.unit;
const subject = unit?.subject; const subject = unit?.subject;
const grade = subject?.grade; const grade = subject?.grade;
setFilter({})
navigate(`/${ABILITIES_ENUM?.GRADE}/${grade?.id}/${ABILITIES_ENUM?.SUBJECT}/${subject?.id}/${ABILITIES_ENUM?.UNIT}/${unit?.id}/${ABILITIES_ENUM?.LESSON}/${lesson?.id}/${ABILITIES_ENUM?.QUESTION}/${record?.id}`); navigate(`/${ABILITIES_ENUM?.GRADE}/${grade?.id}/${ABILITIES_ENUM?.SUBJECT}/${subject?.id}/${ABILITIES_ENUM?.UNIT}/${unit?.id}/${ABILITIES_ENUM?.LESSON}/${lesson?.id}/${ABILITIES_ENUM?.QUESTION}/${record?.id}`);
}; };
const [t] = useTranslation(); const [t] = useTranslation();

View File

@ -19,14 +19,18 @@ import ActionButtons from "../../../Components/Table/ActionButtons";
import { Unit } from "../../../types/Unit"; import { Unit } from "../../../types/Unit";
import { ConvertEnumToTranslate } from "../../../utils/ConvertEnumToTranslate"; import { ConvertEnumToTranslate } from "../../../utils/ConvertEnumToTranslate";
import { DragHandleUnit } from "./DrapableTable"; import { DragHandleUnit } from "./DrapableTable";
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
import { useFilterStateState } from "../../../zustand/Filter";
export const useColumns = () => { export const useColumns = () => {
const { handel_open_model } = useModalHandler(); const { handel_open_model } = useModalHandler();
const { setFilter } = useFilterStateState();
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate(); const navigate = useNavigate();
const handelShow = (record: Unit) => { const handelShow = (record: Unit) => {
setFilter({})
navigate(`${ABILITIES_ENUM?.UNIT}/${record?.id}`); navigate(`${ABILITIES_ENUM?.UNIT}/${record?.id}`);
}; };

View File

@ -15,14 +15,18 @@ import {
} from "../../../utils/hasAbilityFn"; } from "../../../utils/hasAbilityFn";
import ActionButtons from "../../../Components/Table/ActionButtons"; import ActionButtons from "../../../Components/Table/ActionButtons";
import { DragHandleLesson } from "./DrapableTable"; import { DragHandleLesson } from "./DrapableTable";
import { useFilterState } from "../../../Components/Utils/Filter/FilterState";
import { useFilterStateState } from "../../../zustand/Filter";
export const useColumns = () => { export const useColumns = () => {
const { handel_open_model } = useModalHandler(); const { handel_open_model } = useModalHandler();
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const navigate = useNavigate(); const navigate = useNavigate();
const { setFilter } = useFilterStateState();
const handelShow = (record: any) => { const handelShow = (record: any) => {
setFilter({})
navigate(`${ABILITIES_ENUM.LESSON}/${record?.id}`); navigate(`${ABILITIES_ENUM.LESSON}/${record?.id}`);
}; };

View File

@ -26,7 +26,7 @@ const AddPage: React.FC = () => {
const { mutateAsync,isLoading:LoadingAsync } = useAddQuestionAsync(); const { mutateAsync,isLoading:LoadingAsync } = useAddQuestionAsync();
const { mutate, isLoading, isSuccess } = useAddQuestion(); const { mutate, isLoading, isSuccess } = useAddQuestion();
const { isBseQuestion, setTagsSearch, objectToEdit, setSuccess } = const { isBseQuestion, setTagsSearch, setSuccess } =
useObjectToEdit(); useObjectToEdit();
const [t] = useTranslation(); const [t] = useTranslation();
@ -35,7 +35,6 @@ const AddPage: React.FC = () => {
const handleSubmit = ( values: any) => { const handleSubmit = ( values: any) => {
const DataToSend = structuredClone(values); const DataToSend = structuredClone(values);
setTagsSearch(null); setTagsSearch(null);
console.log(1);
const canAnswersBeShuffled = DataToSend?.canAnswersBeShuffled ? 1 : 0; const canAnswersBeShuffled = DataToSend?.canAnswersBeShuffled ? 1 : 0;
@ -64,12 +63,7 @@ const AddPage: React.FC = () => {
...item, ...item,
}; };
}); });
console.log(answers);
if (answers?.length > 0) {
const isValidAnswers = answers?.some(
(answer: any) => answer?.isCorrect === 1,
);
}
mutate({ mutate({
...item, ...item,
parent_id: newBseQuestionId, parent_id: newBseQuestionId,
@ -82,8 +76,6 @@ const AddPage: React.FC = () => {
console.log(newBseQuestionId, "newBseQuestionId"); console.log(newBseQuestionId, "newBseQuestionId");
}); });
} else { } else {
console.log(1);
const tags = processTags(DataToSend); const tags = processTags(DataToSend);
const answers = values?.answers?.map((item: any, index: number) => { const answers = values?.answers?.map((item: any, index: number) => {
return { return {
@ -112,6 +104,8 @@ const AddPage: React.FC = () => {
const handleValidateSingleQuestion = (values:any)=>{ const handleValidateSingleQuestion = (values:any)=>{
const haveMoreThanOneAnswer = values?.answers?.length > 1; const haveMoreThanOneAnswer = values?.answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true ) const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true )
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
if(!haveMoreThanOneAnswer){ if(!haveMoreThanOneAnswer){
toast.error(t("validation.it_should_have_more_than_one_answers")) ; toast.error(t("validation.it_should_have_more_than_one_answers")) ;
return false ; return false ;
@ -120,6 +114,10 @@ const AddPage: React.FC = () => {
toast.error(t("validation.it_should_have_more_than_one_correct_answers")) ; toast.error(t("validation.it_should_have_more_than_one_correct_answers")) ;
return false ; return false ;
} }
if(haveImageOrContent){
toast.error("validation.one_of_image_and_content_should_be_enter")
return false
}
} }
@ -128,9 +126,9 @@ const AddPage: React.FC = () => {
const answers = Question?.answers; const answers = Question?.answers;
const haveAnswers = answers?.length > 0; const haveAnswers = answers?.length > 0;
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1; const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
const haveOneAnswerRight = const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true); const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
if (!haveAnswers) { if (!haveAnswers) {
toast.error(t("validation.it_should_have_more_than_one_answers")); toast.error(t("validation.it_should_have_more_than_one_answers"));
return false; return false;
@ -145,6 +143,11 @@ const AddPage: React.FC = () => {
toast.error(t("validation.it_should_have_more_than_one_correct_answers")); toast.error(t("validation.it_should_have_more_than_one_correct_answers"));
return false; return false;
} }
if(haveImageOrContent){
toast.error("validation.one_of_image_and_content_should_be_enter")
return false
}
return true; return true;
}); });

View File

@ -8,6 +8,7 @@ import CheckboxField from "./CheckboxField";
import TextField from "./TextField"; import TextField from "./TextField";
import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField"; import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import { GoTrash } from "react-icons/go"; import { GoTrash } from "react-icons/go";
import { Popconfirm } from "antd";
const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => { const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
@ -51,7 +52,16 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
name={index} name={index}
type="Checkbox" type="Checkbox"
/> />
<p className="delete_question_options" onClick={handleDeleteChoice}>
<Popconfirm
title={t("header.this_will_un_do_all_your_changes")}
okText={t("practical.yes")}
cancelText={t("practical.no")}
onConfirm={()=>{handleDeleteChoice()}}
defaultOpen={false}
>
<p className="delete_question_options">
{t("header.delete_choice")} {t("header.delete_choice")}
<GoTrash <GoTrash
className="trash_icon" className="trash_icon"
@ -59,6 +69,10 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
size={17} size={17}
/> />
</p> </p>
</Popconfirm>
</div> </div>
</div> </div>
<div className="exercise_form_width"> <div className="exercise_form_width">

View File

@ -9,6 +9,7 @@ import TextField from "./TextField";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField"; import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import { GoTrash } from "react-icons/go"; import { GoTrash } from "react-icons/go";
import { Popconfirm } from "antd";
const ChoiceFields = ({ const ChoiceFields = ({
index, index,
@ -69,7 +70,16 @@ const ChoiceFields = ({
type="Checkbox" type="Checkbox"
parent_index={parent_index} parent_index={parent_index}
/> />
<p className="delete_question_options" onClick={handleDeleteChoice}>
<Popconfirm
title={t("header.this_will_un_do_all_your_changes")}
okText={t("practical.yes")}
cancelText={t("practical.no")}
onConfirm={()=>{handleDeleteChoice()}}
defaultOpen={false}
>
<p className="delete_question_options" >
{t("header.delete_choice")} {t("header.delete_choice")}
<GoTrash <GoTrash
className="trash_icon" className="trash_icon"
@ -77,6 +87,8 @@ const ChoiceFields = ({
size={17} size={17}
/> />
</p> </p>
</Popconfirm>
</div> </div>
</div> </div>

View File

@ -7,6 +7,7 @@ import TextField from "./TextField";
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField"; import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import { GoTrash } from "react-icons/go"; import { GoTrash } from "react-icons/go";
import { Popconfirm } from "antd";
const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => { const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
@ -47,7 +48,15 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
<ImageBoxField name={`Questions.${index}.content_image`} /> <ImageBoxField name={`Questions.${index}.content_image`} />
<div className="answer_status" onClick={handleDeleteQuestion}> <div className="answer_status" >
<Popconfirm
title={t("header.this_will_un_do_all_your_changes")}
okText={t("practical.yes")}
cancelText={t("practical.no")}
onConfirm={()=>{handleDeleteQuestion()}}
defaultOpen={false}
>
<p className="delete_question_options"> <p className="delete_question_options">
{t("header.delete_question")} {t("header.delete_question")}
<GoTrash <GoTrash
@ -56,7 +65,10 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
size={17} size={17}
/> />
</p> </p>
</Popconfirm>
</div> </div>
</div> </div>
</div> </div>
</> </>

View File

@ -25,10 +25,10 @@ export const getValidationSchema = () => {
// validate input // validate input
return Yup.object().shape({ return Yup.object().shape({
content_image: Yup.string().nullable(), content_image: Yup.string().nullable(),
content: Yup.string().required("validation.required"), content: Yup.string().required("validation.required").nullable(),
answers: Yup.array().of( answers: Yup.array().of(
Yup.object().shape({ Yup.object().shape({
content: Yup.string().required("validation.required"), content: Yup.string().nullable(),
content_image: Yup.string().nullable(), content_image: Yup.string().nullable(),
isCorrect: Yup.boolean(), isCorrect: Yup.boolean(),
}), }),
@ -36,10 +36,12 @@ export const getValidationSchema = () => {
"at-least-one-correct", "at-least-one-correct",
"At least one answer must be correct", "At least one answer must be correct",
(answers: any) => { (answers: any) => {
return answers?.some(
(answer: any) => const hasCorrectAnswer = answers?.some((answer:any) => answer?.isCorrect === true || answer?.isCorrect === 1);
answer?.isCorrect === true || answer?.isCorrect === 1,
); const haveImageOrContent = answers?.some((item:any)=> !(item?.content) && !(item.content_image));
return hasCorrectAnswer && !haveImageOrContent ;
}, },
), ),
}); });
@ -106,11 +108,12 @@ export const getValidationSchemaBase = () => {
"at-least-one-correct", "at-least-one-correct",
"At least one answer must be correct", "At least one answer must be correct",
(answers: any) => { (answers: any) => {
return answers.some( const hasCorrectAnswer = answers?.some((answer:any) => answer?.isCorrect === true || answer?.isCorrect === 1);
(answer: any) =>
answer.isCorrect === true || answer.isCorrect === 1, const haveImageOrContent = answers?.some((item:any)=> !(item?.content) && !(item.content_image));
);
return hasCorrectAnswer && !haveImageOrContent ;
}, },
), ),
}), }),

View File

@ -14,12 +14,13 @@ import {
} from "../../../../utils/hasAbilityFn"; } from "../../../../utils/hasAbilityFn";
import { ABILITIES_ENUM } from "../../../../enums/abilities"; import { ABILITIES_ENUM } from "../../../../enums/abilities";
import { Subject } from "../../../../types/Subject"; import { Subject } from "../../../../types/Subject";
import { CiImageOff } from "react-icons/ci"; import { useFilterStateState } from "../../../../zustand/Filter";
export const useColumns = () => { export const useColumns = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { setObjectToEdit } = useObjectToEdit((state) => state); const { setObjectToEdit } = useObjectToEdit((state) => state);
const { setIsOpen } = useModalState((state) => state); const { setIsOpen } = useModalState((state) => state);
const { setFilter } = useFilterStateState();
const handelDelete = (record: Subject) => { const handelDelete = (record: Subject) => {
setObjectToEdit(record); setObjectToEdit(record);
@ -31,6 +32,7 @@ export const useColumns = () => {
}; };
const handelShow = (record: Subject) => { const handelShow = (record: Subject) => {
setFilter({})
navigate(`${ABILITIES_ENUM?.SUBJECT}/${record?.id}`); navigate(`${ABILITIES_ENUM?.SUBJECT}/${record?.id}`);
}; };

View File

@ -1,19 +1,19 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../enums/abilities";
import useSetPageTitle from "../../Hooks/useSetPageTitle";
import useFilter from "../../Components/FilterField/components/useFilter"; import useFilter from "../../Components/FilterField/components/useFilter";
import { Button, Popconfirm } from "antd";
import PageTitle from "../../Layout/Dashboard/PageTitle";
const Dummy = () => { const Dummy = () => {
const [t] = useTranslation(); const [t] = useTranslation();
useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
const { FilterButton, FilterBody } = useFilter(); const { FilterButton, FilterBody } = useFilter();
return ( return (
<div className="DummyHomePage"> <div className="DummyHomePage">
<PageTitle/>
<FilterButton/>
<FilterBody>
karim
</FilterBody>
karim2
</div> </div>
); );
}; };

View File

@ -10,6 +10,7 @@
height: 100vh; height: 100vh;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
background: var(--bgSideBar); background: var(--bgSideBar);
color: var(--textSideBar); color: var(--textSideBar);
position: absolute; position: absolute;
@ -19,6 +20,12 @@
flex-direction: column; flex-direction: column;
z-index: 2; z-index: 2;
&::-webkit-scrollbar {
display: none;
}
.side_bar_header { .side_bar_header {
height: var(--navBarHeight); height: var(--navBarHeight);
display: flex; display: flex;

View File

@ -48,7 +48,8 @@
"Sorry, the question must have at least one option": "عذرًا، يجب أن يحتوي السؤال على خيار واحد على الأقل", "Sorry, the question must have at least one option": "عذرًا، يجب أن يحتوي السؤال على خيار واحد على الأقل",
"at_least_one_answer_should_be_correct": "يجب أن تكون إجابة واحدة صحيحة", "at_least_one_answer_should_be_correct": "يجب أن تكون إجابة واحدة صحيحة",
"it_should_have_more_than_one_answers":"يجب أن يحتوي على أكثر من إجابة", "it_should_have_more_than_one_answers":"يجب أن يحتوي على أكثر من إجابة",
"it_should_have_more_than_one_correct_answers":"يجب أن يحتوي على إجابة صحيحة" "it_should_have_more_than_one_correct_answers":"يجب أن يحتوي على إجابة صحيحة",
"File_size_exceeds_2_MB_limit.":"حجم الملف يتجاوز الحد الأقصى البالغ 2 ميجابايت"
}, },
"header": { "header": {
"register_students": "تسجيل الطلاب", "register_students": "تسجيل الطلاب",