diff --git a/src/Components/CustomFields/ImageBoxField/ImageBoxFieldMemo.tsx b/src/Components/CustomFields/ImageBoxField/ImageBoxFieldMemo.tsx index 7b95e0d..0807526 100644 --- a/src/Components/CustomFields/ImageBoxField/ImageBoxFieldMemo.tsx +++ b/src/Components/CustomFields/ImageBoxField/ImageBoxFieldMemo.tsx @@ -68,7 +68,7 @@ const ImageBoxFieldMemo = memo( console.log(name); return ( -
+
{imagePreview ? ( <> @@ -99,10 +99,11 @@ const ImageBoxFieldMemo = memo( />
); - }, - (prevProps, nextProps) => { - return areFieldPropsEqual(prevProps, nextProps); - }, + } + // , + // (prevProps, nextProps) => { + // return areFieldPropsEqual(prevProps, nextProps); + // }, ); export default ImageBoxFieldMemo; diff --git a/src/Hooks/useReOrderQuestions.ts b/src/Hooks/useReOrderQuestions.ts new file mode 100644 index 0000000..12f7896 --- /dev/null +++ b/src/Hooks/useReOrderQuestions.ts @@ -0,0 +1,43 @@ +import { useFormikContext } from 'formik'; +import React from 'react' +import { moveToBottom, moveToTop } from '../utils/reOrder'; +type FormValues = { + Questions: Array<{ id: string; sub_order?: number } & Record>; +}; + +export function useReOrderQuestions() { + const {setFieldValue,values} = useFormikContext() + + const withSubOrder = (arr: any[]) => arr.map((it, i) => ({ ...it, sub_order: i })); + + const scrollToIdWithOffset = (id: string) => { + const el = document.getElementById(id); + if (!el) return; + const top = el.getBoundingClientRect().top ; + console.log(el.getBoundingClientRect()) + window.scrollBy({ top, behavior: "smooth" }); + }; + + const afterLayout = (fn: () => void) => { + requestAnimationFrame(() => requestAnimationFrame(fn)); + }; + + const moveItemUp = (item:any,index: number) => { + if (index <= 0) return; + const next = moveToTop(index, values.Questions); + setFieldValue("Questions", withSubOrder(next)); + afterLayout(() => scrollToIdWithOffset(`q-${item.id}`)); + + }; + + const moveItemDown = (item:any,index: number) => { + if (index >= values.Questions.length - 1) return; + const next = moveToBottom(index, values.Questions); + setFieldValue("Questions", withSubOrder(next)); + afterLayout(() => scrollToIdWithOffset(`q-${item.id}`)); + + }; + + return { moveItemDown , moveItemUp } +} + diff --git a/src/Pages/Admin/question/Model/Malty/ChoiceField/CheckboxField.tsx b/src/Pages/Admin/question/Model/Malty/ChoiceField/CheckboxField.tsx index 77ceb3a..a2e5d63 100644 --- a/src/Pages/Admin/question/Model/Malty/ChoiceField/CheckboxField.tsx +++ b/src/Pages/Admin/question/Model/Malty/ChoiceField/CheckboxField.tsx @@ -35,7 +35,7 @@ const CheckboxField = ({ ); }; return ( -
+
{ const [t] = useTranslation(); const { ShowHint } = useObjectToEdit(); @@ -49,6 +53,11 @@ const ChoiceFields = React.memo( } return false; }; + const nameTxt = `Questions[${parent_index}].answers[${index}].content`; + const nameImg = `Questions[${parent_index}].answers[${index}].content_image`; + // useEffect(()=>{ + + // })a return ( <> @@ -58,13 +67,15 @@ const ChoiceFields = React.memo( >
@@ -106,26 +117,27 @@ const ChoiceFields = React.memo(
); - }, - (prevProps, nextProps) => { - console.log( - prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[ - prevProps?.index - ] === - nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[ - prevProps?.index - ], - ); + } + // areEqual + // (prevProps, nextProps) => { + // console.log( + // prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[ + // prevProps?.index + // ] === + // nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[ + // prevProps?.index + // ], + // ); - return ( - prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[ - prevProps?.index - ] === - nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[ - prevProps?.index - ] - ); - }, + // return ( + // prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[ + // prevProps?.index + // ] === + // nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[ + // prevProps?.index + // ] + // ); + // }, ); export default ChoiceFields; diff --git a/src/Pages/Admin/question/Model/Malty/ChoiceField/Choices.tsx b/src/Pages/Admin/question/Model/Malty/ChoiceField/Choices.tsx index 00685ab..9a594bd 100644 --- a/src/Pages/Admin/question/Model/Malty/ChoiceField/Choices.tsx +++ b/src/Pages/Admin/question/Model/Malty/ChoiceField/Choices.tsx @@ -45,9 +45,10 @@ const Choices = React.memo( {(values?.Questions?.[parent_index]?.answers || []).map( (item: Choice, index: number) => { return ( -
+
console.log(item)}> */} ); - }, - (prevProps, nextProps) => { - return ( - prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === - nextProps.values?.Questions?.[nextProps?.parent_index]?.answers - ); - }, + } + // , + // (prevProps, nextProps) => { + // return ( + // prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === + // nextProps.values?.Questions?.[nextProps?.parent_index]?.answers + // ); + // }, ); export default Choices; diff --git a/src/Pages/Admin/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx b/src/Pages/Admin/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx index f8d69af..34c6459 100644 --- a/src/Pages/Admin/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx +++ b/src/Pages/Admin/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx @@ -19,6 +19,7 @@ const QuestionFIeld = ({ const formik = useFormikContext(); const { setDeletedQuestions, DeletedQuestions } = useObjectToEdit(); + // const path = git const [t] = useTranslation(); useEffect(() => { setDeletedQuestions([]); @@ -46,9 +47,14 @@ const QuestionFIeld = ({ return false; }; + const nameImg = `Questions[${index}].content_image`; + return ( <> -
+
{ + console.log(values.Questions[index]) + console.log(index) + }}>
console.log(index)} component={ImageBoxFieldMemo} - name={`Questions.${index}.content_image`} + name={nameImg} + /> {handelCanDeleteAnswers() ? (
diff --git a/src/Pages/Admin/question/Model/Malty/components/Question.tsx b/src/Pages/Admin/question/Model/Malty/components/Question.tsx index 43ab8bd..0c7befb 100644 --- a/src/Pages/Admin/question/Model/Malty/components/Question.tsx +++ b/src/Pages/Admin/question/Model/Malty/components/Question.tsx @@ -9,6 +9,7 @@ import { toast } from "react-toastify"; import SelectTagV2 from "../../../../../../Components/CustomFields/SelectTagV2"; import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo"; import { Field } from "formik"; +import { uid } from "../../../../../../utils/reOrder"; export const Question: React.FC = React.memo(({ index, data }) => { const { values, setFieldValue, ShowHint, t } = data; @@ -18,6 +19,7 @@ export const Question: React.FC = React.memo(({ index, data }) => { setFieldValue(`Questions.[${parent_index}].answers`, [ ...(values?.Questions?.[parent_index]?.answers as Choice[]), { + id: uid(), answer: null, content_image: null, content: null, @@ -38,7 +40,6 @@ export const Question: React.FC = React.memo(({ index, data }) => {
@@ -65,9 +66,9 @@ export const Question: React.FC = React.memo(({ index, data }) => { name={`Questions[${index}].hint`} label={t("input.hint_question")} type="TextArea" - style={{ width: "100%", height: 60, resize: "none" }} + // style={{ width: "100%", height: 60, resize: "none" }} showCount={false} - autoSize={{ minRows: 2, maxRows: 10 }} + // autoSize={{ minRows: 2, maxRows: 10 }} /> )} diff --git a/src/Pages/Admin/question/Model/Malty/components/Questions.tsx b/src/Pages/Admin/question/Model/Malty/components/Questions.tsx index 235bd03..1bdc704 100644 --- a/src/Pages/Admin/question/Model/Malty/components/Questions.tsx +++ b/src/Pages/Admin/question/Model/Malty/components/Questions.tsx @@ -1,84 +1,104 @@ -import React, { useCallback, useMemo, useRef, useEffect } from "react"; -import { VariableSizeList as List } from "react-window"; -import { useTranslation } from "react-i18next"; -import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState"; -import { Question } from "./Question"; + import React, { useCallback, useMemo, useRef, useEffect } from "react"; + import { VariableSizeList as List } from "react-window"; + import { useTranslation } from "react-i18next"; + import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState"; + import { Question } from "./Question"; + import { moveToBottom, moveToTop } from "../../../../../../utils/reOrder"; +import { FaArrowRightLong } from "react-icons/fa6"; +import { useReOrderQuestions } from "../../../../../../Hooks/useReOrderQuestions"; -interface QuestionsProps { - setFieldValue: (field: string, value: any) => void; - values: { - Questions: any[]; - }; -} + interface QuestionsProps { + setFieldValue: (field: string, value: any) => void; + values: { + Questions: any[]; + }; + } + + const Questions: React.FC = React.memo( + ({ setFieldValue, values }) => { + const questions = values?.Questions || []; + const { ShowHint } = useObjectToEdit(); + const [t] = useTranslation(); + // const listRef = useRef(null); + const rowRefs = useRef>({}); -const Questions: React.FC = React.memo( - ({ setFieldValue, values }) => { - const questions = values?.Questions || []; - const { ShowHint } = useObjectToEdit(); - const [t] = useTranslation(); - const listRef = useRef(null); - const getItemSize = useCallback( - (index: number) => { - const question = questions[index]; - let height = 300; // Base height for QuestionField + const getItemSize = useCallback( + (index: number) => { + const question = questions[index]; + let height = 300; // Base height for QuestionField - height += (question.answers?.length || 0) * 212; // Height for each answer - if (question.answers?.length < 5) height += 40; // "Add new choice" button - if (ShowHint) height += 80; // Hint field - height += 50; // MaltySelectTag - console.log(height); + height += (question.answers?.length || 0) * 212; // Height for each answer + if (question.answers?.length < 5) height += 40; // "Add new choice" button + if (ShowHint) height += 80; // Hint field + height += 50; // MaltySelectTag + console.log(height); - return height; - }, - [questions, ShowHint], - ); - - const itemData = useMemo( - () => ({ - values, - setFieldValue, - ShowHint, - t, - }), - [values, setFieldValue, ShowHint, t], - ); - - useEffect(() => { - if (listRef.current) { - listRef.current.resetAfterIndex(0); - } - }, [questions, ShowHint]); - - return ( - <> - {/* + return height; + }, + [questions, ShowHint], + ); +// == we don use it == + // const itemData = useMemo( + // () => ({ + // values, + // setFieldValue, + // ShowHint, + // t, + // }), + // [values, setFieldValue, ShowHint, t], + // ); - {Question} - */} - {questions?.map((item: any, index: number) => { - return ( - - ); - })} - - ); - }, - (prevProps, nextProps) => - prevProps?.values?.Questions === nextProps?.values?.Questions, -); + // useEffect(() => { + // if (listRef.current) { + // listRef.current.resetAfterIndex(0); + // } + // }, [questions, ShowHint]); -export default Questions; + const { moveItemDown , moveItemUp} = useReOrderQuestions() + + return ( + <> + {/* + + {Question} + */} + {questions?.map((item: any, index: number) => { + console.log(item) + console.log(questions) + return ( +
console.log(questions)} + ref={(el) => (rowRefs.current[item.id] = el)} + > + +
+ moveItemUp(item,index)}/> + moveItemDown(item,index)}/> +
+
+ ); + })} + + ); + }, + (prevProps, nextProps) => + prevProps?.values?.Questions === nextProps?.values?.Questions, + ); + + export default Questions; diff --git a/src/utils/reOrder.ts b/src/utils/reOrder.ts new file mode 100644 index 0000000..f391c8b --- /dev/null +++ b/src/utils/reOrder.ts @@ -0,0 +1,36 @@ +// export function moveToTop(index:number,array:any[]){ +// const indexItemBefore = index - 1 +// if(indexItemBefore == -1)return array; +// const currentItem = array[index] +// array[index] = array[indexItemBefore] +// array[indexItemBefore] = currentItem +// return array + +// } +// export function moveToBottom(index:number,array:any[]){ +// const indexItemAfter = index + 1 +// if(indexItemAfter == array.length)return array; +// const currentItem = array[index] +// array[index] = array[indexItemAfter] +// array[indexItemAfter] = currentItem +// return array +// } + +function swapImmutable(arr: T[], i: number, j: number): T[] { + if (i === j) return arr.slice(); + const copy = arr.slice(); + [copy[i], copy[j]] = [copy[j], copy[i]]; + return copy; +} + +export function moveToTop(index: number, array: any[]) { + if (index <= 0) return array.slice(); + return swapImmutable(array, index, index - 1); +} + +export function moveToBottom(index: number, array: any[]) { + if (index >= array.length - 1) return array.slice(); + return swapImmutable(array, index, index + 1); +} + +export const uid = () => Date.now().toString() + Math.random().toString(36).slice(2,9);