менюшка для удаления, нумерация вопросов, селект в превью
This commit is contained in:
parent
a169dd0a49
commit
8b252dc6bc
@ -66,6 +66,7 @@ function DraggableListItem({ question, isDragging, index }: Props) {
|
|||||||
question={question}
|
question={question}
|
||||||
draggableProps={provided.dragHandleProps}
|
draggableProps={provided.dragHandleProps}
|
||||||
isDragging={isDragging}
|
isDragging={isDragging}
|
||||||
|
index={index}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -45,9 +45,10 @@ interface Props {
|
|||||||
question: AnyTypedQuizQuestion | UntypedQuizQuestion;
|
question: AnyTypedQuizQuestion | UntypedQuizQuestion;
|
||||||
draggableProps: DraggableProvidedDragHandleProps | null | undefined;
|
draggableProps: DraggableProvidedDragHandleProps | null | undefined;
|
||||||
isDragging: boolean;
|
isDragging: boolean;
|
||||||
|
index: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function QuestionsPageCard({ question, draggableProps, isDragging }: Props) {
|
export default function QuestionsPageCard({ question, draggableProps, isDragging, index }: Props) {
|
||||||
const [plusVisible, setPlusVisible] = useState<boolean>(false);
|
const [plusVisible, setPlusVisible] = useState<boolean>(false);
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -96,7 +97,7 @@ export default function QuestionsPageCard({ question, draggableProps, isDragging
|
|||||||
<TextField
|
<TextField
|
||||||
defaultValue={question.title}
|
defaultValue={question.title}
|
||||||
placeholder={"Заголовок вопроса"}
|
placeholder={"Заголовок вопроса"}
|
||||||
onChange={({ target }: {target: HTMLInputElement}) => setTitle(target.value)}
|
onChange={({ target }: { target: HTMLInputElement }) => setTitle(target.value)}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<Box>
|
<Box>
|
||||||
@ -262,17 +263,26 @@ export default function QuestionsPageCard({ question, draggableProps, isDragging
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
<Box
|
||||||
<OneIcon
|
|
||||||
style={{
|
style={{
|
||||||
fontSize: "30px",
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
height: "30px",
|
||||||
|
width: "30px",
|
||||||
marginLeft: "3px",
|
marginLeft: "3px",
|
||||||
color: !question.expanded ? "#FFF" : "",
|
borderRadius: "50%",
|
||||||
fill: question.expanded
|
fontSize: "16px",
|
||||||
|
color: question.expanded
|
||||||
|
? theme.palette.brightPurple.main
|
||||||
|
: "#FFF",
|
||||||
|
background: question.expanded
|
||||||
? "#EEE4FC"
|
? "#EEE4FC"
|
||||||
: theme.palette.brightPurple.main,
|
: theme.palette.brightPurple.main,
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{index + 1}
|
||||||
|
</Box>
|
||||||
<IconButton
|
<IconButton
|
||||||
disableRipple
|
disableRipple
|
||||||
sx={{
|
sx={{
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useState, useRef } from "react";
|
||||||
import ChartIcon from "@icons/ChartIcon";
|
import ChartIcon from "@icons/ChartIcon";
|
||||||
import LinkIcon from "@icons/LinkIcon";
|
import LinkIcon from "@icons/LinkIcon";
|
||||||
import PencilIcon from "@icons/PencilIcon";
|
import PencilIcon from "@icons/PencilIcon";
|
||||||
@ -10,6 +11,8 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
useTheme,
|
useTheme,
|
||||||
|
Popover,
|
||||||
|
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { deleteQuiz, setEditQuizId } from "@root/quizes/actions";
|
import { deleteQuiz, setEditQuizId } from "@root/quizes/actions";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@ -31,6 +34,8 @@ export default function QuizCard({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [subMenuOpen, setSubMenuOpen] = useState<boolean>(false);
|
||||||
|
const subMenuRef = useRef<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
function handleEditClick() {
|
function handleEditClick() {
|
||||||
setEditQuizId(quiz.backendId);
|
setEditQuizId(quiz.backendId);
|
||||||
@ -134,15 +139,45 @@ export default function QuizCard({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
ref={subMenuRef}
|
||||||
sx={{
|
sx={{
|
||||||
color: theme.palette.brightPurple.main,
|
color: theme.palette.brightPurple.main,
|
||||||
ml: "auto",
|
ml: "auto",
|
||||||
}}
|
}}
|
||||||
onClick={() => deleteQuiz(quiz.id)}
|
onClick={() => setSubMenuOpen(true)}
|
||||||
data-cy="delete-quiz"
|
data-cy="delete-quiz"
|
||||||
>
|
>
|
||||||
<MoreHorizIcon sx={{ transform: "scale(1.75)" }} />
|
<MoreHorizIcon sx={{ transform: "scale(1.75)" }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
<Popover
|
||||||
|
open={subMenuOpen}
|
||||||
|
anchorEl={subMenuRef.current}
|
||||||
|
onClose={() => setSubMenuOpen(false)}
|
||||||
|
anchorOrigin={{ vertical: "top", horizontal: "right" }}
|
||||||
|
>
|
||||||
|
<Box onClick={() => setSubMenuOpen(false)}>
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
display: "block",
|
||||||
|
width: "100%",
|
||||||
|
padding: "15px 30px",
|
||||||
|
}}
|
||||||
|
onClick={()=>{}}
|
||||||
|
>
|
||||||
|
Копировать
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
display: "block",
|
||||||
|
width: "100%",
|
||||||
|
padding: "15px 30px",
|
||||||
|
}}
|
||||||
|
onClick={() => deleteQuiz(quiz.id)}
|
||||||
|
>
|
||||||
|
Удалить
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Popover>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -28,6 +28,10 @@ export const toggleQuizPreview = () => useQuizPreviewStore.setState(
|
|||||||
state => ({ isPreviewShown: !state.isPreviewShown })
|
state => ({ isPreviewShown: !state.isPreviewShown })
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const setCurrentQuestionIndex = (step: number) => useQuizPreviewStore.setState(
|
||||||
|
state => ({ currentQuestionIndex:state.currentQuestionIndex = step })
|
||||||
|
);
|
||||||
|
|
||||||
export const incrementCurrentQuestionIndex = (maxStep: number) => useQuizPreviewStore.setState(
|
export const incrementCurrentQuestionIndex = (maxStep: number) => useQuizPreviewStore.setState(
|
||||||
state => ({ currentQuestionIndex: Math.min(state.currentQuestionIndex + 1, maxStep) })
|
state => ({ currentQuestionIndex: Math.min(state.currentQuestionIndex + 1, maxStep) })
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { Box, Button, LinearProgress, Paper, Typography } from "@mui/material";
|
import { Box, Button, LinearProgress, Paper, Typography, FormControl, Select as MuiSelect, MenuItem, useTheme } from "@mui/material";
|
||||||
import { useQuestionsStore } from "@root/questions/store";
|
import { useQuestionsStore } from "@root/questions/store";
|
||||||
import {
|
import {
|
||||||
decrementCurrentQuestionIndex,
|
decrementCurrentQuestionIndex,
|
||||||
incrementCurrentQuestionIndex,
|
incrementCurrentQuestionIndex,
|
||||||
useQuizPreviewStore,
|
useQuizPreviewStore,
|
||||||
|
setCurrentQuestionIndex
|
||||||
} from "@root/quizPreview";
|
} from "@root/quizPreview";
|
||||||
import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "model/questionTypes/shared";
|
import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "model/questionTypes/shared";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
@ -20,9 +21,10 @@ import Text from "./QuizPreviewQuestionTypes/Text";
|
|||||||
import Variant from "./QuizPreviewQuestionTypes/Variant";
|
import Variant from "./QuizPreviewQuestionTypes/Variant";
|
||||||
import Varimg from "./QuizPreviewQuestionTypes/Varimg";
|
import Varimg from "./QuizPreviewQuestionTypes/Varimg";
|
||||||
import { notReachable } from "../../utils/notReachable";
|
import { notReachable } from "../../utils/notReachable";
|
||||||
|
import ArrowDownIcon from "@icons/ArrowDownIcon";
|
||||||
|
|
||||||
export default function QuizPreviewLayout() {
|
export default function QuizPreviewLayout() {
|
||||||
|
const theme = useTheme();
|
||||||
const questions = useQuestionsStore(state => state.questions);
|
const questions = useQuestionsStore(state => state.questions);
|
||||||
const currentQuizStep = useQuizPreviewStore(
|
const currentQuizStep = useQuizPreviewStore(
|
||||||
(state) => state.currentQuestionIndex
|
(state) => state.currentQuestionIndex
|
||||||
@ -67,7 +69,9 @@ export default function QuizPreviewLayout() {
|
|||||||
whiteSpace: "break-spaces",
|
whiteSpace: "break-spaces",
|
||||||
overflowY: "auto",
|
overflowY: "auto",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
"&::-webkit-scrollbar": { width: 0 },
|
"&::-webkit-scrollbar": { width: 0, display: "none" },
|
||||||
|
msOverflowStyle: "none",
|
||||||
|
scrollbarWidth: "none",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<QuestionPreviewComponent question={currentQuestion} />
|
<QuestionPreviewComponent question={currentQuestion} />
|
||||||
@ -76,62 +80,138 @@ export default function QuizPreviewLayout() {
|
|||||||
sx={{
|
sx={{
|
||||||
mt: "auto",
|
mt: "auto",
|
||||||
p: "16px",
|
p: "16px",
|
||||||
display: "flex",
|
|
||||||
borderTop: "1px solid #E3E3E3",
|
borderTop: "1px solid #E3E3E3",
|
||||||
alignItems: "center",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box sx={{ marginBottom: "10px" }}>
|
||||||
sx={{
|
<FormControl
|
||||||
flexGrow: 1,
|
fullWidth
|
||||||
display: "flex",
|
size="small"
|
||||||
flexDirection: "column",
|
sx={{ width: "100%", minWidth: "200px", height: "48px" }}
|
||||||
gap: 1,
|
>
|
||||||
}}
|
<MuiSelect
|
||||||
>
|
id="category-select"
|
||||||
<Typography>
|
variant="outlined"
|
||||||
{nonDeletedQuizQuestions.length > 0
|
value={currentQuizStep}
|
||||||
? `Вопрос ${currentQuizStep + 1} из ${nonDeletedQuizQuestions.length
|
placeholder="Заголовок вопроса"
|
||||||
}`
|
onChange={({ target }) =>
|
||||||
: "Нет вопросов"}
|
setCurrentQuestionIndex(window.Number(target.value))
|
||||||
</Typography>
|
}
|
||||||
{nonDeletedQuizQuestions.length > 0 && (
|
|
||||||
<LinearProgress
|
|
||||||
variant="determinate"
|
|
||||||
value={currentProgress}
|
|
||||||
sx={{
|
sx={{
|
||||||
"&.MuiLinearProgress-colorPrimary": {
|
height: "48px",
|
||||||
backgroundColor: "fadePurple.main",
|
borderRadius: "8px",
|
||||||
},
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
"& .MuiLinearProgress-barColorPrimary": {
|
border: `1px solid ${theme.palette.brightPurple.main} !important`,
|
||||||
backgroundColor: "brightPurple.main",
|
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
MenuProps={{
|
||||||
)}
|
PaperProps: {
|
||||||
</Box>
|
sx: {
|
||||||
<Box
|
mt: "8px",
|
||||||
sx={{
|
p: "4px",
|
||||||
ml: 2,
|
borderRadius: "8px",
|
||||||
display: "flex",
|
border: "1px solid #EEE4FC",
|
||||||
gap: 1,
|
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
||||||
}}
|
},
|
||||||
>
|
},
|
||||||
<Button
|
MenuListProps: {
|
||||||
variant="outlined"
|
sx: {
|
||||||
onClick={decrementCurrentQuestionIndex}
|
py: 0,
|
||||||
disabled={currentQuizStep === 0}
|
display: "flex",
|
||||||
sx={{ px: 1, minWidth: 0 }}
|
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} />}
|
||||||
|
>
|
||||||
|
{Object.values(questions).map(
|
||||||
|
({ id, title }, index) => (
|
||||||
|
<MenuItem
|
||||||
|
key={id}
|
||||||
|
value={index}
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "20px",
|
||||||
|
p: "4px",
|
||||||
|
borderRadius: "5px",
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{`${index + 1}. ${title}`}
|
||||||
|
</MenuItem>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</MuiSelect>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
flexGrow: 1,
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<ArrowLeft />
|
<Typography>
|
||||||
</Button>
|
{nonDeletedQuizQuestions.length > 0
|
||||||
<Button
|
? `Вопрос ${currentQuizStep + 1} из ${nonDeletedQuizQuestions.length
|
||||||
variant="contained"
|
}`
|
||||||
onClick={() => incrementCurrentQuestionIndex(maxCurrentQuizStep)}
|
: "Нет вопросов"}
|
||||||
disabled={currentQuizStep >= maxCurrentQuizStep}
|
</Typography>
|
||||||
|
{nonDeletedQuizQuestions.length > 0 && (
|
||||||
|
<LinearProgress
|
||||||
|
variant="determinate"
|
||||||
|
value={currentProgress}
|
||||||
|
sx={{
|
||||||
|
"&.MuiLinearProgress-colorPrimary": {
|
||||||
|
backgroundColor: "fadePurple.main",
|
||||||
|
},
|
||||||
|
"& .MuiLinearProgress-barColorPrimary": {
|
||||||
|
backgroundColor: "brightPurple.main",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
ml: 2,
|
||||||
|
display: "flex",
|
||||||
|
gap: 1,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Далее
|
<Button
|
||||||
</Button>
|
variant="outlined"
|
||||||
|
onClick={decrementCurrentQuestionIndex}
|
||||||
|
disabled={currentQuizStep === 0}
|
||||||
|
sx={{ px: 1, minWidth: 0 }}
|
||||||
|
>
|
||||||
|
<ArrowLeft />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => incrementCurrentQuestionIndex(maxCurrentQuizStep)}
|
||||||
|
disabled={currentQuizStep >= maxCurrentQuizStep}
|
||||||
|
>
|
||||||
|
Далее
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user