diff --git a/package.json b/package.json
index af12ffe6..844a197a 100755
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@frontend/kitui": "^1.0.82",
- "@frontend/squzanswerer": "^1.0.38",
+ "@frontend/squzanswerer": "^1.0.41",
"@mui/icons-material": "^5.10.14",
"@mui/material": "^5.10.14",
"@mui/x-charts": "^6.19.5",
diff --git a/src/assets/icons/NumberThree.tsx b/src/assets/icons/NumberThree.tsx
deleted file mode 100644
index f9978180..00000000
--- a/src/assets/icons/NumberThree.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Box } from "@mui/material";
-
-interface Props {
- color: string;
-}
-
-export default function NumberThree({ color }: Props) {
- return (
-
-
-
- );
-}
diff --git a/src/assets/icons/NumberTwo.tsx b/src/assets/icons/NumberTwo.tsx
deleted file mode 100644
index 85116206..00000000
--- a/src/assets/icons/NumberTwo.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Box } from "@mui/material";
-
-interface Props {
- color: string;
-}
-
-export default function NumberTwo({ color }: Props) {
- return (
-
-
-
- );
-}
diff --git a/src/assets/icons/OneIconBorder.tsx b/src/assets/icons/OneIconBorder.tsx
deleted file mode 100644
index e9ac34b4..00000000
--- a/src/assets/icons/OneIconBorder.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Box } from "@mui/material";
-
-interface Props {
- color: string;
-}
-
-export default function OneIconBorder({ color }: Props) {
- return (
-
-
-
- );
-}
diff --git a/src/pages/InstallQuiz/InBodyInstall.tsx b/src/pages/InstallQuiz/InBodyInstall.tsx
index abb494f7..68ae1bb7 100644
--- a/src/pages/InstallQuiz/InBodyInstall.tsx
+++ b/src/pages/InstallQuiz/InBodyInstall.tsx
@@ -1,21 +1,94 @@
-import { Box, Button, Link, Typography, useTheme } from "@mui/material";
-import InstallQzOnSiteParent from "./InstallQzOnSiteParent";
-import Dots from "../../assets/dots.png";
-import React from "react";
-import CustomTextField from "@ui_kit/CustomTextField";
+import {
+ Box,
+ Button,
+ Collapse,
+ Divider,
+ Typography,
+ useMediaQuery,
+ useTheme,
+} from "@mui/material";
+import { useCurrentQuiz } from "@root/quizes/hooks";
+import CircleColorPicker from "@ui_kit/CircleColorPicker";
import CustomCheckbox from "@ui_kit/CustomCheckbox";
+import PenaTextField from "@ui_kit/PenaTextField";
+import { nanoid } from "nanoid";
+import { useState } from "react";
+import Dots from "../../assets/dots.png";
+import WidgetScript from "./QuizInstallationCard/WidgetScript";
+import { createContainerWidgetScriptText } from "./QuizInstallationCard/createWidgetScriptText";
-export default function InBodyInstall() {
+interface Props {
+ step: 2 | 3;
+}
+
+export default function InBodyInstall({ step }: Props) {
const theme = useTheme();
+ const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1065));
+ const quiz = useCurrentQuiz();
+ const [isAutoopenQuizSettingsOpen, setIsAutoopenQuizSettingsOpen] =
+ useState(false);
+ const [widgetWidth, setWidgetWidth] = useState("");
+ const [widgetHeight, setWidgetHeight] = useState("");
+ const [hideOnMobile, setHideOnMobile] = useState(false);
+ const [showButtonOnMobile, setShowButtonOnMobile] = useState(false);
+ const [rounded, setRounded] = useState(false);
+ const [withShadow, setWithShadow] = useState(false);
+ const [buttonFlash, setButtonFlash] = useState(false);
+ const [buttonText, setButtonText] = useState("");
+ const [buttonBackgroundColor, setButtonBackgroundColor] = useState(
+ theme.palette.brightPurple.main,
+ );
+ const [buttonTextColor, setButtonTextColor] = useState("#FFFFFF");
+ const [autoShowQuiz, setAutoShowQuiz] = useState(false);
+ const [autoShowQuizTime, setAutoShowQuizTime] = useState(10);
+ const [openOnLeaveAttempt, setOpenOnLeaveAttempt] = useState(false);
+
+ if (!quiz) return null;
+
+ if (step === 3) {
+ const scriptText = createContainerWidgetScriptText({
+ quizId: quiz.qid,
+ selector: `#pena-quiz-container-${nanoid(6)}`,
+ dimensions:
+ widgetWidth || widgetHeight
+ ? {
+ width: widgetWidth ? `${widgetWidth}px` : "100%",
+ height: widgetHeight ? `${widgetHeight}px` : "100%",
+ }
+ : undefined,
+ hideOnMobile: hideOnMobile || undefined,
+ showButtonOnMobile: showButtonOnMobile || undefined,
+ rounded: rounded || undefined,
+ withShadow: withShadow || undefined,
+ buttonFlash: buttonFlash || undefined,
+ buttonText: buttonText || undefined,
+ buttonBackgroundColor,
+ buttonTextColor,
+ autoShowQuizTime: autoShowQuiz ? autoShowQuizTime : undefined,
+ openOnLeaveAttempt: openOnLeaveAttempt || undefined,
+ });
+
+ return ;
+ }
+
return (
-
-
+
+
-
+
В мобильной версии будет показана кнопка, открывающая quiz в
модальном окне
-
- Если quiz уже установлен на сайт, и вы что-то здесь изменили, код на
- сайте нужно будет поменять. Настройки в этом конструкторе не
- сохраняются.
-
-
- 1. Задайте размеры (опционально)
+
+
+ 1. Задайте размеры (опционально)
+
Ширина (px)
-
-
- Радиус (px)
-
-
+ setWidgetWidth(e.target.value)}
+ FormControlSx={{ maxWidth: "160px" }}
+ placeholder="auto"
+ />
Высота (px)
-
-
- Отступ (px)
-
-
+ setWidgetHeight(e.target.value)}
+ FormControlSx={{ maxWidth: "160px" }}
+ placeholder="auto"
+ />
-
- 2. Настройте кнопку для мобильной версии
+
+
+ 2. Настройте кнопку для мобильной версии
+
Цвет кнопки
-
- {" "}
-
+ setButtonBackgroundColor(color)}
+ />
Цвет текста кнопки
-
- {" "}
-
+ setButtonTextColor(color)}
+ />
-
-
-
-
-
+ setHideOnMobile(e.target.checked)}
+ />
+ setRounded(e.target.checked)}
+ />
+ setWithShadow(e.target.checked)}
+ />
+ setButtonFlash(e.target.checked)}
+ />
+ setShowButtonOnMobile(e.target.checked)}
+ />
Текст кнопки
-
- setButtonText(e.target.value)}
+ placeholder="Пройти тест"
+ FormControlSx={{ maxWidth: "360px" }}
+ />
+
+
+
+ setAutoShowQuiz(e.target.checked)}
+ />
+ setOpenOnLeaveAttempt(e.target.checked)}
+ sx={{
+ mt: "15px",
+ }}
+ />
+
+
+
+
+
+ Показывать через
+
+
+ setAutoShowQuizTime(parseInt(e.target.value))
+ }
+ FormControlSx={{
+ width: "90px",
+ }}
+ />
+
+ секунд
+
+
+
+
+
+
-
+
);
}
diff --git a/src/pages/InstallQuiz/QuizInstallationCard/InstallationStepButton.tsx b/src/pages/InstallQuiz/QuizInstallationCard/InstallationStepButton.tsx
index 900f9833..20736b1d 100644
--- a/src/pages/InstallQuiz/QuizInstallationCard/InstallationStepButton.tsx
+++ b/src/pages/InstallQuiz/QuizInstallationCard/InstallationStepButton.tsx
@@ -17,7 +17,7 @@ export default function InstallationStepButton({
}: Props) {
const theme = useTheme();
- const buttonColorByState: Record = {
+ const buttonColorByState: Record = {
active: "#FC712F",
done: theme.palette.brightPurple.main,
inactive: theme.palette.grey2.main,
@@ -28,13 +28,29 @@ export default function InstallationStepButton({
return (
}
- sx={{
- color: buttonColorByState[state],
- "& .MuiButton-startIcon": {
- mr: "5px",
+ sx={[
+ {
+ color,
+ fontSize: "16px",
+ "& .MuiButton-startIcon": {
+ mr: "5px",
+ },
},
- }}
+ state === "active" && {
+ textDecoration: "underline",
+ textDecorationColor: color,
+ },
+ ]}
+ startIcon={
+
+ }
>
{children}
diff --git a/src/pages/InstallQuiz/QuizInstallationCard/QuizInstallationCard.tsx b/src/pages/InstallQuiz/QuizInstallationCard/QuizInstallationCard.tsx
index ea1648e9..498a5ab7 100644
--- a/src/pages/InstallQuiz/QuizInstallationCard/QuizInstallationCard.tsx
+++ b/src/pages/InstallQuiz/QuizInstallationCard/QuizInstallationCard.tsx
@@ -1,17 +1,8 @@
-import {
- Box,
- IconButton,
- InputAdornment,
- TextField as MuiTextField,
- TextFieldProps,
- Typography,
- useMediaQuery,
- useTheme,
-} from "@mui/material";
+import { WidgetType } from "@frontend/squzanswerer";
+import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
import { useCurrentQuiz } from "@root/quizes/hooks";
-import { useDomainDefine } from "@utils/hooks/useDomainDefine";
-import { FC, useState } from "react";
-import CopyIcon from "../../../assets/icons/CopyIcon";
+import { useState } from "react";
+import InBodyInstall from "../InBodyInstall";
import InstallationStepButton from "./InstallationStepButton";
import WidgetTypeButton from "./WidgetTypeButton";
import BannerWidgetPreview from "./previewIcons/BannerWidgetPreview";
@@ -20,19 +11,20 @@ import ContainerWidgetPreview from "./previewIcons/ContainerWidgetPreview";
import PopupWidgetPreview from "./previewIcons/PopupWidgetPreview";
import SideWidgetPreview from "./previewIcons/SideWidgetPreview";
-const TextField = MuiTextField as unknown as FC;
+type WidgetSetupSettings = {
+ step: 1 | 2 | 3;
+ widgetType: WidgetType;
+};
export default function QuizInstallationCard() {
const theme = useTheme();
- const quiz = useCurrentQuiz();
- const { isTestServer } = useDomainDefine();
- const [stepState, setStepState] = useState<1 | 2 | 3>(1);
const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1065));
+ const quiz = useCurrentQuiz();
+ const [widgetSetupSettings, setWidgetSetupSettings] =
+ useState({ step: 1, widgetType: "container" });
if (!quiz) return null;
- const scriptText = ` `;
-
return (
-
- Установка quiz на сайте
-
- {
- setStepState(1);
+ Установка quiz на сайте
+
- Способ установки
-
- {
- setStepState(2);
- }}
- >
- Настройка кнопки
-
- {
- setStepState(3);
- }}
- >
- Вставить код на сайт
-
-
-
- {stepState === 1 ? (
- <>
- }
- text1="По кнопке"
- text2="Конструктор кнопки или собственная кнопка"
- onClick={() => {
- setStepState(2);
- }}
- />
- }
- text1="Баннером"
- text2="Сбоку или на всю ширину экрана"
- onClick={() => {
- setStepState(2);
- }}
- />
- }
- text1="В тело сайта"
- text2="Задайте свои размеры и встройте в сайт"
- onClick={() => {
- setStepState(2);
- }}
- />
- }
- text1="Автооткрытие"
- text2="Автооткрытие поп-ап на сайте"
- onClick={() => {
- setStepState(2);
- }}
- />
- }
- text1="Виджет"
- text2="Сбоку страницы, как консультант"
- onClick={() => {
- setStepState(2);
- }}
- />
- >
- ) : (
- <>
-
- {
+ setWidgetSetupSettings({
+ step: 1,
+ widgetType: "container",
+ });
+ }}
+ >
+ Способ установки
+
+ {widgetSetupSettings.step !== 1 && (
+ <>
+ {
+ setWidgetSetupSettings((prev) => ({
+ ...prev,
+ step: 2,
+ }));
}}
>
- 1. Код вставки quiz
-
- Установите код в то место, где должен быть quiz
-
-
-
- navigator.clipboard.writeText(scriptText)
- }
- >
-
-
-
- ),
- }}
- />
-
-
-
-
- Код нужно вставить один раз. Изменения в самом quiz будут
- отображаться автоматически после сохранения.
-
-
- Для установки размера добавьте в тег значения высоты и ширины,
- например:
-
-
- {``}
-
-
- >
- )}
+ Настройка кнопки
+
+ {
+ setWidgetSetupSettings((prev) => ({
+ ...prev,
+ step: 3,
+ }));
+ }}
+ >
+ Вставить код на сайт
+
+ >
+ )}
+
+ {widgetSetupSettings.step === 1 ? (
+
+ }
+ text1="По кнопке"
+ text2="Конструктор кнопки или собственная кнопка"
+ onClick={() => {
+ setWidgetSetupSettings({
+ step: 2,
+ widgetType: "button",
+ });
+ }}
+ />
+ }
+ text1="Баннером"
+ text2="Сбоку или на всю ширину экрана"
+ onClick={() => {
+ setWidgetSetupSettings({
+ step: 2,
+ widgetType: "banner",
+ });
+ }}
+ />
+ }
+ text1="В тело сайта"
+ text2="Задайте свои размеры и встройте в сайт"
+ onClick={() => {
+ setWidgetSetupSettings({
+ step: 2,
+ widgetType: "container",
+ });
+ }}
+ />
+ }
+ text1="Автооткрытие"
+ text2="Автооткрытие поп-ап на сайте"
+ onClick={() => {
+ setWidgetSetupSettings({
+ step: 2,
+ widgetType: "popup",
+ });
+ }}
+ />
+ }
+ text1="Виджет"
+ text2="Сбоку страницы, как консультант"
+ onClick={() => {
+ setWidgetSetupSettings({
+ step: 2,
+ widgetType: "side",
+ });
+ }}
+ />
+
+ ) : (
+ <>
+ {widgetSetupSettings.widgetType === "container" && (
+
+ )}
+ >
+ )}
);
}
diff --git a/src/pages/InstallQuiz/QuizInstallationCard/WidgetScript.tsx b/src/pages/InstallQuiz/QuizInstallationCard/WidgetScript.tsx
new file mode 100644
index 00000000..3dc0171c
--- /dev/null
+++ b/src/pages/InstallQuiz/QuizInstallationCard/WidgetScript.tsx
@@ -0,0 +1,66 @@
+import CopyIcon from "@icons/CopyIcon";
+import {
+ Box,
+ IconButton,
+ InputAdornment,
+ TextField as MuiTextField,
+ TextFieldProps,
+ Typography,
+ useTheme,
+} from "@mui/material";
+import { FC } from "react";
+
+const TextField = MuiTextField as unknown as FC;
+
+interface Props {
+ scriptText: string;
+}
+
+export default function WidgetScript({ scriptText }: Props) {
+ const theme = useTheme();
+
+ return (
+
+
+ Установите код в место, в котором должен быть квиз
+
+
+ {
+ navigator.clipboard.writeText(scriptText);
+ }}
+ edge="end"
+ sx={{ marginTop: "22px" }}
+ >
+
+
+
+ ),
+ }}
+ />
+
+ );
+}
diff --git a/src/pages/InstallQuiz/QuizInstallationCard/WidgetTypeButton.tsx b/src/pages/InstallQuiz/QuizInstallationCard/WidgetTypeButton.tsx
index c0dffefc..5ff5c778 100644
--- a/src/pages/InstallQuiz/QuizInstallationCard/WidgetTypeButton.tsx
+++ b/src/pages/InstallQuiz/QuizInstallationCard/WidgetTypeButton.tsx
@@ -1,4 +1,11 @@
-import { Button, ButtonBase, Typography } from "@mui/material";
+import {
+ Box,
+ Button,
+ ButtonBase,
+ Typography,
+ useMediaQuery,
+ useTheme,
+} from "@mui/material";
import { ReactNode } from "react";
interface Props {
@@ -14,29 +21,43 @@ export default function WidgetTypeButton({
text1,
text2,
}: Props) {
+ const theme = useTheme();
+ const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1065));
+
return (
);
}
diff --git a/src/pages/InstallQuiz/QuizInstallationCard/createWidgetScriptText.ts b/src/pages/InstallQuiz/QuizInstallationCard/createWidgetScriptText.ts
new file mode 100644
index 00000000..60488144
--- /dev/null
+++ b/src/pages/InstallQuiz/QuizInstallationCard/createWidgetScriptText.ts
@@ -0,0 +1,55 @@
+import {
+ BannerWidgetParams,
+ ButtonWidgetFixedParams,
+ ButtonWidgetParams,
+ ContainerWidgetParams,
+ PopupWidgetParams,
+ SideWidgetParams,
+ WidgetType,
+} from "@frontend/squzanswerer";
+
+export function createContainerWidgetScriptText(params: ContainerWidgetParams) {
+ return `
+`;
+}
+
+export function createButtonWidgetScriptText(
+ params: ButtonWidgetParams | ButtonWidgetFixedParams,
+) {
+ const widgetClassName =
+ "fixedSide" in params ? "ButtonWidgetFixed" : "ButtonWidget";
+
+ return ``;
+}
+
+export function createPopupWidgetScriptText(params: PopupWidgetParams) {
+ return ``;
+}
+
+export function createSideWidgetScriptText(params: SideWidgetParams) {
+ return ``;
+}
+
+export function createBannerWidgetScriptText(params: BannerWidgetParams) {
+ return ``;
+}
diff --git a/src/pages/InstallQuiz/QuizInstallationCard/previewIcons/WidgetPreviewContainer.tsx b/src/pages/InstallQuiz/QuizInstallationCard/previewIcons/WidgetPreviewContainer.tsx
index 31ca9fa4..ecd9879e 100644
--- a/src/pages/InstallQuiz/QuizInstallationCard/previewIcons/WidgetPreviewContainer.tsx
+++ b/src/pages/InstallQuiz/QuizInstallationCard/previewIcons/WidgetPreviewContainer.tsx
@@ -1,4 +1,4 @@
-import { Box } from "@mui/material";
+import { Box, useMediaQuery, useTheme } from "@mui/material";
import { ReactNode } from "react";
interface Props {
@@ -6,10 +6,13 @@ interface Props {
}
export default function WidgetPreviewContainer({ children }: Props) {
+ const theme = useTheme();
+ const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1065));
+
return (
-
diff --git a/src/ui_kit/CircleColorPicker.tsx b/src/ui_kit/CircleColorPicker.tsx
new file mode 100644
index 00000000..545aa40a
--- /dev/null
+++ b/src/ui_kit/CircleColorPicker.tsx
@@ -0,0 +1,41 @@
+import { ButtonBase } from "@mui/material";
+import { startTransition, useRef } from "react";
+
+interface Props {
+ color: string;
+ onChange: (color: string) => void;
+}
+
+export default function CircleColorPicker({ color, onChange }: Props) {
+ const inputRef = useRef(null);
+
+ return (
+ inputRef.current?.click()}
+ sx={{
+ aspectRatio: 1,
+ height: "22px",
+ width: "22px",
+ minWidth: "20px",
+ borderRadius: "50%",
+ backgroundColor: color,
+ border: "1px solid #4D4D4D",
+ }}
+ >
+ {
+ startTransition(() => {
+ onChange(e.target.value);
+ });
+ }}
+ style={{
+ opacity: 0,
+ cursor: "pointer",
+ }}
+ />
+
+ );
+}
diff --git a/src/ui_kit/PenaTextField.tsx b/src/ui_kit/PenaTextField.tsx
new file mode 100644
index 00000000..d7ed2eca
--- /dev/null
+++ b/src/ui_kit/PenaTextField.tsx
@@ -0,0 +1,135 @@
+import {
+ FormControl,
+ InputLabel,
+ TextField as MuiTextField,
+ SxProps,
+ TextFieldProps,
+ Theme,
+ useMediaQuery,
+ useTheme,
+} from "@mui/material";
+import { FC } from "react";
+
+const TextField = MuiTextField as unknown as FC;
+
+interface Props {
+ id?: string;
+ label?: string;
+ labelSx?: SxProps;
+ bold?: boolean;
+ gap?: string;
+ backgroundColor?: string;
+ FormControlSx?: SxProps;
+ TextFieldSx?: SxProps;
+ placeholder?: TextFieldProps["placeholder"];
+ value?: TextFieldProps["value"];
+ helperText?: TextFieldProps["helperText"];
+ error?: TextFieldProps["error"];
+ type?: TextFieldProps["type"];
+ onBlur?: TextFieldProps["onBlur"];
+ onChange?: TextFieldProps["onChange"];
+ fullWidth?: boolean;
+}
+
+export default function PenaTextField({
+ id,
+ label,
+ labelSx,
+ bold = false,
+ gap = "10px",
+ onChange,
+ error,
+ helperText,
+ onBlur,
+ placeholder,
+ type,
+ value,
+ backgroundColor,
+ FormControlSx,
+ TextFieldSx,
+ fullWidth = true,
+}: Props) {
+ const theme = useTheme();
+ const upMd = useMediaQuery(theme.breakpoints.up("md"));
+
+ const labelFont = upMd
+ ? bold
+ ? theme.typography.p1
+ : { ...theme.typography.body1, fontWeight: 500 }
+ : theme.typography.body2;
+
+ const placeholderFont = upMd
+ ? undefined
+ : { fontWeight: 400, fontSize: "16px", lineHeight: "19px" };
+
+ return (
+
+ {label && (
+
+ {label}
+
+ )}
+
+
+ );
+}
diff --git a/yarn.lock b/yarn.lock
index 51c9ffbe..d4330c50 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1527,10 +1527,10 @@
immer "^10.0.2"
reconnecting-eventsource "^1.6.2"
-"@frontend/squzanswerer@^1.0.38":
- version "1.0.38"
- resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/43/packages/npm/@frontend/squzanswerer/-/@frontend/squzanswerer-1.0.38.tgz#51f382368d73f9ad36c4f7f3357dedb32d5453e8"
- integrity sha1-UfOCNo1z+a02xPfzNX3tsy1UU+g=
+"@frontend/squzanswerer@^1.0.41":
+ version "1.0.41"
+ resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/43/packages/npm/@frontend/squzanswerer/-/@frontend/squzanswerer-1.0.41.tgz#d535b03c0a432a2c427c99083a6ec9b1e64e060e"
+ integrity sha1-1TWwPApDKixCfJkIOm7JseZOBg4=
dependencies:
bowser "1.9.4"
country-flag-emoji-polyfill "^0.1.8"