Merge branch 'quiz-fixes' into 'dev'
feat: quiz fixes See merge request frontend/squiz!43
This commit is contained in:
commit
cca074feb4
@ -12,5 +12,6 @@ export const QUIZ_QUESTION_TEXT: Omit<QuizQuestionText, "id"> = {
|
|||||||
innerName: "",
|
innerName: "",
|
||||||
required: false,
|
required: false,
|
||||||
answerType: "single",
|
answerType: "single",
|
||||||
|
onlyNumbers: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import type {
|
|||||||
QuestionBranchingRule,
|
QuestionBranchingRule,
|
||||||
} from "./shared";
|
} from "./shared";
|
||||||
|
|
||||||
export const uploadFileTypesMap = {
|
export const UPLOAD_FILE_TYPES_MAP = {
|
||||||
all: "Все типы файлов",
|
all: "Все типы файлов",
|
||||||
picture: "Изображения",
|
picture: "Изображения",
|
||||||
video: "Видео",
|
video: "Видео",
|
||||||
@ -12,7 +12,7 @@ export const uploadFileTypesMap = {
|
|||||||
document: "Документ",
|
document: "Документ",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type UploadFileType = keyof typeof uploadFileTypesMap;
|
export type UploadFileType = keyof typeof UPLOAD_FILE_TYPES_MAP;
|
||||||
|
|
||||||
export interface QuizQuestionFile extends QuizQuestionBase {
|
export interface QuizQuestionFile extends QuizQuestionBase {
|
||||||
type: "file";
|
type: "file";
|
||||||
|
|||||||
@ -16,10 +16,11 @@ export interface QuizQuestionText extends QuizQuestionBase {
|
|||||||
required: boolean;
|
required: boolean;
|
||||||
/** Чекбокс "Автозаполнение адреса" */
|
/** Чекбокс "Автозаполнение адреса" */
|
||||||
autofill: boolean;
|
autofill: boolean;
|
||||||
answerType: "single" | "multi" | "number";
|
answerType: "single" | "multi";
|
||||||
hint: QuestionHint;
|
hint: QuestionHint;
|
||||||
rule: QuestionBranchingRule;
|
rule: QuestionBranchingRule;
|
||||||
back: string;
|
back: string;
|
||||||
originalBack: string;
|
originalBack: string;
|
||||||
|
onlyNumbers: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,6 +134,7 @@ export const ChooseAnswerModal = ({
|
|||||||
removeQuestionForce(quizId, question.id);
|
removeQuestionForce(quizId, question.id);
|
||||||
createQuestion(quizId, selectedValue, totalIndex);
|
createQuestion(quizId, selectedValue, totalIndex);
|
||||||
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
|
||||||
|
title: question.title,
|
||||||
expanded: question.expanded,
|
expanded: question.expanded,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -226,7 +226,7 @@ export default function QuestionsPageCard({
|
|||||||
sx={{
|
sx={{
|
||||||
margin: isMobile ? "10px 0" : 0,
|
margin: isMobile ? "10px 0" : 0,
|
||||||
"& .MuiInputBase-root": {
|
"& .MuiInputBase-root": {
|
||||||
color: question.expanded ? "#000000" : "#4D4D4D",
|
color: "#000000",
|
||||||
backgroundColor: question.expanded
|
backgroundColor: question.expanded
|
||||||
? theme.palette.background.default
|
? theme.palette.background.default
|
||||||
: "transparent",
|
: "transparent",
|
||||||
|
|||||||
@ -28,16 +28,17 @@ type SettingTextFieldProps = {
|
|||||||
|
|
||||||
type Answer = {
|
type Answer = {
|
||||||
name: string;
|
name: string;
|
||||||
value: "single" | "multi" | "number";
|
value: "single" | "multi";
|
||||||
};
|
};
|
||||||
|
|
||||||
const ANSWER_TYPES: Answer[] = [
|
const ANSWER_TYPES: Answer[] = [
|
||||||
{ name: "Однострочное", value: "single" },
|
{ name: "Однострочное", value: "single" },
|
||||||
{ name: "Многострочное", value: "multi" },
|
{ name: "Многострочное", value: "multi" },
|
||||||
{ name: "Только числа", value: "number" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function SettingTextField({ totalIndex }: SettingTextFieldProps) {
|
export default function SettingTextField({
|
||||||
|
totalIndex,
|
||||||
|
}: SettingTextFieldProps) {
|
||||||
const { listQuestions } = questionStore();
|
const { listQuestions } = questionStore();
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -68,12 +69,24 @@ export default function SettingTextField({ totalIndex }: SettingTextFieldProps)
|
|||||||
pl: "20px",
|
pl: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography sx={{ fontWeight: "500", fontSize: "18px", color: " #4D4D4D", marginBottom: "14px" }}>
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontWeight: "500",
|
||||||
|
fontSize: "18px",
|
||||||
|
color: " #4D4D4D",
|
||||||
|
marginBottom: "14px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
Настройки ответов
|
Настройки ответов
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
sx={{ display: "flex", flexDirection: "column", gap: "14px", width: "100%" }}
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "14px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
aria-labelledby="demo-controlled-radio-buttons-group"
|
aria-labelledby="demo-controlled-radio-buttons-group"
|
||||||
name="controlled-radio-buttons-group"
|
name="controlled-radio-buttons-group"
|
||||||
value={ANSWER_TYPES.findIndex(
|
value={ANSWER_TYPES.findIndex(
|
||||||
@ -97,12 +110,29 @@ export default function SettingTextField({ totalIndex }: SettingTextFieldProps)
|
|||||||
"& .MuiRadio-root": { padding: "8px 9px" },
|
"& .MuiRadio-root": { padding: "8px 9px" },
|
||||||
}}
|
}}
|
||||||
value={index}
|
value={index}
|
||||||
control={<Radio icon={<CheckIcon />} checkedIcon={<CheckedIcon />} />}
|
control={
|
||||||
|
<Radio icon={<CheckIcon />} checkedIcon={<CheckedIcon />} />
|
||||||
|
}
|
||||||
label={name}
|
label={name}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
<CustomCheckbox
|
||||||
|
sx={{
|
||||||
|
display: isMobile ? "flex" : "block",
|
||||||
|
mr: isMobile ? "0px" : "16px",
|
||||||
|
marginTop: "15px",
|
||||||
|
alignItems: isMobile ? "flex-end" : "center",
|
||||||
|
}}
|
||||||
|
label={"Только числа"}
|
||||||
|
checked={question.content.onlyNumbers}
|
||||||
|
handleChange={({ target }) => {
|
||||||
|
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, {
|
||||||
|
content: { ...question.content, onlyNumbers: target.checked },
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -115,7 +145,14 @@ export default function SettingTextField({ totalIndex }: SettingTextFieldProps)
|
|||||||
gap: "14px",
|
gap: "14px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography sx={{ height: isMobile ? "18px" : "auto", fontWeight: "500", fontSize: "18px", color: " #4D4D4D" }}>
|
<Typography
|
||||||
|
sx={{
|
||||||
|
height: isMobile ? "18px" : "auto",
|
||||||
|
fontWeight: "500",
|
||||||
|
fontSize: "18px",
|
||||||
|
color: " #4D4D4D",
|
||||||
|
}}
|
||||||
|
>
|
||||||
Настройки вопросов
|
Настройки вопросов
|
||||||
</Typography>
|
</Typography>
|
||||||
<CustomCheckbox
|
<CustomCheckbox
|
||||||
@ -172,7 +209,10 @@ export default function SettingTextField({ totalIndex }: SettingTextFieldProps)
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tooltip title="Будет отображаться как заголовок вопроса в приходящих заявках." placement="top">
|
<Tooltip
|
||||||
|
title="Будет отображаться как заголовок вопроса в приходящих заявках."
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
<Box>
|
<Box>
|
||||||
<InfoIcon />
|
<InfoIcon />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -160,5 +160,4 @@ export default function QuizPreviewLayout() {
|
|||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,23 @@
|
|||||||
import { Box, Typography } from "@mui/material";
|
import { Box, Typography } from "@mui/material";
|
||||||
import LabeledDatePicker from "@ui_kit/LabeledDatePicker";
|
|
||||||
import { QuizQuestionDate } from "model/questionTypes/date";
|
|
||||||
|
|
||||||
|
import LabeledDatePicker from "@ui_kit/LabeledDatePicker";
|
||||||
|
import type { QuizQuestionDate } from "model/questionTypes/date";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionDate;
|
question: QuizQuestionDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Date({ question }: Props) {
|
export default function Date({ question }: Props) {
|
||||||
|
return (
|
||||||
return (
|
<Box
|
||||||
<Box sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: 1,
|
gap: 1,
|
||||||
}}>
|
}}
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
>
|
||||||
<LabeledDatePicker />
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
</Box>
|
<LabeledDatePicker />
|
||||||
);
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import { useState, ChangeEvent } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -9,8 +9,10 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { QuizQuestionEmoji } from "model/questionTypes/emoji";
|
|
||||||
import { useState, ChangeEvent } from "react";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
|
|
||||||
|
import type { QuizQuestionEmoji } from "model/questionTypes/emoji";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionEmoji;
|
question: QuizQuestionEmoji;
|
||||||
@ -31,23 +33,27 @@ export default function Emoji({ question }: Props) {
|
|||||||
value={value}
|
value={value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
{question.content.variants.map((variant, index) => (
|
{question.content.variants
|
||||||
<FormControlLabel
|
.filter(({ answer }) => answer)
|
||||||
key={index}
|
.map((variant, index) => (
|
||||||
value={variant.answer}
|
<FormControlLabel
|
||||||
control={<Radio />}
|
key={index}
|
||||||
label={
|
value={variant.answer}
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
control={<Radio />}
|
||||||
<Typography>{`${variant.extendedText} ${variant.answer}`}</Typography>
|
label={
|
||||||
<Tooltip title="Подсказка" placement="right">
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
<Box>
|
<Typography>{`${variant.extendedText} ${variant.answer}`}</Typography>
|
||||||
<InfoIcon />
|
{variant.hints && (
|
||||||
</Box>
|
<Tooltip title="Подсказка" placement="right">
|
||||||
</Tooltip>
|
<Box>
|
||||||
</Box>
|
<InfoIcon />
|
||||||
}
|
</Box>
|
||||||
/>
|
</Tooltip>
|
||||||
))}
|
)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,44 +1,63 @@
|
|||||||
|
import { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||||
import { Box, Button, Typography } from "@mui/material";
|
import { Box, Button, Typography } from "@mui/material";
|
||||||
import { QuizQuestionFile } from "model/questionTypes/file";
|
|
||||||
import { ChangeEvent, useRef, useState } from "react";
|
|
||||||
|
|
||||||
|
import type {
|
||||||
|
QuizQuestionFile,
|
||||||
|
UploadFileType,
|
||||||
|
} from "model/questionTypes/file";
|
||||||
|
|
||||||
|
export const UPLOAD_FILE_TYPES_MAP: Record<UploadFileType, string> = {
|
||||||
|
all: "file",
|
||||||
|
picture: "image/*",
|
||||||
|
video: "video/*",
|
||||||
|
audio: "audio/*",
|
||||||
|
document:
|
||||||
|
".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,.pdf",
|
||||||
|
} as const;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionFile;
|
question: QuizQuestionFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function File({ question }: Props) {
|
export default function File({ question }: Props) {
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
|
const [acceptedType, setAcceptedType] = useState<any>(
|
||||||
|
UPLOAD_FILE_TYPES_MAP.all
|
||||||
|
);
|
||||||
|
|
||||||
function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
|
useEffect(() => {
|
||||||
if (!event.target.files?.[0]) return setFile(null);
|
setAcceptedType(UPLOAD_FILE_TYPES_MAP[question.content.type]);
|
||||||
setFile(event.target.files[0]);
|
}, [question.content.type]);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
|
||||||
<Box sx={{
|
if (!event.target.files?.[0]) return setFile(null);
|
||||||
display: "flex",
|
setFile(event.target.files[0]);
|
||||||
flexDirection: "column",
|
}
|
||||||
alignItems: "start",
|
|
||||||
gap: 1,
|
return (
|
||||||
}}>
|
<Box
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
sx={{
|
||||||
<Button
|
display: "flex",
|
||||||
variant="contained"
|
flexDirection: "column",
|
||||||
onClick={() => fileInputRef.current?.click()}
|
alignItems: "start",
|
||||||
>
|
gap: 1,
|
||||||
Загрузить файл
|
}}
|
||||||
<input
|
>
|
||||||
ref={fileInputRef}
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
onChange={handleFileChange}
|
<Button variant="contained" onClick={() => fileInputRef.current?.click()}>
|
||||||
type="file"
|
Загрузить файл
|
||||||
style={{
|
<input
|
||||||
display: "none",
|
ref={fileInputRef}
|
||||||
}}
|
onChange={handleFileChange}
|
||||||
/>
|
type="file"
|
||||||
</Button>
|
accept={acceptedType}
|
||||||
{file && <Typography>Выбран файл: {file.name}</Typography>}
|
style={{
|
||||||
</Box>
|
display: "none",
|
||||||
);
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
{file && <Typography>Выбран файл: {file.name}</Typography>}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
@ -7,8 +7,10 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { QuizQuestionImages } from "model/questionTypes/images";
|
|
||||||
import { useEffect, useState } from "react";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
|
|
||||||
|
import type { QuizQuestionImages } from "model/questionTypes/images";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionImages;
|
question: QuizQuestionImages;
|
||||||
@ -53,54 +55,58 @@ export default function Images({ question }: Props) {
|
|||||||
gap: 1,
|
gap: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{question.content.variants.map((variant, index) => (
|
{question.content.variants
|
||||||
<ButtonBase
|
.filter(({ answer }) => answer)
|
||||||
key={index}
|
.map((variant, index) => (
|
||||||
onClick={() => handleVariantClick(index)}
|
<ButtonBase
|
||||||
sx={{
|
key={index}
|
||||||
display: "flex",
|
onClick={() => handleVariantClick(index)}
|
||||||
flexDirection: "column",
|
|
||||||
borderRadius: "8px",
|
|
||||||
overflow: "hidden",
|
|
||||||
border: "1px solid",
|
|
||||||
borderColor: selectedVariants.includes(index)
|
|
||||||
? theme.palette.brightPurple.main
|
|
||||||
: "#E3E3E3",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{variant.extendedText ? (
|
|
||||||
<img
|
|
||||||
src={variant.extendedText}
|
|
||||||
alt="question variant"
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
display: "block",
|
|
||||||
objectFit: "scale-down",
|
|
||||||
flexGrow: 1,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Typography p={2}>Картинка отсутствует</Typography>
|
|
||||||
)}
|
|
||||||
<Divider sx={{ width: "100%" }} />
|
|
||||||
<Box
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
flexDirection: "column",
|
||||||
justifyContent: "space-between",
|
borderRadius: "8px",
|
||||||
gap: 2,
|
overflow: "hidden",
|
||||||
p: 1,
|
border: "1px solid",
|
||||||
|
borderColor: selectedVariants.includes(index)
|
||||||
|
? theme.palette.brightPurple.main
|
||||||
|
: "#E3E3E3",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>{variant.answer}</Typography>
|
{variant.extendedText ? (
|
||||||
<Tooltip title="Подсказка" placement="right">
|
<img
|
||||||
<Box>
|
src={variant.extendedText}
|
||||||
<InfoIcon />
|
alt="question variant"
|
||||||
</Box>
|
style={{
|
||||||
</Tooltip>
|
width: "100%",
|
||||||
</Box>
|
display: "block",
|
||||||
</ButtonBase>
|
objectFit: "scale-down",
|
||||||
))}
|
flexGrow: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Typography p={2}>Картинка отсутствует</Typography>
|
||||||
|
)}
|
||||||
|
<Divider sx={{ width: "100%" }} />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
gap: 2,
|
||||||
|
p: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography>{variant.answer}</Typography>
|
||||||
|
{variant.hints && (
|
||||||
|
<Tooltip title={variant.hints} placement="right">
|
||||||
|
<Box>
|
||||||
|
<InfoIcon />
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</ButtonBase>
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,47 +1,52 @@
|
|||||||
import { Box, Typography } from "@mui/material";
|
|
||||||
import { CustomSlider } from "@ui_kit/CustomSlider";
|
|
||||||
import { QuizQuestionNumber } from "model/questionTypes/number";
|
|
||||||
import { useLayoutEffect, useState } from "react";
|
import { useLayoutEffect, useState } from "react";
|
||||||
|
import { Box, Typography } from "@mui/material";
|
||||||
|
|
||||||
|
import { CustomSlider } from "@ui_kit/CustomSlider";
|
||||||
|
|
||||||
|
import type { QuizQuestionNumber } from "model/questionTypes/number";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionNumber;
|
question: QuizQuestionNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Number({ question }: Props) {
|
export default function Number({ question }: Props) {
|
||||||
const [sliderValues, setSliderValues] = useState<number | number[]>(0);
|
const [sliderValues, setSliderValues] = useState<number | number[]>(0);
|
||||||
|
|
||||||
const start = question.content.start;
|
const start = question.content.start;
|
||||||
const min = parseInt(question.content.range.split("—")[0]);
|
const min = parseInt(question.content.range.split("—")[0]);
|
||||||
const max = parseInt(question.content.range.split("—")[1]);
|
const max = parseInt(question.content.range.split("—")[1]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (question.content.chooseRange) {
|
if (question.content.chooseRange) {
|
||||||
setSliderValues([start, start + (max - start) / 2]);
|
setSliderValues([start, start + (max - start) / 2]);
|
||||||
} else {
|
} else {
|
||||||
setSliderValues(start);
|
setSliderValues(start);
|
||||||
}
|
}
|
||||||
}, [max, question.content.chooseRange, start]);
|
}, [max, question.content.chooseRange, start]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box
|
||||||
display: "flex",
|
sx={{
|
||||||
flexDirection: "column",
|
display: "flex",
|
||||||
gap: 1,
|
flexDirection: "column",
|
||||||
}}>
|
gap: 1,
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
}}
|
||||||
<Box sx={{
|
>
|
||||||
px: 2,
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
}}>
|
<Box
|
||||||
<CustomSlider
|
sx={{
|
||||||
value={sliderValues}
|
px: 2,
|
||||||
onChange={value => setSliderValues(value)}
|
}}
|
||||||
min={min}
|
>
|
||||||
max={max}
|
<CustomSlider
|
||||||
defaultValue={start}
|
value={sliderValues}
|
||||||
step={question.content.step}
|
onChange={(value) => setSliderValues(value)}
|
||||||
/>
|
min={min}
|
||||||
</Box>
|
max={max}
|
||||||
</Box>
|
defaultValue={start}
|
||||||
);
|
step={question.content.step}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,34 +1,35 @@
|
|||||||
import { Box, Typography } from "@mui/material";
|
import { Box, Typography } from "@mui/material";
|
||||||
import { QuizQuestionPage } from "model/questionTypes/page";
|
|
||||||
|
|
||||||
|
import type { QuizQuestionPage } from "model/questionTypes/page";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionPage;
|
question: QuizQuestionPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Page({ question }: Props) {
|
export default function Page({ question }: Props) {
|
||||||
|
return (
|
||||||
return (
|
<Box
|
||||||
<Box sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
alignItems: "start",
|
alignItems: "start",
|
||||||
gap: 1,
|
gap: 1,
|
||||||
}}>
|
}}
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
>
|
||||||
<Typography>{question.content.text}</Typography>
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
{question.content.picture &&
|
<Typography>{question.content.text}</Typography>
|
||||||
<img
|
{question.content.picture && (
|
||||||
src={question.content.picture}
|
<img
|
||||||
alt=""
|
src={question.content.picture}
|
||||||
style={{
|
alt=""
|
||||||
width: "100%",
|
style={{
|
||||||
display: "block",
|
width: "100%",
|
||||||
objectFit: "scale-down",
|
display: "block",
|
||||||
flexGrow: 1,
|
objectFit: "scale-down",
|
||||||
}}
|
flexGrow: 1,
|
||||||
/>
|
}}
|
||||||
}
|
/>
|
||||||
</Box>
|
)}
|
||||||
);
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,91 +1,113 @@
|
|||||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
||||||
import { FC, useState } from "react";
|
import { FC, useState } from "react";
|
||||||
import FlagIcon from "../../../assets/icons/questionsPage/FlagIcon";
|
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||||
import StarIconMini from "../../../assets/icons/questionsPage/StarIconMini";
|
|
||||||
import HashtagIcon from "../../../assets/icons/questionsPage/hashtagIcon";
|
|
||||||
import HeartIcon from "../../../assets/icons/questionsPage/heartIcon";
|
|
||||||
import LightbulbIcon from "../../../assets/icons/questionsPage/lightbulbIcon";
|
|
||||||
import LikeIcon from "../../../assets/icons/questionsPage/likeIcon";
|
|
||||||
import TropfyIcon from "../../../assets/icons/questionsPage/tropfyIcon";
|
|
||||||
import { QuizQuestionRating } from "model/questionTypes/rating";
|
|
||||||
|
|
||||||
|
import FlagIcon from "@icons/questionsPage/FlagIcon";
|
||||||
|
import StarIconMini from "@icons/questionsPage/StarIconMini";
|
||||||
|
import HashtagIcon from "@icons/questionsPage/hashtagIcon";
|
||||||
|
import HeartIcon from "@icons/questionsPage/heartIcon";
|
||||||
|
import LightbulbIcon from "@icons/questionsPage/lightbulbIcon";
|
||||||
|
import LikeIcon from "@icons/questionsPage/likeIcon";
|
||||||
|
import TropfyIcon from "@icons/questionsPage/tropfyIcon";
|
||||||
|
|
||||||
type RatingIconType = "star" | "trophie" | "flag" | "heart" | "like" | "bubble" | "hashtag";
|
import type { QuizQuestionRating } from "model/questionTypes/rating";
|
||||||
|
|
||||||
const ratingIconComponentByType: Record<RatingIconType, FC<{ color: string; }>> = {
|
type RatingIconType =
|
||||||
"star": StarIconMini,
|
| "star"
|
||||||
"trophie": TropfyIcon,
|
| "trophie"
|
||||||
"flag": FlagIcon,
|
| "flag"
|
||||||
"heart": HeartIcon,
|
| "heart"
|
||||||
"like": LikeIcon,
|
| "like"
|
||||||
"bubble": LightbulbIcon,
|
| "bubble"
|
||||||
"hashtag": HashtagIcon,
|
| "hashtag";
|
||||||
|
|
||||||
|
const ratingIconComponentByType: Record<
|
||||||
|
RatingIconType,
|
||||||
|
FC<{ color: string }>
|
||||||
|
> = {
|
||||||
|
star: StarIconMini,
|
||||||
|
trophie: TropfyIcon,
|
||||||
|
flag: FlagIcon,
|
||||||
|
heart: HeartIcon,
|
||||||
|
like: LikeIcon,
|
||||||
|
bubble: LightbulbIcon,
|
||||||
|
hashtag: HashtagIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionRating;
|
question: QuizQuestionRating;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Rating({ question }: Props) {
|
export default function Rating({ question }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||||
const [selectedRating, setSelectedRating] = useState<number>(0);
|
const [selectedRating, setSelectedRating] = useState<number>(0);
|
||||||
|
|
||||||
console.log(question);
|
console.log(question);
|
||||||
|
|
||||||
const RatingIconComponent = ratingIconComponentByType[question.content.form as RatingIconType];
|
const RatingIconComponent =
|
||||||
|
ratingIconComponentByType[question.content.form as RatingIconType];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 1,
|
||||||
|
width: "fit-content",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
gap: isMobile ? "10px" : "15px",
|
||||||
gap: 1,
|
flexWrap: "wrap",
|
||||||
}}>
|
}}
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
>
|
||||||
<Box sx={{
|
{Array.from(
|
||||||
display: "flex",
|
{ length: question.content.steps },
|
||||||
flexDirection: "column",
|
(_, index) => index
|
||||||
gap: 1,
|
).map((itemNumber) => (
|
||||||
width: "fit-content",
|
<Box
|
||||||
}}>
|
key={itemNumber}
|
||||||
<Box sx={{
|
onClick={() => setSelectedRating(itemNumber + 1)}
|
||||||
display: "flex",
|
sx={{
|
||||||
gap: isMobile ? "10px" : "15px",
|
cursor: "pointer",
|
||||||
flexWrap: "wrap",
|
transform: "scale(1.5)",
|
||||||
}}>
|
":hover": {
|
||||||
{Array.from(
|
transform: "scale(1.7)",
|
||||||
{ length: question.content.steps },
|
transition: "0.2s",
|
||||||
(_, index) => index
|
},
|
||||||
).map((itemNumber) => (
|
}}
|
||||||
<Box
|
>
|
||||||
key={itemNumber}
|
<RatingIconComponent
|
||||||
onClick={() => setSelectedRating(itemNumber + 1)}
|
color={
|
||||||
sx={{
|
selectedRating > itemNumber
|
||||||
cursor: "pointer",
|
? theme.palette.brightPurple.main
|
||||||
transform: "scale(1.5)",
|
: theme.palette.grey2.main
|
||||||
":hover": {
|
}
|
||||||
transform: "scale(1.7)",
|
/>
|
||||||
transition: "0.2s",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RatingIconComponent color={
|
|
||||||
selectedRating > itemNumber
|
|
||||||
? theme.palette.brightPurple.main
|
|
||||||
: theme.palette.grey2.main
|
|
||||||
} />
|
|
||||||
</Box>
|
|
||||||
))}
|
|
||||||
</Box>
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
gap: 2,
|
|
||||||
}}>
|
|
||||||
<Typography>{question.content.ratingNegativeDescription}</Typography>
|
|
||||||
<Typography>{question.content.ratingPositiveDescription}</Typography>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
gap: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography>{question.content.ratingNegativeDescription}</Typography>
|
||||||
|
<Typography>{question.content.ratingPositiveDescription}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,102 +1,124 @@
|
|||||||
import ArrowDownIcon from "@icons/ArrowDownIcon";
|
|
||||||
import { Box, FormControl, MenuItem, Select, SelectChangeEvent, Typography, useTheme } from "@mui/material";
|
|
||||||
import { QuizQuestionSelect } from "model/questionTypes/select";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
FormControl,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
SelectChangeEvent,
|
||||||
|
Typography,
|
||||||
|
useTheme,
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
|
import ArrowDownIcon from "@icons/ArrowDownIcon";
|
||||||
|
|
||||||
|
import type { QuizQuestionSelect } from "model/questionTypes/select";
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionSelect;
|
question: QuizQuestionSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Text({ question }: Props) {
|
export default function Text({ question }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [selectValue, setSelectValue] = useState<string>("");
|
const [selectValue, setSelectValue] = useState<string>("");
|
||||||
|
|
||||||
function handleChange(event: SelectChangeEvent<string | null>) {
|
function handleChange(event: SelectChangeEvent<string | null>) {
|
||||||
setSelectValue((event.target as HTMLInputElement).value);
|
setSelectValue((event.target as HTMLInputElement).value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box
|
||||||
display: "flex",
|
sx={{
|
||||||
flexDirection: "column",
|
display: "flex",
|
||||||
gap: 1,
|
flexDirection: "column",
|
||||||
}}>
|
gap: 1,
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
}}
|
||||||
<FormControl
|
>
|
||||||
fullWidth
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
size="small"
|
<FormControl
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
minWidth: "200px",
|
||||||
|
height: "48px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
id="category-select"
|
||||||
|
variant="outlined"
|
||||||
|
value={selectValue}
|
||||||
|
placeholder={question.content.default}
|
||||||
|
displayEmpty
|
||||||
|
onChange={handleChange}
|
||||||
|
sx={{
|
||||||
|
height: "48px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
|
border: `1px solid ${theme.palette.brightPurple.main} !important`,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
MenuProps={{
|
||||||
|
PaperProps: {
|
||||||
|
sx: {
|
||||||
|
mt: "8px",
|
||||||
|
p: "4px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
border: "1px solid #EEE4FC",
|
||||||
|
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MenuListProps: {
|
||||||
|
sx: {
|
||||||
|
py: 0,
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: "8px",
|
||||||
|
"& .Mui-selected": {
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
color: theme.palette.brightPurple.main,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
inputProps={{
|
||||||
|
sx: {
|
||||||
|
color: theme.palette.brightPurple.main,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
px: "9px",
|
||||||
|
gap: "20px",
|
||||||
|
"& + input": !selectValue && {
|
||||||
|
border: "none",
|
||||||
|
transform: "translateY(-50%)",
|
||||||
|
top: "50%",
|
||||||
|
left: "10px",
|
||||||
|
opacity: 1,
|
||||||
|
color: "#333",
|
||||||
|
fontSize: "16px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
IconComponent={(props) => <ArrowDownIcon {...props} />}
|
||||||
|
>
|
||||||
|
{question.content.variants
|
||||||
|
.filter(({ answer }) => answer)
|
||||||
|
.map((variant) => (
|
||||||
|
<MenuItem
|
||||||
|
key={variant.answer}
|
||||||
|
value={variant.answer}
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
display: "flex",
|
||||||
minWidth: "200px",
|
alignItems: "center",
|
||||||
height: "48px",
|
gap: "20px",
|
||||||
|
p: "4px",
|
||||||
|
borderRadius: "5px",
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Select
|
{variant.answer}
|
||||||
id="category-select"
|
</MenuItem>
|
||||||
variant="outlined"
|
))}
|
||||||
value={selectValue}
|
</Select>
|
||||||
displayEmpty
|
</FormControl>
|
||||||
onChange={handleChange}
|
</Box>
|
||||||
sx={{
|
);
|
||||||
height: "48px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: `1px solid ${theme.palette.brightPurple.main} !important`,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
MenuProps={{
|
|
||||||
PaperProps: {
|
|
||||||
sx: {
|
|
||||||
mt: "8px",
|
|
||||||
p: "4px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
border: "1px solid #EEE4FC",
|
|
||||||
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MenuListProps: {
|
|
||||||
sx: {
|
|
||||||
py: 0,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: "8px",
|
|
||||||
"& .Mui-selected": {
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
color: theme.palette.brightPurple.main,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
inputProps={{
|
|
||||||
sx: {
|
|
||||||
color: theme.palette.brightPurple.main,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
px: "9px",
|
|
||||||
gap: "20px",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
IconComponent={(props) => <ArrowDownIcon {...props} />}
|
|
||||||
>
|
|
||||||
{question.content.variants.map(variant => (
|
|
||||||
<MenuItem
|
|
||||||
key={variant.answer}
|
|
||||||
value={variant.answer}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "20px",
|
|
||||||
p: "4px",
|
|
||||||
borderRadius: "5px",
|
|
||||||
color: theme.palette.grey2.main,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{variant.answer}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,24 @@
|
|||||||
import { Box, Typography } from "@mui/material";
|
import { Box, Typography } from "@mui/material";
|
||||||
import CustomTextField from "@ui_kit/CustomTextField";
|
|
||||||
import { QuizQuestionText } from "model/questionTypes/text";
|
|
||||||
|
|
||||||
|
import CustomTextField from "@ui_kit/CustomTextField";
|
||||||
|
|
||||||
|
import type { QuizQuestionText } from "model/questionTypes/text";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionText;
|
question: QuizQuestionText;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Text({ question }: Props) {
|
export default function Text({ question }: Props) {
|
||||||
|
return (
|
||||||
return (
|
<Box
|
||||||
<Box sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: 1,
|
gap: 1,
|
||||||
}}>
|
}}
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
>
|
||||||
<CustomTextField
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
placeholder={question.content.placeholder}
|
<CustomTextField placeholder={question.content.placeholder} />
|
||||||
/>
|
</Box>
|
||||||
</Box>
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import { ChangeEvent, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -9,8 +9,10 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { QuizQuestionVariant } from "model/questionTypes/variant";
|
|
||||||
import { ChangeEvent, useState } from "react";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
|
|
||||||
|
import type { QuizQuestionVariant } from "model/questionTypes/variant";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionVariant;
|
question: QuizQuestionVariant;
|
||||||
@ -23,41 +25,46 @@ export default function Variant({ question }: Props) {
|
|||||||
setValue((event.target as HTMLInputElement).value);
|
setValue((event.target as HTMLInputElement).value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<FormLabel
|
<FormLabel id="quiz-question-radio-group" data-cy="variant-title">
|
||||||
id="quiz-question-radio-group"
|
{question.title}
|
||||||
data-cy="variant-title"
|
</FormLabel>
|
||||||
>{question.title}</FormLabel>
|
<RadioGroup
|
||||||
<RadioGroup
|
aria-labelledby="quiz-question-radio-group"
|
||||||
aria-labelledby="quiz-question-radio-group"
|
value={value}
|
||||||
value={value}
|
onChange={handleChange}
|
||||||
onChange={handleChange}
|
>
|
||||||
>
|
{question.content.variants
|
||||||
{question.content.variants.map((variant, index) => (
|
.filter(({ answer }) => answer)
|
||||||
<FormControlLabel
|
.map((variant, index) => (
|
||||||
key={index}
|
<FormControlLabel
|
||||||
value={variant.answer}
|
key={index}
|
||||||
control={<Radio
|
value={variant.answer}
|
||||||
inputProps={{
|
control={
|
||||||
"data-cy": "variant-radio",
|
<Radio
|
||||||
}}
|
inputProps={{
|
||||||
/>}
|
"data-cy": "variant-radio",
|
||||||
label={
|
}}
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
/>
|
||||||
<Typography
|
}
|
||||||
data-cy="variant-answer"
|
label={
|
||||||
>{variant.answer}</Typography>
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
<Tooltip title={variant.hints} placement="right">
|
<Typography data-cy="variant-answer">
|
||||||
<Box>
|
{variant.answer}
|
||||||
<InfoIcon />
|
</Typography>
|
||||||
</Box>
|
{variant.hints && (
|
||||||
</Tooltip>
|
<Tooltip title={variant.hints} placement="right">
|
||||||
</Box>
|
<Box>
|
||||||
}
|
<InfoIcon />
|
||||||
/>
|
</Box>
|
||||||
))}
|
</Tooltip>
|
||||||
</RadioGroup>
|
)}
|
||||||
</FormControl>
|
</Box>
|
||||||
);
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import { useState, ChangeEvent } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -9,9 +9,11 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { QuestionVariant } from "model/questionTypes/shared";
|
|
||||||
import { QuizQuestionVarImg } from "model/questionTypes/varimg";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
import { useState, ChangeEvent } from "react";
|
|
||||||
|
import type { QuestionVariant } from "model/questionTypes/shared";
|
||||||
|
import type { QuizQuestionVarImg } from "model/questionTypes/varimg";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionVarImg;
|
question: QuizQuestionVarImg;
|
||||||
@ -46,23 +48,27 @@ export default function Varimg({ question }: Props) {
|
|||||||
value={currentVariant?.answer ?? ""}
|
value={currentVariant?.answer ?? ""}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
{question.content.variants.map((variant, index) => (
|
{question.content.variants
|
||||||
<FormControlLabel
|
.filter(({ answer }) => answer)
|
||||||
key={index}
|
.map((variant, index) => (
|
||||||
value={variant.answer}
|
<FormControlLabel
|
||||||
control={<Radio />}
|
key={index}
|
||||||
label={
|
value={variant.answer}
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
control={<Radio />}
|
||||||
<Typography>{variant.answer}</Typography>
|
label={
|
||||||
<Tooltip title="Подсказка" placement="right">
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
<Box>
|
<Typography>{variant.answer}</Typography>
|
||||||
<InfoIcon />
|
{variant.hints && (
|
||||||
</Box>
|
<Tooltip title={variant.hints} placement="right">
|
||||||
</Tooltip>
|
<Box>
|
||||||
</Box>
|
<InfoIcon />
|
||||||
}
|
</Box>
|
||||||
/>
|
</Tooltip>
|
||||||
))}
|
)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<Box
|
<Box
|
||||||
|
|||||||
@ -7,7 +7,11 @@ interface Props {
|
|||||||
steps?: number;
|
steps?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ProgressMobileStepper({ desc, activeStep = 1, steps = 8 }: Props) {
|
export default function ProgressMobileStepper({
|
||||||
|
desc,
|
||||||
|
activeStep = 1,
|
||||||
|
steps = 8,
|
||||||
|
}: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
|
|
||||||
@ -18,7 +22,7 @@ export default function ProgressMobileStepper({ desc, activeStep = 1, steps = 8
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
height: "51px",
|
height: "73px",
|
||||||
borderRadius: "13px",
|
borderRadius: "13px",
|
||||||
border: "solid #7E2AEA 1px",
|
border: "solid #7E2AEA 1px",
|
||||||
padding: "0 0 20px 0",
|
padding: "0 0 20px 0",
|
||||||
@ -33,7 +37,7 @@ export default function ProgressMobileStepper({ desc, activeStep = 1, steps = 8
|
|||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
paddingLeft: 0,
|
padding: "8px 0",
|
||||||
"& .css-1ej0n1q-MuiLinearProgress-root-MuiMobileStepper-progress": {
|
"& .css-1ej0n1q-MuiLinearProgress-root-MuiMobileStepper-progress": {
|
||||||
height: "10px",
|
height: "10px",
|
||||||
background: "#ffffff",
|
background: "#ffffff",
|
||||||
@ -47,7 +51,9 @@ export default function ProgressMobileStepper({ desc, activeStep = 1, steps = 8
|
|||||||
backButton={<></>}
|
backButton={<></>}
|
||||||
/>
|
/>
|
||||||
<Box sx={{ padding: "3px 3px 3px 20px" }}>
|
<Box sx={{ padding: "3px 3px 3px 20px" }}>
|
||||||
<Typography sx={{ fontWeight: 400, fontSize: "12px", lineHeight: "14.22px" }}>
|
<Typography
|
||||||
|
sx={{ fontWeight: 400, fontSize: "12px", lineHeight: "14.22px" }}
|
||||||
|
>
|
||||||
{" "}
|
{" "}
|
||||||
Шаг {activeStep} из {steps - 1}
|
Шаг {activeStep} из {steps - 1}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user