add images to previews

This commit is contained in:
nflnkr 2023-12-06 19:41:17 +03:00
parent 27a76b3011
commit 9e92209088
6 changed files with 197 additions and 176 deletions

@ -29,8 +29,6 @@ export type QuizResultsType = true | null;
export interface QuizConfig {
type: QuizType;
logo: string | null;
originalLogo: string | null;
noStartPage: boolean;
startpageType: QuizStartpageType;
results: QuizResultsType;
@ -41,6 +39,8 @@ export interface QuizConfig {
position: QuizStartpageAlignType;
favIcon: string | null;
originalFavIcon: string | null;
logo: string | null;
originalLogo: string | null;
background: {
type: null | "image" | "video";
desktop: string | null;
@ -63,8 +63,6 @@ export interface QuizConfig {
export const defaultQuizConfig: QuizConfig = {
type: null,
logo: null,
originalLogo: null,
noStartPage: false,
startpageType: null,
results: null,
@ -75,6 +73,8 @@ export const defaultQuizConfig: QuizConfig = {
position: "left",
favIcon: null,
originalFavIcon: null,
logo: null,
originalLogo: null,
background: {
type: null,
desktop: null,

@ -582,22 +582,22 @@ export default function StartPageSettings() {
<DropZone
text={"5 MB максимум"}
sx={{ maxWidth: "300px" }}
imageUrl={quiz.config.logo}
originalImageUrl={quiz.config.originalLogo}
imageUrl={quiz.config.startpage.logo}
originalImageUrl={quiz.config.startpage.originalLogo}
onImageUploadClick={file => {
uploadQuizImage(quiz.id, file, (quiz, url) => {
quiz.config.logo = url;
quiz.config.originalLogo = url;
quiz.config.startpage.logo = url;
quiz.config.startpage.originalLogo = url;
});
}}
onImageSaveClick={file => {
uploadQuizImage(quiz.id, file, (quiz, url) => {
quiz.config.logo = url;
quiz.config.startpage.logo = url;
});
}}
onDeleteClick={() => {
updateQuiz(quiz.id, quiz => {
quiz.config.logo = null;
quiz.config.startpage.logo = null;
});
}}
/>
@ -664,22 +664,22 @@ export default function StartPageSettings() {
<DropZone
text={"5 MB максимум"}
sx={{ maxWidth: "300px" }}
imageUrl={quiz.config.logo}
originalImageUrl={quiz.config.originalLogo}
imageUrl={quiz.config.startpage.logo}
originalImageUrl={quiz.config.startpage.originalLogo}
onImageUploadClick={file => {
uploadQuizImage(quiz.id, file, (quiz, url) => {
quiz.config.logo = url;
quiz.config.originalLogo = url;
quiz.config.startpage.logo = url;
quiz.config.startpage.originalLogo = url;
});
}}
onImageSaveClick={file => {
uploadQuizImage(quiz.id, file, (quiz, url) => {
quiz.config.logo = url;
quiz.config.startpage.logo = url;
});
}}
onDeleteClick={() => {
updateQuiz(quiz.id, quiz => {
quiz.config.logo = null;
quiz.config.startpage.logo = null;
});
}}
/>

@ -219,9 +219,9 @@ export default function QuizPreviewLayout() {
}
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) {
case "variant": return <Variant question={question} />;

@ -1,13 +1,13 @@
import { ChangeEvent, useState } from "react";
import {
Box,
FormControl,
FormControlLabel,
FormLabel,
Radio,
RadioGroup,
Tooltip,
Typography,
Box,
FormControl,
FormControlLabel,
FormLabel,
Radio,
RadioGroup,
Tooltip,
Typography,
} from "@mui/material";
import InfoIcon from "@icons/InfoIcon";
@ -15,57 +15,68 @@ import InfoIcon from "@icons/InfoIcon";
import type { QuizQuestionVariant } from "model/questionTypes/variant";
interface Props {
question: QuizQuestionVariant;
question: QuizQuestionVariant;
}
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>) => {
setValue((event.target as HTMLInputElement).value);
};
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setValue((event.target as HTMLInputElement).value);
};
return (
<FormControl fullWidth>
<FormLabel id="quiz-question-radio-group" data-cy="question-title">
{question.title}
</FormLabel>
<RadioGroup
aria-labelledby="quiz-question-radio-group"
value={value}
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>
}
return (
<Box sx={{
display: "flex",
flexDirection: "column",
gap: 1,
}}>
<Typography>{question.title}</Typography>
<RadioGroup
aria-labelledby="quiz-question-radio-group"
value={value}
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>
<img
src={question.content.back}
style={{
display: "block",
objectFit: "scale-down",
alignSelf: "start",
maxWidth: "100%",
}}
/>
))}
</RadioGroup>
</FormControl>
);
</Box>
);
}

@ -1,13 +1,13 @@
import { useState, ChangeEvent } from "react";
import { useState, ChangeEvent, useEffect } from "react";
import {
Box,
FormControl,
FormControlLabel,
FormLabel,
Radio,
RadioGroup,
Tooltip,
Typography,
Box,
FormControl,
FormControlLabel,
FormLabel,
Radio,
RadioGroup,
Tooltip,
Typography,
} from "@mui/material";
import InfoIcon from "@icons/InfoIcon";
@ -16,103 +16,113 @@ import type { QuestionVariant } from "model/questionTypes/shared";
import type { QuizQuestionVarImg } from "model/questionTypes/varimg";
interface Props {
question: QuizQuestionVarImg;
question: QuizQuestionVarImg;
}
export default function Varimg({ question }: Props) {
const [selectedVariantIndex, setSelectedVariantIndex] = useState<number>(-1);
const [selectedVariantIndex, setSelectedVariantIndex] = useState<number>(-1);
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setSelectedVariantIndex(
question.content.variants.findIndex(
(variant) => variant.answer === event.target.value
)
);
};
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setSelectedVariantIndex(
question.content.variants.findIndex(
(variant) => variant.answer === event.target.value
)
);
};
const currentVariant: QuestionVariant | undefined =
question.content.variants[selectedVariantIndex];
const currentVariant: QuestionVariant | undefined =
question.content.variants[selectedVariantIndex];
return (
<Box
sx={{
display: "flex",
flexWrap: "wrap",
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,
return (
<Box
sx={{
display: "flex",
flexWrap: "wrap",
gap: 2,
}}
/>
) : (
<Typography p={2}>
{selectedVariantIndex === -1
? "Выберите вариант"
: "Картинка отсутствует"}
</Typography>
)}
</Box>
</Box>
);
>
<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",
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.desktop && (
quiz.config.startpage.logo && (
<img
src={quiz.config.startpage.background.desktop}
src={quiz.config.startpage.logo}
style={{
height: "30px",
maxWidth: "50px",