вопросы и форма контактов отсылают ответы

This commit is contained in:
Nastya 2023-12-18 00:28:57 +03:00
parent 7d436c9df3
commit 25062ad07c
15 changed files with 532 additions and 96 deletions

@ -1,19 +1,98 @@
import { makeRequest } from "@frontend/kitui"; import { makeRequest } from "@frontend/kitui";
function get(quizId: string) { export function getData(quizId: string) {
return makeRequest<any>({ return makeRequest<any>({
url: `https://squiz.pena.digital/answer/settings`, url: `https://squiz.pena.digital/answer/settings`,
body: { body: {
quiz_id: quizId, quiz_id: quizId,
limit: 100, limit: 100,
page: 0, page: 0,
need_config: true, need_config: true,
}, },
method: "POST", method: "POST",
}); });
} }
export const relaseApi = { export function sendAnswer({ questionId, body, qid }: any) {
get: get, const formData = new FormData();
};
const answers = [{
question_id: questionId,
content: body, //тут массив с ответом
qid
}]
formData.append("answers", JSON.stringify(answers));
return makeRequest<FormData, { [key: string]: string; }>({
url: `https://squiz.pena.digital/answer/answer`,
body: formData,
method: "POST",
});
}
//body ={file, filename}
export function sendFile({ questionId, body, qid }: any) {
const formData = new FormData();
const fd: any = {
question_id: questionId,
content: body.name,
qid
}
fd[body.name] = body.filen //target.files[0]
const answers = [fd]
formData.append("answers", JSON.stringify(answers));
return makeRequest<FormData, { [key: string]: string; }>({
url: `https://squiz.pena.digital/answer/answer`,
body: formData,
method: "POST",
});
}
const fields = [
"name",
"email",
"phone",
"adress",
"telegram",
"wechat",
"viber",
"vk",
"skype",
"whatsup",
"messenger",
"text"
]
//форма контактов
export function sendFC({ questionId, body, qid }: any) {
console.log("start fetch")
const formData = new FormData();
// const keysBody = Object.keys(body)
// const content:any = {}
// fields.forEach((key) => {
// if (keysBody.includes(key)) content[key] = body.key
// })
const answers = [{
question_id: questionId,
content: body,
result: true,
qid
}]
formData.append("answers", JSON.stringify(answers));
return makeRequest<FormData, { [key: string]: string; }>({
url: `https://squiz.pena.digital/answer/answer`,
body: formData,
method: "POST",
});
}

