fix: requests

This commit is contained in:
IlyaDoronin 2024-05-14 17:27:14 +03:00
parent a23181e7db
commit 7dc71b91e1
10 changed files with 343 additions and 321 deletions

@ -4,10 +4,15 @@ interface Props {
color?: string; color?: string;
bgcolor?: string; bgcolor?: string;
marL?: string; marL?: string;
width?: string width?: string;
} }
export default function CopyIcon({ color, bgcolor, marL, width = "36px" }: Props) { export default function CopyIcon({
color,
bgcolor,
marL,
width = "36px",
}: Props) {
const theme = useTheme(); const theme = useTheme();
return ( return (

@ -122,7 +122,7 @@ export const DesignFilling = ({
width: "100%", width: "100%",
borderRadius: "12px", borderRadius: "12px",
height: "calc(100vh - 300px)", height: "calc(100vh - 300px)",
mb: "76px" mb: "76px",
}} }}
> >
<Box <Box

@ -158,11 +158,14 @@ export default function QuizInstallationCard() {
<IconButton <IconButton
edge="end" edge="end"
sx={{ marginTop: "22px" }} sx={{ marginTop: "22px" }}
onClick={() => navigator.clipboard.writeText( // TODO onClick={() =>
navigator.clipboard.writeText(
// TODO
document.getElementById( document.getElementById(
"outlined-multiline-static" "outlined-multiline-static",
).value ).value,
)} )
}
> >
<CopyIcon <CopyIcon
color={"#ffffff"} color={"#ffffff"}

@ -136,8 +136,7 @@ export const VKPixelInstruction = () => {
<ListItem> <ListItem>
<Typography> <Typography>
Посетитель отправил заявку с заполненным полем Х: Посетитель отправил заявку с заполненным полем Х:
<b>penaquiz-formfield-X</b>, где X одно из полей. <b>penaquiz-formfield-X</b>, где X одно из полей. Например,
Например,
</Typography> </Typography>
</ListItem> </ListItem>
<List> <List>
@ -163,7 +162,8 @@ export const VKPixelInstruction = () => {
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography> <Typography>
<b>penaquiz</b>-formfield-text (это будет кастомное поле, которое вы настроили сами) <b>penaquiz</b>-formfield-text (это будет кастомное поле,
которое вы настроили сами)
</Typography> </Typography>
</ListItem> </ListItem>
</List> </List>

@ -132,8 +132,7 @@ export const YandexInstruction = () => {
<ListItem> <ListItem>
<Typography> <Typography>
Посетитель отправил заявку с заполненным полем Х: Посетитель отправил заявку с заполненным полем Х:
<b>penaquiz-formfield-X</b>, где X одно из полей. <b>penaquiz-formfield-X</b>, где X одно из полей. Например,
Например,
</Typography> </Typography>
</ListItem> </ListItem>
<List> <List>
@ -159,7 +158,8 @@ export const YandexInstruction = () => {
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography> <Typography>
<b>penaquiz</b>-formfield-text (это будет кастомное поле, которое вы настроили сами) <b>penaquiz</b>-formfield-text (это будет кастомное поле,
которое вы настроили сами)
</Typography> </Typography>
</ListItem> </ListItem>
</List> </List>

@ -168,10 +168,7 @@ export default function HowItWorks() {
}} }}
> >
<Icon21 /> <Icon21 />
<Typography fontSize="18px"> <Typography fontSize="18px"> на сайте</Typography>
{" "}
на сайте
</Typography>
</Box> </Box>
<Box <Box
sx={{ sx={{

@ -99,283 +99,290 @@ const QuestionPageCardTitle = memo<Props>(function ({
return ( return (
<> <>
<Box <Box
sx={{
display: "flex",
alignItems: "center",
padding: isMobile ? "10px" : "20px 10px 20px 20px",
flexDirection: "row",
flexWrap: isMobile && isExpanded ? "wrap" : "nowrap",
}}
>
<FormControl
variant="standard"
sx={{
p: 0,
maxWidth: isTablet ? "549px" : "640px",
width: "100%",
marginRight: isMobile ? "0px" : "16.1px",
display: "flex",
flexDirection: "row",
flexBasis: isMobile && isExpanded ? "calc(100% - 30px)" : null,
}}
>
<TextField
id="questionTitle"
value={title}
placeholder={"Заголовок вопроса"}
onChange={({ target }) => setTitle(target.value || " ")}
onFocus={handleInputFocus}
onBlur={handleInputBlur}
inputProps={{
maxLength: maxLengthTextField,
}}
InputProps={{
startAdornment: (
<Box>
<InputAdornment
ref={anchorRef}
position="start"
sx={{ cursor: "pointer" }}
onClick={() => setOpen((isOpened) => !isOpened)}
>
{IconAndrom(isExpanded, questionType)}
</InputAdornment>
<ChooseAnswerModal
open={open}
onClose={() => setOpen(false)}
anchorRef={anchorRef}
questionId={questionId}
questionContentId={questionContentId}
questionType={questionType}
/>
</Box>
),
endAdornment: isTextFieldtActive &&
title.length >= maxLengthTextField - 7 && (
<Box
sx={{
display: "flex",
marginTop: "5px",
marginLeft: "auto",
position: "absolute",
bottom: "-28px",
right: "0",
}}
>
<Typography fontSize="14px">{title.length}</Typography>
<span>/</span>
<Typography fontSize="14px">
{maxLengthTextField}
</Typography>
</Box>
),
}}
sx={{ sx={{
flexGrow: 1,
margin: isMobile ? "10px 0" : 0,
"& .MuiInputBase-root": {
color: "#000000",
backgroundColor: isExpanded
? theme.palette.background.default
: "transparent",
height: "48px",
borderRadius: "10px",
".MuiOutlinedInput-notchedOutline": {
borderWidth: "1px !important",
border: !isExpanded ? "none" : null,
},
"& .MuiInputBase-input::placeholder": {
color: "#4D4D4D",
opacity: 0.8,
},
},
}}
/>
</FormControl>
<IconButton
disableRipple
sx={{
order: isMobile && isExpanded ? "0" : "1",
padding: isMobile ? "0" : "0 5px",
right: isMobile ? "0" : null,
bottom: isMobile ? "0" : null,
marginLeft: !isMobile && isExpanded ? "10px" : null,
}}
{...draggableProps}
onMouseDown={collapseAllQuestions}
onTouchStart={collapseAllQuestions}
>
<PointsIcon style={{ color: "#4D4D4D", fontSize: "30px" }} />
</IconButton>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
width: isMobile ? "100%" : "auto",
position: "relative",
}}
>
<IconButton
sx={{ padding: "0", margin: "5px" }}
disableRipple
data-cy="expand-question"
onClick={() => toggleExpandQuestion(questionId)}
>
{isExpanded ? (
<ArrowDownIcon
style={{
width: "18px",
color: "#4D4D4D",
}}
/>
) : (
<ExpandLessIcon
sx={{
boxSizing: "border-box",
fill: theme.palette.brightPurple.main,
background: "#FFF",
borderRadius: "6px",
height: "30px",
width: "30px",
}}
/>
)}
</IconButton>
{isExpanded ? (
<></>
) : (
<Box
sx={{
display: "flex",
height: "30px",
borderRight: "solid 1px #4D4D4D",
}}
>
<IconButton
sx={{ padding: "0" }}
onClick={() => copyQuestion(questionId, quizId)}
>
<CopyIcon style={{ color: theme.palette.brightPurple.main }} />
</IconButton>
<IconButton
sx={{
cursor: "pointer",
borderRadius: "6px",
padding: "0",
margin: "0 5px 0 10px",
}}
onClick={() => {
if (questionType === null) {
deleteQuestion(questionId);
return;
}
if (questionHasParent) {
setOpenDelete(true);
} else {
deleteQuestionWithTimeout(questionId, () =>
DeleteFunction(questionId),
);
}
}}
data-cy="delete-question"
>
<DeleteIcon
style={{ color: theme.palette.brightPurple.main }}
/>
</IconButton>
<Modal open={openDelete} onClose={() => setOpenDelete(false)}>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
padding: "30px",
borderRadius: "10px",
background: "#FFFFFF",
}}
>
<Typography variant="h6" sx={{ textAlign: "center" }}>
Вы удаляете вопрос, участвующий в ветвлении. Все его потомки
потеряют данные ветвления. Вы уверены, что хотите удалить
вопрос?
</Typography>
<Box
sx={{
marginTop: "30px",
display: "flex",
justifyContent: "center",
gap: "15px",
}}
>
<Button
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => setOpenDelete(false)}
>
Отмена
</Button>
<Button
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => {
deleteQuestionWithTimeout(questionId, () =>
DeleteFunction(questionId),
);
}}
>
Подтвердить
</Button>
</Box>
</Box>
</Modal>
</Box>
)}
{page !== null && (
<Box
style={{
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
padding: isMobile ? "10px" : "20px 10px 20px 20px", justifyContent: "center",
flexDirection: "row", height: "30px",
flexWrap: isMobile && isExpanded ? "wrap" : "nowrap", width: "30px",
}} marginLeft: "3px",
> borderRadius: "50%",
<FormControl fontSize: "16px",
variant="standard" color: isExpanded ? theme.palette.brightPurple.main : "#FFF",
sx={{ background: isExpanded
p: 0, ? "#EEE4FC"
maxWidth: isTablet ? "549px" : "640px", : theme.palette.brightPurple.main,
width: "100%", }}
marginRight: isMobile ? "0px" : "16.1px",
display: "flex",
flexDirection: "row",
flexBasis: isMobile && isExpanded ? "calc(100% - 30px)" : null,
}}
> >
<TextField {page + 1}
id="questionTitle"
value={title}
placeholder={"Заголовок вопроса"}
onChange={({ target }) => setTitle(target.value || " ")}
onFocus={handleInputFocus}
onBlur={handleInputBlur}
inputProps={{
maxLength: maxLengthTextField,
}}
InputProps={{
startAdornment: (
<Box>
<InputAdornment
ref={anchorRef}
position="start"
sx={{ cursor: "pointer" }}
onClick={() => setOpen((isOpened) => !isOpened)}
>
{IconAndrom(isExpanded, questionType)}
</InputAdornment>
<ChooseAnswerModal
open={open}
onClose={() => setOpen(false)}
anchorRef={anchorRef}
questionId={questionId}
questionContentId={questionContentId}
questionType={questionType}
/>
</Box>
),
endAdornment: isTextFieldtActive &&
title.length >= maxLengthTextField - 7 && (
<Box
sx={{
display: "flex",
marginTop: "5px",
marginLeft: "auto",
position: "absolute",
bottom: "-28px",
right: "0",
}}
>
<Typography fontSize="14px">{title.length}</Typography>
<span>/</span>
<Typography fontSize="14px">{maxLengthTextField}</Typography>
</Box>
),
}}
sx={{
flexGrow: 1,
margin: isMobile ? "10px 0" : 0,
"& .MuiInputBase-root": {
color: "#000000",
backgroundColor: isExpanded
? theme.palette.background.default
: "transparent",
height: "48px",
borderRadius: "10px",
".MuiOutlinedInput-notchedOutline": {
borderWidth: "1px !important",
border: !isExpanded ? "none" : null,
},
"& .MuiInputBase-input::placeholder": {
color: "#4D4D4D",
opacity: 0.8,
},
},
}}
/>
</FormControl>
<IconButton
disableRipple
sx={{
order: isMobile && isExpanded ? "0" : "1",
padding: isMobile ? "0" : "0 5px",
right: isMobile ? "0" : null,
bottom: isMobile ? "0" : null,
marginLeft: !isMobile && isExpanded ? "10px" : null,
}}
{...draggableProps}
onMouseDown={collapseAllQuestions}
onTouchStart={collapseAllQuestions}
>
<PointsIcon style={{ color: "#4D4D4D", fontSize: "30px" }} />
</IconButton>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
width: isMobile ? "100%" : "auto",
position: "relative",
}}
>
<IconButton
sx={{ padding: "0", margin: "5px" }}
disableRipple
data-cy="expand-question"
onClick={() => toggleExpandQuestion(questionId)}
>
{isExpanded ? (
<ArrowDownIcon
style={{
width: "18px",
color: "#4D4D4D",
}}
/>
) : (
<ExpandLessIcon
sx={{
boxSizing: "border-box",
fill: theme.palette.brightPurple.main,
background: "#FFF",
borderRadius: "6px",
height: "30px",
width: "30px",
}}
/>
)}
</IconButton>
{isExpanded ? (
<></>
) : (
<Box
sx={{
display: "flex",
height: "30px",
borderRight: "solid 1px #4D4D4D",
}}
>
<IconButton
sx={{ padding: "0" }}
onClick={() => copyQuestion(questionId, quizId)}
>
<CopyIcon style={{ color: theme.palette.brightPurple.main }} />
</IconButton>
<IconButton
sx={{
cursor: "pointer",
borderRadius: "6px",
padding: "0",
margin: "0 5px 0 10px",
}}
onClick={() => {
if (questionType === null) {
deleteQuestion(questionId);
return;
}
if (questionHasParent) {
setOpenDelete(true);
} else {
deleteQuestionWithTimeout(questionId, () =>
DeleteFunction(questionId),
);
}
}}
data-cy="delete-question"
>
<DeleteIcon style={{ color: theme.palette.brightPurple.main }} />
</IconButton>
<Modal open={openDelete} onClose={() => setOpenDelete(false)}>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
padding: "30px",
borderRadius: "10px",
background: "#FFFFFF",
}}
>
<Typography variant="h6" sx={{ textAlign: "center" }}>
Вы удаляете вопрос, участвующий в ветвлении. Все его потомки
потеряют данные ветвления. Вы уверены, что хотите удалить
вопрос?
</Typography>
<Box
sx={{
marginTop: "30px",
display: "flex",
justifyContent: "center",
gap: "15px",
}}
>
<Button
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => setOpenDelete(false)}
>
Отмена
</Button>
<Button
variant="contained"
sx={{ minWidth: "150px" }}
onClick={() => {
deleteQuestionWithTimeout(questionId, () =>
DeleteFunction(questionId),
);
}}
>
Подтвердить
</Button>
</Box>
</Box>
</Modal>
</Box>
)}
{page !== null && (
<Box
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "30px",
width: "30px",
marginLeft: "3px",
borderRadius: "50%",
fontSize: "16px",
color: isExpanded ? theme.palette.brightPurple.main : "#FFF",
background: isExpanded
? "#EEE4FC"
: theme.palette.brightPurple.main,
}}
>
{page + 1}
</Box>
)}
</Box> </Box>
)}
</Box> </Box>
{questionType !== null && </Box>
<Box sx={{ {questionType !== null && (
<Box
sx={{
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
flexWrap: isMobile ? "wrap" : undefined, flexWrap: isMobile ? "wrap" : undefined,
gap: "10px", gap: "10px",
padding: "0 20px 20px 20px" padding: "0 20px 20px 20px",
}}> }}
<Typography>ID Вопроса</Typography> >
<Typography <Typography>ID Вопроса</Typography>
id={"id-copy"} <Typography id={"id-copy"}>{questionBackendId}</Typography>
>{questionBackendId}</Typography> <IconButton
<IconButton edge="end"
edge="end" onClick={() =>
onClick={() => navigator.clipboard.writeText(document.querySelector("#id-copy").innerText) navigator.clipboard.writeText(
} document.querySelector("#id-copy").innerText,
> )
<CopyIconPurple }
color={"#ffffff"} >
width={"30px"} <CopyIconPurple
bgcolor={theme.palette.brightPurple.main} color={"#ffffff"}
/> width={"30px"}
</IconButton> bgcolor={theme.palette.brightPurple.main}
</Box>} />
</IconButton>
</Box>
)}
</> </>
); );
}); });

