add images to previews
This commit is contained in:
parent
27a76b3011
commit
9e92209088
@ -29,8 +29,6 @@ export type QuizResultsType = true | null;
|
|||||||
|
|
||||||
export interface QuizConfig {
|
export interface QuizConfig {
|
||||||
type: QuizType;
|
type: QuizType;
|
||||||
logo: string | null;
|
|
||||||
originalLogo: string | null;
|
|
||||||
noStartPage: boolean;
|
noStartPage: boolean;
|
||||||
startpageType: QuizStartpageType;
|
startpageType: QuizStartpageType;
|
||||||
results: QuizResultsType;
|
results: QuizResultsType;
|
||||||
@ -41,6 +39,8 @@ export interface QuizConfig {
|
|||||||
position: QuizStartpageAlignType;
|
position: QuizStartpageAlignType;
|
||||||
favIcon: string | null;
|
favIcon: string | null;
|
||||||
originalFavIcon: string | null;
|
originalFavIcon: string | null;
|
||||||
|
logo: string | null;
|
||||||
|
originalLogo: string | null;
|
||||||
background: {
|
background: {
|
||||||
type: null | "image" | "video";
|
type: null | "image" | "video";
|
||||||
desktop: string | null;
|
desktop: string | null;
|
||||||
@ -63,8 +63,6 @@ export interface QuizConfig {
|
|||||||
|
|
||||||
export const defaultQuizConfig: QuizConfig = {
|
export const defaultQuizConfig: QuizConfig = {
|
||||||
type: null,
|
type: null,
|
||||||
logo: null,
|
|
||||||
originalLogo: null,
|
|
||||||
noStartPage: false,
|
noStartPage: false,
|
||||||
startpageType: null,
|
startpageType: null,
|
||||||
results: null,
|
results: null,
|
||||||
@ -75,6 +73,8 @@ export const defaultQuizConfig: QuizConfig = {
|
|||||||
position: "left",
|
position: "left",
|
||||||
favIcon: null,
|
favIcon: null,
|
||||||
originalFavIcon: null,
|
originalFavIcon: null,
|
||||||
|
logo: null,
|
||||||
|
originalLogo: null,
|
||||||
background: {
|
background: {
|
||||||
type: null,
|
type: null,
|
||||||
desktop: null,
|
desktop: null,
|
||||||
|
|||||||
@ -582,22 +582,22 @@ export default function StartPageSettings() {
|
|||||||
<DropZone
|
<DropZone
|
||||||
text={"5 MB максимум"}
|
text={"5 MB максимум"}
|
||||||
sx={{ maxWidth: "300px" }}
|
sx={{ maxWidth: "300px" }}
|
||||||
imageUrl={quiz.config.logo}
|
imageUrl={quiz.config.startpage.logo}
|
||||||
originalImageUrl={quiz.config.originalLogo}
|
originalImageUrl={quiz.config.startpage.originalLogo}
|
||||||
onImageUploadClick={file => {
|
onImageUploadClick={file => {
|
||||||
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
||||||
quiz.config.logo = url;
|
quiz.config.startpage.logo = url;
|
||||||
quiz.config.originalLogo = url;
|
quiz.config.startpage.originalLogo = url;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onImageSaveClick={file => {
|
onImageSaveClick={file => {
|
||||||
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
||||||
quiz.config.logo = url;
|
quiz.config.startpage.logo = url;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onDeleteClick={() => {
|
onDeleteClick={() => {
|
||||||
updateQuiz(quiz.id, quiz => {
|
updateQuiz(quiz.id, quiz => {
|
||||||
quiz.config.logo = null;
|
quiz.config.startpage.logo = null;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -664,22 +664,22 @@ export default function StartPageSettings() {
|
|||||||
<DropZone
|
<DropZone
|
||||||
text={"5 MB максимум"}
|
text={"5 MB максимум"}
|
||||||
sx={{ maxWidth: "300px" }}
|
sx={{ maxWidth: "300px" }}
|
||||||
imageUrl={quiz.config.logo}
|
imageUrl={quiz.config.startpage.logo}
|
||||||
originalImageUrl={quiz.config.originalLogo}
|
originalImageUrl={quiz.config.startpage.originalLogo}
|
||||||
onImageUploadClick={file => {
|
onImageUploadClick={file => {
|
||||||
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
||||||
quiz.config.logo = url;
|
quiz.config.startpage.logo = url;
|
||||||
quiz.config.originalLogo = url;
|
quiz.config.startpage.originalLogo = url;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onImageSaveClick={file => {
|
onImageSaveClick={file => {
|
||||||
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
uploadQuizImage(quiz.id, file, (quiz, url) => {
|
||||||
quiz.config.logo = url;
|
quiz.config.startpage.logo = url;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onDeleteClick={() => {
|
onDeleteClick={() => {
|
||||||
updateQuiz(quiz.id, quiz => {
|
updateQuiz(quiz.id, quiz => {
|
||||||
quiz.config.logo = null;
|
quiz.config.startpage.logo = null;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -219,9 +219,9 @@ export default function QuizPreviewLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function QuestionPreviewComponent({ question }: {
|
function QuestionPreviewComponent({ question }: {
|
||||||
question: AnyTypedQuizQuestion | UntypedQuizQuestion;
|
question: AnyTypedQuizQuestion | UntypedQuizQuestion | undefined;
|
||||||
}) {
|
}) {
|
||||||
if (question.type === null) return null;
|
if (!question || question.type === null) return null;
|
||||||
|
|
||||||
switch (question.type) {
|
switch (question.type) {
|
||||||
case "variant": return <Variant question={question} />;
|
case "variant": return <Variant question={question} />;
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { ChangeEvent, useState } from "react";
|
import { ChangeEvent, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Radio,
|
Radio,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
||||||
import InfoIcon from "@icons/InfoIcon";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
@ -15,57 +15,68 @@ import InfoIcon from "@icons/InfoIcon";
|
|||||||
import type { QuizQuestionVariant } from "model/questionTypes/variant";
|
import type { QuizQuestionVariant } from "model/questionTypes/variant";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionVariant;
|
question: QuizQuestionVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Variant({ question }: Props) {
|
export default function Variant({ question }: Props) {
|
||||||
const [value, setValue] = useState<string | null>(null);
|
const [value, setValue] = useState<string | null>(null);
|
||||||
|
|
||||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setValue((event.target as HTMLInputElement).value);
|
setValue((event.target as HTMLInputElement).value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl fullWidth>
|
<Box sx={{
|
||||||
<FormLabel id="quiz-question-radio-group" data-cy="question-title">
|
display: "flex",
|
||||||
{question.title}
|
flexDirection: "column",
|
||||||
</FormLabel>
|
gap: 1,
|
||||||
<RadioGroup
|
}}>
|
||||||
aria-labelledby="quiz-question-radio-group"
|
<Typography>{question.title}</Typography>
|
||||||
value={value}
|
<RadioGroup
|
||||||
onChange={handleChange}
|
aria-labelledby="quiz-question-radio-group"
|
||||||
>
|
value={value}
|
||||||
{question.content.variants
|
onChange={handleChange}
|
||||||
.filter(({ answer }) => answer)
|
>
|
||||||
.map((variant, index) => (
|
{question.content.variants
|
||||||
<FormControlLabel
|
.filter(({ answer }) => answer)
|
||||||
key={index}
|
.map((variant, index) => (
|
||||||
value={variant.answer}
|
<FormControlLabel
|
||||||
data-cy="variant-answer"
|
key={index}
|
||||||
control={
|
value={variant.answer}
|
||||||
<Radio
|
data-cy="variant-answer"
|
||||||
inputProps={{
|
control={
|
||||||
"data-cy": "variant-radio",
|
<Radio
|
||||||
}}
|
inputProps={{
|
||||||
/>
|
"data-cy": "variant-radio",
|
||||||
}
|
}}
|
||||||
label={
|
/>
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
}
|
||||||
<Typography>
|
label={
|
||||||
{variant.answer}
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
</Typography>
|
<Typography>
|
||||||
{variant.hints && (
|
{variant.answer}
|
||||||
<Tooltip title={variant.hints} placement="right">
|
</Typography>
|
||||||
<Box>
|
{variant.hints && (
|
||||||
<InfoIcon />
|
<Tooltip title={variant.hints} placement="right">
|
||||||
</Box>
|
<Box>
|
||||||
</Tooltip>
|
<InfoIcon />
|
||||||
)}
|
</Box>
|
||||||
</Box>
|
</Tooltip>
|
||||||
}
|
)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
<img
|
||||||
|
src={question.content.back}
|
||||||
|
style={{
|
||||||
|
display: "block",
|
||||||
|
objectFit: "scale-down",
|
||||||
|
alignSelf: "start",
|
||||||
|
maxWidth: "100%",
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
</Box>
|
||||||
</RadioGroup>
|
);
|
||||||
</FormControl>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { useState, ChangeEvent } from "react";
|
import { useState, ChangeEvent, useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Radio,
|
Radio,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
||||||
import InfoIcon from "@icons/InfoIcon";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
@ -16,103 +16,113 @@ import type { QuestionVariant } from "model/questionTypes/shared";
|
|||||||
import type { QuizQuestionVarImg } from "model/questionTypes/varimg";
|
import type { QuizQuestionVarImg } from "model/questionTypes/varimg";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionVarImg;
|
question: QuizQuestionVarImg;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Varimg({ question }: Props) {
|
export default function Varimg({ question }: Props) {
|
||||||
const [selectedVariantIndex, setSelectedVariantIndex] = useState<number>(-1);
|
const [selectedVariantIndex, setSelectedVariantIndex] = useState<number>(-1);
|
||||||
|
|
||||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setSelectedVariantIndex(
|
setSelectedVariantIndex(
|
||||||
question.content.variants.findIndex(
|
question.content.variants.findIndex(
|
||||||
(variant) => variant.answer === event.target.value
|
(variant) => variant.answer === event.target.value
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentVariant: QuestionVariant | undefined =
|
const currentVariant: QuestionVariant | undefined =
|
||||||
question.content.variants[selectedVariantIndex];
|
question.content.variants[selectedVariantIndex];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
gap: 2,
|
gap: 2,
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<FormLabel
|
|
||||||
id="quiz-question-radio-group"
|
|
||||||
data-cy="question-title"
|
|
||||||
>
|
|
||||||
{question.title}
|
|
||||||
</FormLabel>
|
|
||||||
<RadioGroup
|
|
||||||
aria-labelledby="quiz-question-radio-group"
|
|
||||||
value={currentVariant?.answer ?? ""}
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
{question.content.variants
|
|
||||||
.filter(({ answer }) => answer)
|
|
||||||
.map((variant, index) => (
|
|
||||||
<FormControlLabel
|
|
||||||
key={index}
|
|
||||||
value={variant.answer}
|
|
||||||
data-cy="variant-answer"
|
|
||||||
control={
|
|
||||||
<Radio
|
|
||||||
inputProps={{
|
|
||||||
"data-cy": "variant-radio",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
|
||||||
<Typography>{variant.answer}</Typography>
|
|
||||||
{variant.hints && (
|
|
||||||
<Tooltip title={variant.hints} placement="right">
|
|
||||||
<Box>
|
|
||||||
<InfoIcon />
|
|
||||||
</Box>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</RadioGroup>
|
|
||||||
</FormControl>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
border: "1px solid #E3E3E3",
|
|
||||||
maxWidth: "400px",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
borderRadius: "8px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{currentVariant?.extendedText ? (
|
|
||||||
<img
|
|
||||||
src={currentVariant.extendedText}
|
|
||||||
data-cy="variant-image"
|
|
||||||
alt="question variant"
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
display: "block",
|
|
||||||
objectFit: "scale-down",
|
|
||||||
flexGrow: 1,
|
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
) : (
|
<FormControl>
|
||||||
<Typography p={2}>
|
<FormLabel
|
||||||
{selectedVariantIndex === -1
|
id="quiz-question-radio-group"
|
||||||
? "Выберите вариант"
|
data-cy="question-title"
|
||||||
: "Картинка отсутствует"}
|
>
|
||||||
</Typography>
|
{question.title}
|
||||||
)}
|
</FormLabel>
|
||||||
</Box>
|
<RadioGroup
|
||||||
</Box>
|
aria-labelledby="quiz-question-radio-group"
|
||||||
);
|
value={currentVariant?.answer ?? ""}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
{question.content.variants
|
||||||
|
.filter(({ answer }) => answer)
|
||||||
|
.map((variant, index) => (
|
||||||
|
<FormControlLabel
|
||||||
|
key={index}
|
||||||
|
value={variant.answer}
|
||||||
|
data-cy="variant-answer"
|
||||||
|
control={
|
||||||
|
<Radio
|
||||||
|
inputProps={{
|
||||||
|
"data-cy": "variant-radio",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
|
<Typography>{variant.answer}</Typography>
|
||||||
|
{variant.hints && (
|
||||||
|
<Tooltip title={variant.hints} placement="right">
|
||||||
|
<Box>
|
||||||
|
<InfoIcon />
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
border: "1px solid #E3E3E3",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentVariant ?
|
||||||
|
currentVariant.extendedText ? (
|
||||||
|
<img
|
||||||
|
src={currentVariant.extendedText}
|
||||||
|
data-cy="variant-image"
|
||||||
|
alt="question variant"
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
display: "block",
|
||||||
|
objectFit: "scale-down",
|
||||||
|
flexGrow: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Typography p={2}>Картинка отсутствует</Typography>
|
||||||
|
) : question.content.back ? (
|
||||||
|
<img
|
||||||
|
src={question.content.back}
|
||||||
|
data-cy="variant-image"
|
||||||
|
alt="question variant"
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
display: "block",
|
||||||
|
objectFit: "scale-down",
|
||||||
|
flexGrow: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Typography p={2}>Выберите вариант</Typography>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,9 +53,9 @@ export default function QuizPreviewLayout() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{quiz.config.startpage.background.type === "image" &&
|
{quiz.config.startpage.background.type === "image" &&
|
||||||
quiz.config.startpage.background.desktop && (
|
quiz.config.startpage.logo && (
|
||||||
<img
|
<img
|
||||||
src={quiz.config.startpage.background.desktop}
|
src={quiz.config.startpage.logo}
|
||||||
style={{
|
style={{
|
||||||
height: "30px",
|
height: "30px",
|
||||||
maxWidth: "50px",
|
maxWidth: "50px",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user