@ -6,7 +6,8 @@ export const ApologyPage = ({message}:{message: string}) => {
sx={{ sx={{
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center" justifyContent: "center",
height: "100vh"
}} }}
> >
<Typography <Typography

@ -4,12 +4,15 @@ import EmailIcon from "@icons/ContactFormIcon/EmailIcon";
import PhoneIcon from "@icons/ContactFormIcon/PhoneIcon"; import PhoneIcon from "@icons/ContactFormIcon/PhoneIcon";
import TextIcon from "@icons/ContactFormIcon/TextIcon"; import TextIcon from "@icons/ContactFormIcon/TextIcon";
import AddressIcon from "@icons/ContactFormIcon/AddressIcon"; import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
import { useDebouncedCallback } from "use-debounce";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
import { useState } from "react"; import { useEffect, useRef, useState } from "react";
import { useQuestionsStore } from "@root/quizData/store"; import { useQuestionsStore } from "@root/quizData/store";
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared"; import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
import { enqueueSnackbar } from "notistack";
import { sendFC } from "@api/quizRelase";
type ContactFormProps = { type ContactFormProps = {
currentQuestion: AnyTypedQuizQuestion; currentQuestion: AnyTypedQuizQuestion;
@ -19,11 +22,11 @@ type ContactFormProps = {
}; };
const icons = [ const icons = [
{ type: "name", icon: NameIcon, defaultText: "Введите имя", defaultTitle: "имя" }, { type: "name", icon: NameIcon, defaultText: "Введите имя", defaultTitle: "имя", backendName: "name" },
{ type: "email", icon: EmailIcon, defaultText: "Введите Email", defaultTitle: "Email" }, { type: "email", icon: EmailIcon, defaultText: "Введите Email", defaultTitle: "Email", backendName: "email" },
{ type: "phone", icon: PhoneIcon, defaultText: "Введите номер телефона", defaultTitle: "номер телефона" }, { type: "phone", icon: PhoneIcon, defaultText: "Введите номер телефона", defaultTitle: "номер телефона", backendName: "phone" },
{ type: "text", icon: TextIcon, defaultText: "Введите фамилию", defaultTitle: "фамилию" }, { type: "text", icon: TextIcon, defaultText: "Введите фамилию", defaultTitle: "фамилию", backendName: "adress" },
{ type: "address", icon: AddressIcon, defaultText: "Введите адрес", defaultTitle: "адрес" }, { type: "address", icon: AddressIcon, defaultText: "Введите адрес", defaultTitle: "адрес", backendName: "adress" },
] ]
export const ContactForm = ({ export const ContactForm = ({
@ -65,19 +68,19 @@ export const ContactForm = ({
}} }}
> >
{settings?.cfg.formContact.title || "Заполните форму, чтобы получить результаты теста"} {settings?.cfg.formContact.title || "Заполните форму, чтобы получить результаты теста"}
</Typography> </Typography>
{ {
settings?.cfg.formContact.desc && settings?.cfg.formContact.desc &&
<Typography <Typography
sx={{ sx={{
textAlign: "center", textAlign: "center",
m: "20px 0", m: "20px 0",
fontSize: "18px" fontSize: "18px"
}} }}
> >
{settings?.cfg.formContact.desc} {settings?.cfg.formContact.desc}
</Typography> </Typography>
} }
</Box> </Box>
@ -98,7 +101,7 @@ export const ContactForm = ({
my: "20px" my: "20px"
}} }}
> >
<Inputs /> <Inputs currentQuestion={currentQuestion} />
</Box> </Box>
@ -136,33 +139,92 @@ export const ContactForm = ({
); );
}; };
const Inputs = () => { const Inputs = (currentQuestion: any) => {
const { settings } = useQuestionsStore() const { settings, items } = useQuestionsStore()
let someUsed:any = []
const Icons = icons.map((data) => { const [name, setName] = useState("")
const [email, setEmail] = useState("")
const [phone, setPhone] = useState("")
const [text, setText] = useState("")
const [adress, setAdress] = useState("")
const inputHC = useDebouncedCallback(async () => {
console.log("start input")
const body = {}
//@ts-ignore //@ts-ignore
const FC:any = settings?.cfg.formContact[data.type] if (name.length > 0) body.name = name
if (FC.used) someUsed.push(<CustomInput title={FC.innerText || data.defaultText} desc={FC.text || data.defaultTitle} Icon={data.icon} />) //@ts-ignore
return <CustomInput title={FC.innerText || data.defaultText} desc={FC.text || data.defaultTitle} Icon={data.icon} /> if (email.length > 0) body.email = email
}) //@ts-ignore
if (phone.length > 0) body.phone = phone
//@ts-ignore
if (text.length > 0) body.text = text
//@ts-ignore
if (adress.length > 0) body.adress = adress
if (someUsed.length) { console.log(body)
return <>{someUsed}</> if (Object.keys(body).length > 0) {
try {
await sendFC({
questionId: currentQuestion.id,
body: body,
//@ts-ignore
qid: settings.qid
})
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}
}, 1000);
useEffect(() => {
inputHC()
}, [name, email, phone, text, adress])
//@ts-ignore
const FC: any = settings?.cfg.formContact
//@ts-ignore
const Name = <CustomInput onChange={({ target }) => setName(target.value)} id={name} title={FC["name"].innerText || "Введите имя"} desc={FC["name"].text || "имя"} Icon={NameIcon} />
//@ts-ignore
const Email = <CustomInput onChange={({ target }) => setEmail(target.value)} id={email} title={FC["email"].innerText || "Введите Email"} desc={FC["email"].text || "Email"} Icon={EmailIcon} />
//@ts-ignore
const Phone = <CustomInput onChange={({ target }) => setPhone(target.value)} id={phone} title={FC["phone"].innerText || "Введите номер телефона"} desc={FC["phone"].text || "номер телефона"} Icon={PhoneIcon} />
//@ts-ignore
const Text = <CustomInput onChange={({ target }) => setText(target.value)} id={text} title={FC["text"].innerText || "Введите фамилию"} desc={FC["text"].text || "фамилию"} Icon={TextIcon} />
//@ts-ignore
const Adress = <CustomInput onChange={({ target }) => setAdress(target.value)} id={adress} title={FC["address"].innerText || "Введите адрес"} desc={FC["address"].text || "адрес"} Icon={AddressIcon} />
//@ts-ignore
if (items.some((data) => data.used)) {
return <>
{FC["name"].used ? Name : <></>}
{FC["email"].used ? Email : <></>}
{FC["phone"].used ? Phone : <></>}
{FC["text"].used ? Text : <></>}
{FC["address"].used ? Adress : <></>}
</>
} else { } else {
return <> return <>
{Icons[0]} {Name}
{Icons[1]} {Email}
{Icons[2]} {Phone}
</> </>
} }
} }
const CustomInput = ({ title, desc, Icon }: any) => { const CustomInput = ({ title, desc, Icon, onChange }: any) => {
return <Box m="15px 0"> return <Box m="15px 0">
<Typography mb="7px">{title}</Typography> <Typography mb="7px">{title}</Typography>
<TextField <TextField
onChange={onChange}
sx={{ sx={{
width: "350px", width: "350px",
}} }}

@ -6,7 +6,7 @@ import { Question } from "./Question";
import { ApologyPage } from "./ApologyPage" import { ApologyPage } from "./ApologyPage"
import { useQuestionsStore } from "@root/quizData/store" import { useQuestionsStore } from "@root/quizData/store"
import { relaseApi } from "@api/quizRelase" import { getData } from "@api/quizRelase"
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { useGetSettings } from "../../utils/hooks/useGetSettings"; import { useGetSettings } from "../../utils/hooks/useGetSettings";
@ -15,10 +15,12 @@ export const ViewPage = () => {
const { settings, cnt, items } = useQuestionsStore() const { settings, cnt, items } = useQuestionsStore()
const [visualStartPage, setVisualStartPage] = useState<boolean>(); const [visualStartPage, setVisualStartPage] = useState<boolean>();
const [errormessage, setErrormessage] = useState<string>("");
useEffect(() => { useEffect(() => {
async function get() { async function get() {
const data = await relaseApi.get("c1ee11d2-ed5a-47d1-b500-bda6fd442114") try {
const data = await getData("c1ee11d2-ed5a-47d1-b500-bda6fd442114")
//@ts-ignore //@ts-ignore
const settings = data.settings const settings = data.settings
console.log(data) console.log(data)
@ -51,6 +53,12 @@ export const ViewPage = () => {
} }
console.log(parseData) console.log(parseData)
useQuestionsStore.setState(parseData) useQuestionsStore.setState(parseData)
} catch (e) {
//@ts-ignore
if (e?.response?.status === 423) setErrormessage("квиз не активирован")
}
} }
get() get()
},[]) },[])
@ -76,6 +84,7 @@ console.log(items)
console.log(filteredQuestions) console.log(filteredQuestions)
if (errormessage) return <ApologyPage message={errormessage} />
if (visualStartPage === undefined) return <Skeleton sx={{ bgcolor: 'grey', width: "100vw", height: "100vh" }} variant="rectangular" />; if (visualStartPage === undefined) return <Skeleton sx={{ bgcolor: 'grey', width: "100vw", height: "100vh" }} variant="rectangular" />;
if (cnt === 0) return <ApologyPage message="Нет созданных вопросов" /> if (cnt === 0) return <ApologyPage message="Нет созданных вопросов" />
return ( return (

@ -6,12 +6,16 @@ import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
import type { QuizQuestionDate } from "../../../model/questionTypes/date"; import type { QuizQuestionDate } from "../../../model/questionTypes/date";
import CalendarIcon from "@icons/CalendarIcon"; import CalendarIcon from "@icons/CalendarIcon";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type DateProps = { type DateProps = {
currentQuestion: QuizQuestionDate; currentQuestion: QuizQuestionDate;
}; };
export const Date = ({ currentQuestion }: DateProps) => { export const Date = ({ currentQuestion }: DateProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const answer = answers.find( const answer = answers.find(
({ questionId }) => questionId === currentQuestion.id ({ questionId }) => questionId === currentQuestion.id
@ -38,21 +42,39 @@ export const Date = ({ currentQuestion }: DateProps) => {
? new window.Date(`${month}.${day}.${year}`) ? new window.Date(`${month}.${day}.${year}`)
: new window.Date() : new window.Date()
)} )}
onChange={(date) => { onChange={async (date) => {
if (!date) { if (!date) {
return; return;
} }
updateAnswer( try {
currentQuestion.id,
String( await sendAnswer({
new window.Date(date.toDate()).toLocaleDateString("ru-RU", { questionId: currentQuestion.id,
body: new window.Date(date.toDate()).toLocaleDateString("ru-RU", {
year: "numeric", year: "numeric",
month: "2-digit", month: "2-digit",
day: "2-digit", day: "2-digit",
}) }),
) //@ts-ignore
); qid: settings.qid
})
updateAnswer(
currentQuestion.id,
String(
new window.Date(date.toDate()).toLocaleDateString("ru-RU", {
year: "numeric",
month: "2-digit",
day: "2-digit",
})
)
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}} }}
slotProps={{ slotProps={{
openPickerButton: { openPickerButton: {

@ -14,12 +14,16 @@ import RadioCheck from "@ui_kit/RadioCheck";
import RadioIcon from "@ui_kit/RadioIcon"; import RadioIcon from "@ui_kit/RadioIcon";
import type { QuizQuestionEmoji } from "../../../model/questionTypes/emoji"; import type { QuizQuestionEmoji } from "../../../model/questionTypes/emoji";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type EmojiProps = { type EmojiProps = {
currentQuestion: QuizQuestionEmoji; currentQuestion: QuizQuestionEmoji;
}; };
export const Emoji = ({ currentQuestion }: EmojiProps) => { export const Emoji = ({ currentQuestion }: EmojiProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const theme = useTheme(); const theme = useTheme();
const { answer } = const { answer } =
@ -94,13 +98,29 @@ export const Emoji = ({ currentQuestion }: EmojiProps) => {
gap: "10px", gap: "10px",
}} }}
value={index} value={index}
onClick={(event) => { onClick={async (event) => {
event.preventDefault(); event.preventDefault();
updateAnswer( try {
currentQuestion.id,
currentQuestion.content.variants[index].id await sendAnswer({
); questionId: currentQuestion.id,
body: currentQuestion.content.variants[index].id,
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
if (answer === currentQuestion.content.variants[index].id) { if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id); deleteAnswer(currentQuestion.id);

@ -15,6 +15,9 @@ import type { ChangeEvent } from "react";
import type { QuizQuestionFile } from "../../../model/questionTypes/file"; import type { QuizQuestionFile } from "../../../model/questionTypes/file";
import type { DragEvent } from "react"; import type { DragEvent } from "react";
import type { UploadFileType } from "@model/questionTypes/file"; import type { UploadFileType } from "@model/questionTypes/file";
import { enqueueSnackbar } from "notistack";
import { sendFile } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type FileProps = { type FileProps = {
currentQuestion: QuizQuestionFile; currentQuestion: QuizQuestionFile;
@ -38,19 +41,39 @@ export const UPLOAD_FILE_DESCRIPTIONS_MAP: Record<
} as const; } as const;
export const File = ({ currentQuestion }: FileProps) => { export const File = ({ currentQuestion }: FileProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const answer = answers.find( const answer = answers.find(
({ questionId }) => questionId === currentQuestion.id ({ questionId }) => questionId === currentQuestion.id
)?.answer as string; )?.answer as string;
const theme = useTheme(); const theme = useTheme();
const uploadFile = ({ target }: ChangeEvent<HTMLInputElement>) => { const uploadFile = async ({ target }: ChangeEvent<HTMLInputElement>) => {
const file = target.files?.[0]; const file = target.files?.[0];
console.log(file)
if (file) { if (file) {
updateAnswer(
currentQuestion.id, try {
`${file.name}|${URL.createObjectURL(file)}`
); await sendFile({
questionId: currentQuestion.id,
body: {
file: `${file.name}|${URL.createObjectURL(file)}`,
name: file.name
},
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
`${file.name}|${URL.createObjectURL(file)}`
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
} }
}; };
@ -84,7 +107,9 @@ export const File = ({ currentQuestion }: FileProps) => {
<IconButton <IconButton
sx={{ p: 0 }} sx={{ p: 0 }}
onClick={() => { onClick={() => {
updateAnswer(currentQuestion.id, "");
updateAnswer(currentQuestion.id, "");
}} }}
> >
<CloseBold /> <CloseBold />

@ -13,12 +13,16 @@ import RadioCheck from "@ui_kit/RadioCheck";
import RadioIcon from "@ui_kit/RadioIcon"; import RadioIcon from "@ui_kit/RadioIcon";
import type { QuizQuestionImages } from "../../../model/questionTypes/images"; import type { QuizQuestionImages } from "../../../model/questionTypes/images";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type ImagesProps = { type ImagesProps = {
currentQuestion: QuizQuestionImages; currentQuestion: QuizQuestionImages;
}; };
export const Images = ({ currentQuestion }: ImagesProps) => { export const Images = ({ currentQuestion }: ImagesProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const theme = useTheme(); const theme = useTheme();
const { answer } = const { answer } =
@ -64,13 +68,28 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
borderRadius: "5px", borderRadius: "5px",
border: `1px solid ${theme.palette.grey2.main}`, border: `1px solid ${theme.palette.grey2.main}`,
}} }}
onClick={(event) => { onClick={async(event) => {
event.preventDefault(); event.preventDefault();
updateAnswer( try {
currentQuestion.id,
currentQuestion.content.variants[index].id await sendAnswer({
); questionId: currentQuestion.id,
body: currentQuestion.content.variants[index].id,
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
if (answer === currentQuestion.content.variants[index].id) { if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id); deleteAnswer(currentQuestion.id);

@ -8,29 +8,63 @@ import { CustomSlider } from "@ui_kit/CustomSlider";
import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
import type { QuizQuestionNumber } from "../../../model/questionTypes/number"; import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type NumberProps = { type NumberProps = {
currentQuestion: QuizQuestionNumber; currentQuestion: QuizQuestionNumber;
}; };
export const Number = ({ currentQuestion }: NumberProps) => { export const Number = ({ currentQuestion }: NumberProps) => {
const { settings } = useQuestionsStore()
const [minRange, setMinRange] = useState<string>("0"); const [minRange, setMinRange] = useState<string>("0");
const [maxRange, setMaxRange] = useState<string>("100000000000"); const [maxRange, setMaxRange] = useState<string>("100000000000");
const theme = useTheme(); const theme = useTheme();
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const updateMinRangeDebounced = useDebouncedCallback((value, crowded = false) => { const updateMinRangeDebounced = useDebouncedCallback(async (value, crowded = false) => {
if (crowded) { if (crowded) {
setMinRange(maxRange); setMinRange(maxRange);
} }
updateAnswer(currentQuestion.id, value); try {
await sendAnswer({
questionId: currentQuestion.id,
body: value,
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, value);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}, 1000); }, 1000);
const updateMaxRangeDebounced = useDebouncedCallback((value, crowded = false) => { const updateMaxRangeDebounced = useDebouncedCallback(async(value, crowded = false) => {
if (crowded) { if (crowded) {
setMaxRange(minRange); setMaxRange(minRange);
} }
try {
await sendAnswer({
questionId: currentQuestion.id,
body: value,
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, value);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
updateAnswer(currentQuestion.id, value);
}, 1000); }, 1000);
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string; const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
@ -73,9 +107,29 @@ export const Number = ({ currentQuestion }: NumberProps) => {
min={min} min={min}
max={max} max={max}
step={currentQuestion.content.step || 1} step={currentQuestion.content.step || 1}
onChange={(_, value) => { onChange={async (_, value) => {
const range = String(value).replace(",", "—"); const range = String(value).replace(",", "—");
updateAnswer(currentQuestion.id, range);
try {
await sendAnswer({
questionId: currentQuestion.id,
body: range,
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, range);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}} }}
onChangeCommitted={(_, value) => { onChangeCommitted={(_, value) => {
if (currentQuestion.content.chooseRange) { if (currentQuestion.content.chooseRange) {
@ -91,15 +145,41 @@ export const Number = ({ currentQuestion }: NumberProps) => {
<CustomTextField <CustomTextField
placeholder="0" placeholder="0"
value={answer} value={answer}
onChange={({ target }) => { onChange={async({ target }) => {
updateAnswer(
currentQuestion.id,
window.Number(target.value) > max
try {
await sendAnswer({
questionId: currentQuestion.id,
body: window.Number(target.value) > max
? String(max) ? String(max)
: window.Number(target.value) < min : window.Number(target.value) < min
? String(min) ? String(min)
: target.value : target.value,
); //@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
window.Number(target.value) > max
? String(max)
: window.Number(target.value) < min
? String(min)
: target.value
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}} }}
sx={{ sx={{
maxWidth: "80px", maxWidth: "80px",

@ -16,6 +16,9 @@ import HashtagIcon from "@icons/questionsPage/hashtagIcon";
import StarIconMini from "@icons/questionsPage/StarIconMini"; import StarIconMini from "@icons/questionsPage/StarIconMini";
import type { QuizQuestionRating } from "../../../model/questionTypes/rating"; import type { QuizQuestionRating } from "../../../model/questionTypes/rating";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type RatingProps = { type RatingProps = {
currentQuestion: QuizQuestionRating; currentQuestion: QuizQuestionRating;
@ -53,6 +56,7 @@ const buttonRatingForm = [
]; ];
export const Rating = ({ currentQuestion }: RatingProps) => { export const Rating = ({ currentQuestion }: RatingProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const theme = useTheme(); const theme = useTheme();
const { answer } = const { answer } =
@ -85,8 +89,26 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
> >
<RatingComponent <RatingComponent
value={Number(answer || 0)} value={Number(answer || 0)}
onChange={(_, value) => onChange={async (_, value) => {
updateAnswer(currentQuestion.id, String(value))
try {
await sendAnswer({
questionId: currentQuestion.id,
body: String(value),
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, String(value))
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}
} }
sx={{ height: "50px", gap: "15px" }} sx={{ height: "50px", gap: "15px" }}
max={currentQuestion.content.steps} max={currentQuestion.content.steps}

@ -5,12 +5,16 @@ import { Select as SelectComponent } from "../tools//Select";
import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store"; import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store";
import type { QuizQuestionSelect } from "../../../model/questionTypes/select"; import type { QuizQuestionSelect } from "../../../model/questionTypes/select";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type SelectProps = { type SelectProps = {
currentQuestion: QuizQuestionSelect; currentQuestion: QuizQuestionSelect;
}; };
export const Select = ({ currentQuestion }: SelectProps) => { export const Select = ({ currentQuestion }: SelectProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const { answer } = const { answer } =
answers.find( answers.find(
@ -32,14 +36,30 @@ export const Select = ({ currentQuestion }: SelectProps) => {
placeholder={currentQuestion.content.default} placeholder={currentQuestion.content.default}
activeItemIndex={answer ? Number(answer) : -1} activeItemIndex={answer ? Number(answer) : -1}
items={currentQuestion.content.variants.map(({ answer }) => answer)} items={currentQuestion.content.variants.map(({ answer }) => answer)}
onChange={(_, value) => { onChange={async(_, value) => {
if (value < 0) { if (value < 0) {
deleteAnswer(currentQuestion.id); deleteAnswer(currentQuestion.id);
return; return;
} }
updateAnswer(currentQuestion.id, String(value)); try {
await sendAnswer({
questionId: currentQuestion.id,
body: String(value),
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, String(value));
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}} }}
/> />
</Box> </Box>

@ -5,12 +5,16 @@ import CustomTextField from "@ui_kit/CustomTextField";
import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
import type { QuizQuestionText } from "../../../model/questionTypes/text"; import type { QuizQuestionText } from "../../../model/questionTypes/text";
import { enqueueSnackbar } from "notistack";
import { useQuestionsStore } from "@root/quizData/store"
import { sendAnswer } from "@api/quizRelase";
type TextProps = { type TextProps = {
currentQuestion: QuizQuestionText; currentQuestion: QuizQuestionText;
}; };
export const Text = ({ currentQuestion }: TextProps) => { export const Text = ({ currentQuestion }: TextProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {}; const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
@ -29,7 +33,24 @@ export const Text = ({ currentQuestion }: TextProps) => {
placeholder={currentQuestion.content.placeholder} placeholder={currentQuestion.content.placeholder}
//@ts-ignore //@ts-ignore
value={answer || ""} value={answer || ""}
onChange={({ target }) => updateAnswer(currentQuestion.id, target.value)} onChange={async ({ target }) => {
try {
await sendAnswer({
questionId: currentQuestion.id,
body: target.value,
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, target.value)
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
}
}
/> />
</Box> </Box>
</Box> </Box>

@ -25,6 +25,9 @@ import { CheckboxIcon } from "@icons/Checkbox";
import type { QuizQuestionVariant } from "../../../model/questionTypes/variant"; import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
import type { QuestionVariant } from "../../../model/questionTypes/shared"; import type { QuestionVariant } from "../../../model/questionTypes/shared";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
type VariantProps = { type VariantProps = {
stepNumber: number; stepNumber: number;
@ -40,6 +43,7 @@ type VariantItemProps = {
}; };
export const Variant = ({ currentQuestion }: VariantProps) => { export const Variant = ({ currentQuestion }: VariantProps) => {
const { settings } = useQuestionsStore()
const { answers, ownVariants } = useQuizViewStore(); const { answers, ownVariants } = useQuizViewStore();
const { answer } = const { answer } =
answers.find( answers.find(
@ -159,24 +163,55 @@ const VariantItem = ({
} }
//@ts-ignore //@ts-ignore
label={own ? <TextField label="Другое..." /> : variant.answer} label={own ? <TextField label="Другое..." /> : variant.answer}
onClick={(event) => { onClick={async(event) => {
event.preventDefault(); event.preventDefault();
const variantId = currentQuestion.content.variants[index].id; const variantId = currentQuestion.content.variants[index].id;
if (currentQuestion.content.multi) { if (currentQuestion.content.multi) {
const currentAnswer = typeof answer !== "string" ? answer || [] : []; const currentAnswer = typeof answer !== "string" ? answer || [] : [];
updateAnswer( try {
currentQuestion.id,
currentAnswer.includes(variantId) await sendAnswer({
questionId: currentQuestion.id,
body: currentAnswer.includes(variantId)
? currentAnswer?.filter((item) => item !== variantId) ? currentAnswer?.filter((item) => item !== variantId)
: [...currentAnswer, variantId] : [...currentAnswer, variantId],
); //@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
currentAnswer.includes(variantId)
? currentAnswer?.filter((item) => item !== variantId)
: [...currentAnswer, variantId]
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
return; return;
} }
updateAnswer(currentQuestion.id, variantId); try {
await sendAnswer({
questionId: currentQuestion.id,
body: variantId,
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, variantId);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
if (answer === variantId) { if (answer === variantId) {
deleteAnswer(currentQuestion.id); deleteAnswer(currentQuestion.id);

@ -9,18 +9,22 @@ import {
import gag from "./gag.png" import gag from "./gag.png"
import { useQuestionsStore } from "@root/quizData/store"
import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store"; import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store";
import RadioCheck from "@ui_kit/RadioCheck"; import RadioCheck from "@ui_kit/RadioCheck";
import RadioIcon from "@ui_kit/RadioIcon"; import RadioIcon from "@ui_kit/RadioIcon";
import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg"; import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
type VarimgProps = { type VarimgProps = {
currentQuestion: QuizQuestionVarImg; currentQuestion: QuizQuestionVarImg;
}; };
export const Varimg = ({ currentQuestion }: VarimgProps) => { export const Varimg = ({ currentQuestion }: VarimgProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const theme = useTheme(); const theme = useTheme();
const { answer } = const { answer } =
@ -63,13 +67,30 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
display: "flex", display: "flex",
}} }}
value={index} value={index}
onClick={(event) => { onClick={async(event) => {
event.preventDefault(); event.preventDefault();
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id try {
);
await sendAnswer({
questionId: currentQuestion.id,
body: currentQuestion.content.variants[index].id,
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id
);
} catch (e) {
console.log(e)
enqueueSnackbar("ответ не был засчитан")
}
if (answer === currentQuestion.content.variants[index].id) { if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id); deleteAnswer(currentQuestion.id);

@ -1,7 +1,7 @@
import { useEffect, useLayoutEffect, useRef, useState } from "react" import { useEffect, useLayoutEffect, useRef, useState } from "react"
import { useQuestionsStore } from "@root/quizData/store"; import { useQuestionsStore } from "@root/quizData/store";
import { relaseApi } from "@api/quizRelase" import { getData } from "@api/quizRelase"
interface SettingsGetter { interface SettingsGetter {
quizId: string quizId: string
@ -13,7 +13,7 @@ export function useGetSettings(quizId: string) {
useEffect(() => { useEffect(() => {
async function get() { async function get() {
const data = await relaseApi.get(quizId) const data = await getData(quizId)
//@ts-ignore //@ts-ignore
const settings = data.settings const settings = data.settings
console.log(data) console.log(data)