@ -9,16 +9,17 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
import { import {
Box, Box,
IconButton, IconButton,
Paper, Paper,
Button, Button,
Typography, Typography,
TextField, TextField,
useMediaQuery, useMediaQuery,
useTheme, useTheme,
FormControl, FormControl,
Popover, InputAdornment, Popover,
InputAdornment,
} from "@mui/material"; } from "@mui/material";
import MiniButtonSetting from "@ui_kit/MiniButtonSetting"; import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
@ -260,28 +261,31 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
}} }}
> >
<Box sx={{ p: "0 20px", pt: "10px" }}> <Box sx={{ p: "0 20px", pt: "10px" }}>
<Box sx={{ <Box
display: "flex", sx={{
alignItems: "center", display: "flex",
gap: "10px", alignItems: "center",
mb: "19px", gap: "10px",
}}> mb: "19px",
<Typography>ID результата</Typography> }}
<Typography >
id={"id-copy"} <Typography>ID результата</Typography>
>{resultData.backendId}</Typography> <Typography id={"id-copy"}>{resultData.backendId}</Typography>
<IconButton <IconButton
edge="end" edge="end"
onClick={() => navigator.clipboard.writeText(document.querySelector("#id-copy").innerText) onClick={() =>
} navigator.clipboard.writeText(
> document.querySelector("#id-copy").innerText,
<CopyIcon )
color={"#ffffff"} }
width={"30px"} >
bgcolor={theme.palette.brightPurple.main} <CopyIcon
/> color={"#ffffff"}
</IconButton> width={"30px"}
</Box> bgcolor={theme.palette.brightPurple.main}
/>
</IconButton>
</Box>
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",

