Merge branch 'dev' of https://git.point-dev.net/Karimaldeen/Quiz_dashboard into dev
This commit is contained in:
commit
f03af7d690
|
|
@ -9,6 +9,7 @@
|
||||||
margin-block: 10px;
|
margin-block: 10px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
z-index: 9999999 !important;
|
z-index: 9999999 !important;
|
||||||
|
cursor: pointer;
|
||||||
.ImageBoxIcon {
|
.ImageBoxIcon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
|
|
||||||
import { Button } from "antd";
|
|
||||||
import { BsPlusCircleFill } from "react-icons/bs";
|
import { BsPlusCircleFill } from "react-icons/bs";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useModalHandler from "../../utils/useModalHandler";
|
import useModalHandler from "../../utils/useModalHandler";
|
||||||
import { MdOutlineArrowForwardIos } from "react-icons/md";
|
|
||||||
import { deletePathSegments } from "../../utils/deletePathSegments";
|
import { deletePathSegments } from "../../utils/deletePathSegments";
|
||||||
import { getPrevPathRoute } from "../../utils/getPrevPathRoute";
|
import { getPrevPathRoute } from "../../utils/getPrevPathRoute";
|
||||||
import PageTitleComponent from "./PageTitle";
|
import PageTitleComponent from "./PageTitle";
|
||||||
|
|
@ -33,10 +31,10 @@ const PageHeader = ({
|
||||||
if (PrevPath === 0) {
|
if (PrevPath === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// navigate(deletePathSegments(location.pathname, PrevPath));
|
navigate(deletePathSegments(location.pathname, PrevPath));
|
||||||
};
|
};
|
||||||
const handleNavigateToPage = (location: string) => {
|
const handleNavigateToPage = (location: string) => {
|
||||||
// navigate(location);
|
navigate(location);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log();
|
console.log();
|
||||||
|
|
@ -46,7 +44,7 @@ const PageHeader = ({
|
||||||
<span className="page_header_links" onClick={handelNavigate}>
|
<span className="page_header_links" onClick={handelNavigate}>
|
||||||
<h1 className="page_title">{t(`PageTitle.${pageTitle}`)}</h1>
|
<h1 className="page_title">{t(`PageTitle.${pageTitle}`)}</h1>
|
||||||
<span className="page_links">
|
<span className="page_links">
|
||||||
<MdOutlineArrowForwardIos /> <PageTitleComponent/>
|
<PageTitleComponent/>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{ addModal ? canAdd && (
|
{ addModal ? canAdd && (
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const Form = () => {
|
||||||
<ValidationField placeholder="name" label="name" name="name" />
|
<ValidationField placeholder="name" label="name" name="name" />
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
<div>
|
<div className="DynamicTags">
|
||||||
<DynamicTags />
|
<DynamicTags />
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
||||||
81
src/Pages/Admin/Tags/field/SelectTag.tsx
Normal file
81
src/Pages/Admin/Tags/field/SelectTag.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
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 SelectTag: React.FC = () => {
|
||||||
|
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("");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = useDebounce((value: string) => {
|
||||||
|
setSearchValue(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleFieldChange = (value: string) => {
|
||||||
|
setFieldValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
setSearchValue("");
|
||||||
|
setFieldValue("");
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data, isLoading } = useGetAllTag({
|
||||||
|
name: searchValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [t] = useTranslation();
|
||||||
|
|
||||||
|
const options = data?.data ?? [];
|
||||||
|
const additionalData =
|
||||||
|
options.length < 1 && searchValue.length > 1 && !isLoading
|
||||||
|
? [{ id: searchValue, name: searchValue }]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const value =
|
||||||
|
formik?.values?.tags?.map((item: any) => item?.id ?? item) ?? [];
|
||||||
|
|
||||||
|
const AllOptions = [...options, ...additionalData];
|
||||||
|
|
||||||
|
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={AllOptions}
|
||||||
|
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={value}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SelectTag;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useFormikContext } from "formik";
|
import { useFormikContext } from "formik";
|
||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FaCirclePlus } from "react-icons/fa6";
|
import { FaCirclePlus } from "react-icons/fa6";
|
||||||
import Tag from "./Tag";
|
import Tag from "./Tag";
|
||||||
|
|
@ -8,20 +8,37 @@ const DynamicTags = () => {
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
|
|
||||||
console.log(formik?.values?.synonyms);
|
|
||||||
|
|
||||||
const handleAddChoice = () => {
|
const handleAddChoice = () => {
|
||||||
const length = formik?.values?.synonyms.length;
|
const length = formik?.values?.synonyms.length;
|
||||||
const lastElement = formik?.values?.synonyms[length - 1];
|
const lastElement = formik?.values?.synonyms[length - 1];
|
||||||
|
|
||||||
|
|
||||||
if (lastElement !== "") {
|
if (lastElement !== "") {
|
||||||
formik.setFieldValue("synonyms", [
|
formik.setFieldValue("synonyms", [
|
||||||
...((formik?.values as any)?.synonyms as any[]),
|
...((formik?.values as any)?.synonyms as any[]),
|
||||||
"",
|
"",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const lastElementIndex = formik?.values?.synonyms?.length - 1;
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
const currentElement = document.getElementById(`synonyms_${lastElementIndex}`)
|
||||||
|
|
||||||
|
if (currentElement) {
|
||||||
|
currentElement.focus(); // Set focus on the element
|
||||||
|
}
|
||||||
|
console.log(currentElement,"currentElement");
|
||||||
|
}, [lastElementIndex])
|
||||||
|
|
||||||
// console.log(formik?.values);
|
// console.log(formik?.values);
|
||||||
// console.log(currentTag);
|
// console.log(currentTag);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,57 +4,52 @@ import { useObjectToEdit } from "../../../../zustand/ObjectToEditState";
|
||||||
import { FaTrash } from "react-icons/fa";
|
import { FaTrash } from "react-icons/fa";
|
||||||
|
|
||||||
const Tag = ({ data, index }: { data: any; index: number }) => {
|
const Tag = ({ data, index }: { data: any; index: number }) => {
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const { setTagsSearch, setCurrentTag } = useObjectToEdit();
|
const { setTagsSearch, setCurrentTag } = useObjectToEdit();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (inputRef.current) {
|
if (textareaRef.current) {
|
||||||
inputRef.current.style.width = `${(formik?.values?.synonyms[index]?.length + 1) * 8}px`;
|
// Adjust the height of the textarea based on content
|
||||||
|
textareaRef.current.style.height = 'auto'; // Reset height
|
||||||
|
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`; // Set to scroll height
|
||||||
}
|
}
|
||||||
}, [formik?.values?.synonyms[index]]);
|
}, [formik?.values?.synonyms[index]]);
|
||||||
console.log(formik?.values?.synonyms);
|
|
||||||
console.log(index);
|
|
||||||
|
|
||||||
const handleEditInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleEditInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
// console.log(e.target.value);
|
|
||||||
formik.setFieldValue(`synonyms[${index}]`, e.target.value);
|
formik.setFieldValue(`synonyms[${index}]`, e.target.value);
|
||||||
setTagsSearch(e.target.value);
|
setTagsSearch(e.target.value);
|
||||||
setCurrentTag(index);
|
setCurrentTag(index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInputBlur = () => {
|
const handleInputBlur = () => {
|
||||||
// setTagsSearch(null)
|
// Optionally reset search state
|
||||||
|
// setTagsSearch(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteChoice = () => {
|
const handleDeleteChoice = () => {
|
||||||
console.log(data);
|
|
||||||
// Create a copy of current tags array
|
|
||||||
const currentTags = [...formik.values.synonyms];
|
const currentTags = [...formik.values.synonyms];
|
||||||
// Remove the item at the specified index from the array
|
|
||||||
currentTags.splice(index, 1);
|
currentTags.splice(index, 1);
|
||||||
console.log(currentTags); // Log the updated tags array
|
console.log(currentTags); // Log the updated tags array
|
||||||
|
|
||||||
// Update formik field value with the updated tags array
|
|
||||||
formik.setFieldValue("synonyms", currentTags);
|
formik.setFieldValue("synonyms", currentTags);
|
||||||
|
|
||||||
// Reset search state if needed
|
|
||||||
setTagsSearch(null);
|
setTagsSearch(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tag">
|
<div className="tag">
|
||||||
<input
|
<textarea
|
||||||
ref={inputRef}
|
id={`synonyms_${index}`}
|
||||||
|
ref={textareaRef}
|
||||||
className="tagInput"
|
className="tagInput"
|
||||||
type="text"
|
|
||||||
value={formik?.values?.synonyms[index]}
|
value={formik?.values?.synonyms[index]}
|
||||||
onChange={handleEditInputChange}
|
onChange={handleEditInputChange}
|
||||||
onBlur={handleInputBlur}
|
onBlur={handleInputBlur}
|
||||||
|
rows={1}
|
||||||
|
style={{ resize: 'none', overflow: 'hidden' }}
|
||||||
/>
|
/>
|
||||||
<FaTrash onClick={handleDeleteChoice} />
|
<FaTrash onClick={handleDeleteChoice} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Tag;
|
export default Tag;
|
||||||
|
|
@ -42,6 +42,9 @@
|
||||||
.exercise_add_main {
|
.exercise_add_main {
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
padding: 10px 2vw;
|
padding: 10px 2vw;
|
||||||
|
max-height: 84vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
@include Scrollbar();
|
||||||
}
|
}
|
||||||
.exercise_add_buttons {
|
.exercise_add_buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -90,19 +93,24 @@
|
||||||
background: rgba(49, 130, 206, 0.15);
|
background: rgba(49, 130, 206, 0.15);
|
||||||
color: #3182ce;
|
color: #3182ce;
|
||||||
min-width: 50px;
|
min-width: 50px;
|
||||||
padding: 3px 10px;
|
padding: 5px 10px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tagInput {
|
.tagInput {
|
||||||
all: unset;
|
all: unset;
|
||||||
min-width: 50px;
|
min-width: 30px;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
.DynamicTags{
|
||||||
|
padding: 2px 15px;
|
||||||
|
}
|
||||||
.suggests {
|
.suggests {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user