@ -63,7 +63,9 @@ export const createTariffElements = (
lineHeight: "21px", lineHeight: "21px",
}} }}
> >
{currencyFormatter.format(Math.trunc(priceBeforeDiscounts) / 100)} {currencyFormatter.format(
Math.trunc(priceBeforeDiscounts) / 100,
)}
</Typography> </Typography>
)} )}
<Typography <Typography
@ -74,7 +76,9 @@ export const createTariffElements = (
color: "#4D4D4D", color: "#4D4D4D",
}} }}
> >
{currencyFormatter.format(Math.trunc(priceAfterDiscounts) / 100)} {currencyFormatter.format(
Math.trunc(priceAfterDiscounts) / 100,
)}
</Typography> </Typography>
</> </>
} }

@ -96,13 +96,15 @@ export const ExportResults = async (
parseFilters(filterNew, filterDate), parseFilters(filterNew, filterDate),
); );
console.log(typeof data) console.log(typeof data);
const blob = new Blob([data as BlobPart], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8" }); const blob = new Blob([data as BlobPart], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
});
const link = document.createElement("a"); const link = document.createElement("a");
link.href = window.URL.createObjectURL(data as Blob); link.href = window.URL.createObjectURL(data as Blob);
console.log(link) console.log(link);
link.download = `report_${new Date().getTime()}.xlsx`; link.download = `report_${new Date().getTime()}.xlsx`;
link.click(); link.click();
} catch (nativeError) { } catch (nativeError) {