move widget types to package
This commit is contained in:
parent
8276355ed5
commit
81cbe420c5
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,7 +11,7 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-package
|
dist-package
|
||||||
dist-ssr
|
dist-ssr
|
||||||
widget
|
/widget
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
|
22
lib/model/widget/banner.ts
Normal file
22
lib/model/widget/banner.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export interface BannerWidgetComponentProps {
|
||||||
|
quizId: string;
|
||||||
|
position: "topleft" | "topright" | "bottomleft" | "bottomright";
|
||||||
|
onWidgetClose?: () => void;
|
||||||
|
appealText?: string;
|
||||||
|
quizHeaderText?: string;
|
||||||
|
buttonTextColor?: string;
|
||||||
|
buttonBackgroundColor?: string;
|
||||||
|
/**
|
||||||
|
* Открыть квиз через X секунд, 0 - сразу
|
||||||
|
*/
|
||||||
|
autoShowQuizTime?: number | null;
|
||||||
|
openOnLeaveAttempt?: boolean;
|
||||||
|
buttonFlash?: boolean;
|
||||||
|
hideOnMobile?: boolean;
|
||||||
|
withShadow?: boolean;
|
||||||
|
rounded?: boolean;
|
||||||
|
bannerFullWidth?: boolean;
|
||||||
|
pulsation?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BannerWidgetParams = Omit<BannerWidgetComponentProps, "onWidgetClose">;
|
29
lib/model/widget/button.ts
Normal file
29
lib/model/widget/button.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export interface ButtonWidgetComponentProps {
|
||||||
|
quizId: string;
|
||||||
|
fixedSide?: "left" | "right";
|
||||||
|
dialogDimensions?: { width: string; height: string; };
|
||||||
|
/**
|
||||||
|
* Открыть квиз через X секунд, 0 - сразу
|
||||||
|
*/
|
||||||
|
autoShowQuizTime?: number | null;
|
||||||
|
hideOnMobile?: boolean;
|
||||||
|
openOnLeaveAttempt?: boolean;
|
||||||
|
buttonFlash?: boolean;
|
||||||
|
withShadow?: boolean;
|
||||||
|
rounded?: boolean;
|
||||||
|
buttonText?: string;
|
||||||
|
buttonTextColor?: string;
|
||||||
|
buttonBackgroundColor?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ButtonWidgetParams = Omit<ButtonWidgetComponentProps, "fixedSide"> & {
|
||||||
|
selector: string;
|
||||||
|
/**
|
||||||
|
* In seconds, null - polling disabled
|
||||||
|
*/
|
||||||
|
selectorPollingTimeLimit?: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ButtonWidgetFixedParams = Omit<ButtonWidgetComponentProps, "selector"> & {
|
||||||
|
fixedSide: "left" | "right";
|
||||||
|
};
|
15
lib/model/widget/container.ts
Normal file
15
lib/model/widget/container.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ButtonWidgetComponentProps } from "./button";
|
||||||
|
|
||||||
|
export type ContainerWidgetComponentProps = ButtonWidgetComponentProps & {
|
||||||
|
quizId: string;
|
||||||
|
showButtonOnMobile?: boolean;
|
||||||
|
dimensions?: { width: string; height: string; };
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ContainerWidgetParams = ContainerWidgetComponentProps & {
|
||||||
|
selector: string;
|
||||||
|
/**
|
||||||
|
* In seconds, null - polling disabled
|
||||||
|
*/
|
||||||
|
selectorPollingTimeLimit?: number | null;
|
||||||
|
};
|
12
lib/model/widget/popup.ts
Normal file
12
lib/model/widget/popup.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export interface PopupWidgetComponentProps {
|
||||||
|
quizId: string;
|
||||||
|
dialogDimensions?: { width: string; height: string; };
|
||||||
|
/**
|
||||||
|
* Открыть квиз через X секунд, 0 - сразу
|
||||||
|
*/
|
||||||
|
autoShowQuizTime?: number | null;
|
||||||
|
hideOnMobile?: boolean;
|
||||||
|
openOnLeaveAttempt?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PopupWidgetParams = PopupWidgetComponentProps;
|
20
lib/model/widget/side.ts
Normal file
20
lib/model/widget/side.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export interface SideWidgetComponentProps {
|
||||||
|
quizId: string;
|
||||||
|
position: "left" | "right";
|
||||||
|
buttonBackgroundColor?: string;
|
||||||
|
buttonTextColor?: string;
|
||||||
|
dialogDimensions?: { width: string; height: string; };
|
||||||
|
fullScreen?: boolean;
|
||||||
|
buttonFlash?: boolean;
|
||||||
|
/**
|
||||||
|
* Скрывать виджет первые X секунд
|
||||||
|
*/
|
||||||
|
autoOpenTime?: number;
|
||||||
|
/**
|
||||||
|
* Открыть квиз через X секунд, 0 - сразу
|
||||||
|
*/
|
||||||
|
autoShowQuizTime?: number | null;
|
||||||
|
hideOnMobile?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SideWidgetParams = SideWidgetComponentProps;
|
@ -1,15 +1,13 @@
|
|||||||
|
import { BannerWidgetParams } from "@/model/widget/banner";
|
||||||
import { Root, createRoot } from "react-dom/client";
|
import { Root, createRoot } from "react-dom/client";
|
||||||
import QuizBanner from "./QuizBanner";
|
import QuizBanner from "./QuizBanner";
|
||||||
import { ComponentPropsWithoutRef } from "react";
|
|
||||||
|
|
||||||
|
|
||||||
type Props = Omit<ComponentPropsWithoutRef<typeof QuizBanner>, "onClose">;
|
|
||||||
|
|
||||||
export class BannerWidget {
|
export class BannerWidget {
|
||||||
root: Root | undefined;
|
root: Root | undefined;
|
||||||
element = document.createElement("div");
|
element = document.createElement("div");
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: BannerWidgetParams) {
|
||||||
this.element.style.setProperty("display", "none");
|
this.element.style.setProperty("display", "none");
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element);
|
||||||
|
|
||||||
@ -18,7 +16,7 @@ export class BannerWidget {
|
|||||||
this.render(props);
|
this.render(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props: Props) {
|
render(props: BannerWidgetParams) {
|
||||||
this.root?.render(
|
this.root?.render(
|
||||||
<QuizBanner
|
<QuizBanner
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { BannerWidgetComponentProps } from "@/model/widget/banner";
|
||||||
import lightTheme from "@/utils/themes/light";
|
import lightTheme from "@/utils/themes/light";
|
||||||
import { Box, Button, Fade, IconButton, ThemeProvider, Typography, useMediaQuery } from "@mui/material";
|
import { Box, Button, Fade, IconButton, ThemeProvider, Typography, useMediaQuery } from "@mui/material";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
@ -10,27 +11,6 @@ import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
|||||||
|
|
||||||
const PADDING = 10;
|
const PADDING = 10;
|
||||||
|
|
||||||
interface Props {
|
|
||||||
quizId: string;
|
|
||||||
position: "topleft" | "topright" | "bottomleft" | "bottomright";
|
|
||||||
onWidgetClose?: () => void;
|
|
||||||
appealText?: string;
|
|
||||||
quizHeaderText?: string;
|
|
||||||
buttonTextColor?: string;
|
|
||||||
buttonBackgroundColor?: string;
|
|
||||||
/**
|
|
||||||
* Открыть квиз через X секунд, 0 - сразу
|
|
||||||
*/
|
|
||||||
autoShowQuizTime?: number | null;
|
|
||||||
openOnLeaveAttempt?: boolean;
|
|
||||||
buttonFlash?: boolean;
|
|
||||||
hideOnMobile?: boolean;
|
|
||||||
withShadow?: boolean;
|
|
||||||
rounded?: boolean;
|
|
||||||
bannerFullWidth?: boolean;
|
|
||||||
pulsation?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function QuizBanner({
|
export default function QuizBanner({
|
||||||
quizId,
|
quizId,
|
||||||
position,
|
position,
|
||||||
@ -47,7 +27,7 @@ export default function QuizBanner({
|
|||||||
rounded = false,
|
rounded = false,
|
||||||
bannerFullWidth = false,
|
bannerFullWidth = false,
|
||||||
pulsation = false,
|
pulsation = false,
|
||||||
}: Props) {
|
}: BannerWidgetComponentProps) {
|
||||||
const isMobile = useMediaQuery("(max-width: 600px)");
|
const isMobile = useMediaQuery("(max-width: 600px)");
|
||||||
const [isQuizShown, setIsQuizShown] = useState<boolean>(false);
|
const [isQuizShown, setIsQuizShown] = useState<boolean>(false);
|
||||||
const [isFlashEnabled, setIsFlashEnabled] = useState<boolean>(buttonFlash);
|
const [isFlashEnabled, setIsFlashEnabled] = useState<boolean>(buttonFlash);
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
import { ComponentPropsWithoutRef } from "react";
|
import { ButtonWidgetFixedParams, ButtonWidgetParams } from "@/model/widget/button";
|
||||||
|
import { createPortal } from "react-dom";
|
||||||
import { Root, createRoot } from "react-dom/client";
|
import { Root, createRoot } from "react-dom/client";
|
||||||
import { pollForSelector } from "../shared/pollForSelector";
|
import { pollForSelector } from "../shared/pollForSelector";
|
||||||
import OpenQuizButton from "./OpenQuizButton";
|
import OpenQuizButton from "./OpenQuizButton";
|
||||||
import { createPortal } from "react-dom";
|
|
||||||
|
|
||||||
|
|
||||||
type ButtonWidgetProps = Omit<ComponentPropsWithoutRef<typeof OpenQuizButton>, "fixedSide">;
|
|
||||||
|
|
||||||
export class ButtonWidget {
|
export class ButtonWidget {
|
||||||
root: Root | undefined;
|
root: Root | undefined;
|
||||||
|
|
||||||
constructor(props: ButtonWidgetProps & {
|
constructor(props: ButtonWidgetParams) {
|
||||||
selector: string;
|
|
||||||
/**
|
|
||||||
* In seconds, null - polling disabled
|
|
||||||
*/
|
|
||||||
selectorPollingTimeLimit?: number | null;
|
|
||||||
}) {
|
|
||||||
const { selector, selectorPollingTimeLimit = 60 } = props;
|
const { selector, selectorPollingTimeLimit = 60 } = props;
|
||||||
|
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
@ -38,7 +30,7 @@ export class ButtonWidget {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props: ButtonWidgetProps) {
|
render(props: Omit<ButtonWidgetParams, "selector" | "selectorPollingTimeLimit">) {
|
||||||
this.root?.render(<OpenQuizButton {...props} />);
|
this.root?.render(<OpenQuizButton {...props} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,15 +39,11 @@ export class ButtonWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ButtonWidgetFixedProps = Omit<ComponentPropsWithoutRef<typeof OpenQuizButton>, "selector"> & {
|
|
||||||
fixedSide: "left" | "right";
|
|
||||||
};
|
|
||||||
|
|
||||||
export class ButtonWidgetFixed {
|
export class ButtonWidgetFixed {
|
||||||
root: Root | undefined;
|
root: Root | undefined;
|
||||||
element = document.createElement("div");
|
element = document.createElement("div");
|
||||||
|
|
||||||
constructor(props: ButtonWidgetFixedProps) {
|
constructor(props: ButtonWidgetFixedParams) {
|
||||||
this.element.style.setProperty("display", "none");
|
this.element.style.setProperty("display", "none");
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element);
|
||||||
|
|
||||||
@ -64,7 +52,7 @@ export class ButtonWidgetFixed {
|
|||||||
this.render(props);
|
this.render(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props: ButtonWidgetFixedProps) {
|
render(props: ButtonWidgetFixedParams) {
|
||||||
this.root?.render(createPortal(<OpenQuizButton {...props} />, document.body));
|
this.root?.render(createPortal(<OpenQuizButton {...props} />, document.body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ButtonWidgetComponentProps } from "@/model/widget/button";
|
||||||
import lightTheme from "@/utils/themes/light";
|
import lightTheme from "@/utils/themes/light";
|
||||||
import { Button, ThemeProvider, useMediaQuery } from "@mui/material";
|
import { Button, ThemeProvider, useMediaQuery } from "@mui/material";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
@ -9,24 +10,6 @@ import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
|||||||
const WIDGET_DEFAULT_WIDTH = "600px";
|
const WIDGET_DEFAULT_WIDTH = "600px";
|
||||||
const WIDGET_DEFAULT_HEIGHT = "80%";
|
const WIDGET_DEFAULT_HEIGHT = "80%";
|
||||||
|
|
||||||
interface Props {
|
|
||||||
quizId: string;
|
|
||||||
fixedSide?: "left" | "right";
|
|
||||||
dialogDimensions?: { width: string; height: string; };
|
|
||||||
/**
|
|
||||||
* Открыть квиз через X секунд, 0 - сразу
|
|
||||||
*/
|
|
||||||
autoShowQuizTime?: number | null;
|
|
||||||
hideOnMobile?: boolean;
|
|
||||||
openOnLeaveAttempt?: boolean;
|
|
||||||
buttonFlash?: boolean;
|
|
||||||
withShadow?: boolean;
|
|
||||||
rounded?: boolean;
|
|
||||||
buttonText?: string;
|
|
||||||
buttonTextColor?: string;
|
|
||||||
buttonBackgroundColor?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function OpenQuizButton({
|
export default function OpenQuizButton({
|
||||||
quizId,
|
quizId,
|
||||||
fixedSide,
|
fixedSide,
|
||||||
@ -40,7 +23,7 @@ export default function OpenQuizButton({
|
|||||||
buttonText = "Пройти квиз",
|
buttonText = "Пройти квиз",
|
||||||
buttonTextColor,
|
buttonTextColor,
|
||||||
buttonBackgroundColor,
|
buttonBackgroundColor,
|
||||||
}: Props) {
|
}: ButtonWidgetComponentProps) {
|
||||||
const isMobile = useMediaQuery("(max-width: 600px)");
|
const isMobile = useMediaQuery("(max-width: 600px)");
|
||||||
const [isQuizShown, setIsQuizShown] = useState<boolean>(false);
|
const [isQuizShown, setIsQuizShown] = useState<boolean>(false);
|
||||||
const isQuizCompleted = useQuizCompletionStatus(quizId);
|
const isQuizCompleted = useQuizCompletionStatus(quizId);
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
import { ComponentPropsWithoutRef } from "react";
|
import { ContainerWidgetParams } from "@/model/widget/container";
|
||||||
import { Root, createRoot } from "react-dom/client";
|
import { Root, createRoot } from "react-dom/client";
|
||||||
import { pollForSelector } from "../shared/pollForSelector";
|
import { pollForSelector } from "../shared/pollForSelector";
|
||||||
import QuizContainer from "./QuizContainer";
|
import QuizContainer from "./QuizContainer";
|
||||||
|
|
||||||
|
|
||||||
type Props = ComponentPropsWithoutRef<typeof QuizContainer>;
|
|
||||||
|
|
||||||
export class ContainerWidget {
|
export class ContainerWidget {
|
||||||
root: Root | undefined;
|
root: Root | undefined;
|
||||||
|
|
||||||
constructor(props: Props & {
|
constructor(props: ContainerWidgetParams) {
|
||||||
selector: string;
|
|
||||||
/**
|
|
||||||
* In seconds, null - polling disabled
|
|
||||||
*/
|
|
||||||
selectorPollingTimeLimit?: number | null;
|
|
||||||
}) {
|
|
||||||
const { selector, selectorPollingTimeLimit = 60 } = props;
|
const { selector, selectorPollingTimeLimit = 60 } = props;
|
||||||
|
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
@ -37,7 +29,7 @@ export class ContainerWidget {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props: Props) {
|
render(props: Omit<ContainerWidgetParams, "selector" | "selectorPollingTimeLimit">) {
|
||||||
this.root?.render(<QuizContainer {...props} />);
|
this.root?.render(<QuizContainer {...props} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
import QuizAnswerer from "@/components/QuizAnswerer";
|
import QuizAnswerer from "@/components/QuizAnswerer";
|
||||||
|
import { ContainerWidgetComponentProps } from "@/model/widget/container";
|
||||||
import { Box, useMediaQuery } from "@mui/material";
|
import { Box, useMediaQuery } from "@mui/material";
|
||||||
import { ComponentPropsWithoutRef } from "react";
|
|
||||||
import OpenQuizButton from "../button/OpenQuizButton";
|
import OpenQuizButton from "../button/OpenQuizButton";
|
||||||
|
|
||||||
|
|
||||||
type Props = ComponentPropsWithoutRef<typeof OpenQuizButton> & {
|
export default function QuizContainer(props: ContainerWidgetComponentProps) {
|
||||||
quizId: string;
|
|
||||||
showButtonOnMobile?: boolean;
|
|
||||||
dimensions?: { width: string; height: string; };
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function QuizContainer(props: Props) {
|
|
||||||
const { quizId, dimensions, showButtonOnMobile = false } = props;
|
const { quizId, dimensions, showButtonOnMobile = false } = props;
|
||||||
const isMobile = useMediaQuery("(max-width: 600px)");
|
const isMobile = useMediaQuery("(max-width: 600px)");
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
|
import { PopupWidgetParams } from "@/model/widget/popup";
|
||||||
import { Root, createRoot } from "react-dom/client";
|
import { Root, createRoot } from "react-dom/client";
|
||||||
import { ComponentPropsWithoutRef } from "react";
|
|
||||||
import QuizPopup from "./QuizPopup";
|
import QuizPopup from "./QuizPopup";
|
||||||
|
|
||||||
|
|
||||||
type Props = ComponentPropsWithoutRef<typeof QuizPopup>;
|
|
||||||
|
|
||||||
export class PopupWidget {
|
export class PopupWidget {
|
||||||
root: Root | undefined;
|
root: Root | undefined;
|
||||||
element = document.createElement("div");
|
element = document.createElement("div");
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: PopupWidgetParams) {
|
||||||
this.element.style.setProperty("display", "none");
|
this.element.style.setProperty("display", "none");
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element);
|
||||||
|
|
||||||
@ -18,7 +16,7 @@ export class PopupWidget {
|
|||||||
this.render(props);
|
this.render(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props: Props) {
|
render(props: PopupWidgetParams) {
|
||||||
this.root?.render(<QuizPopup {...props} />);
|
this.root?.render(<QuizPopup {...props} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,29 +2,19 @@ import { useEffect, useRef, useState } from "react";
|
|||||||
import QuizDialog from "../shared/QuizDialog";
|
import QuizDialog from "../shared/QuizDialog";
|
||||||
import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
||||||
import { useMediaQuery } from "@mui/material";
|
import { useMediaQuery } from "@mui/material";
|
||||||
|
import { PopupWidgetComponentProps } from "@/model/widget/popup";
|
||||||
|
|
||||||
|
|
||||||
const WIDGET_DEFAULT_WIDTH = "600px";
|
const WIDGET_DEFAULT_WIDTH = "600px";
|
||||||
const WIDGET_DEFAULT_HEIGHT = "80%";
|
const WIDGET_DEFAULT_HEIGHT = "80%";
|
||||||
|
|
||||||
interface Props {
|
|
||||||
quizId: string;
|
|
||||||
dialogDimensions?: { width: string; height: string; };
|
|
||||||
/**
|
|
||||||
* Открыть квиз через X секунд, 0 - сразу
|
|
||||||
*/
|
|
||||||
autoShowQuizTime?: number | null;
|
|
||||||
hideOnMobile?: boolean;
|
|
||||||
openOnLeaveAttempt?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function QuizPopup({
|
export default function QuizPopup({
|
||||||
quizId,
|
quizId,
|
||||||
dialogDimensions,
|
dialogDimensions,
|
||||||
autoShowQuizTime = null,
|
autoShowQuizTime = null,
|
||||||
hideOnMobile = false,
|
hideOnMobile = false,
|
||||||
openOnLeaveAttempt = false,
|
openOnLeaveAttempt = false,
|
||||||
}: Props) {
|
}: PopupWidgetComponentProps) {
|
||||||
const initialIsQuizShown = (autoShowQuizTime !== null || openOnLeaveAttempt) ? false : true;
|
const initialIsQuizShown = (autoShowQuizTime !== null || openOnLeaveAttempt) ? false : true;
|
||||||
|
|
||||||
const [isQuizShown, setIsQuizShown] = useState<boolean>(initialIsQuizShown);
|
const [isQuizShown, setIsQuizShown] = useState<boolean>(initialIsQuizShown);
|
||||||
|
@ -6,31 +6,13 @@ import QuizDialog from "../shared/QuizDialog";
|
|||||||
import RunningStripe from "../shared/RunningStripe";
|
import RunningStripe from "../shared/RunningStripe";
|
||||||
import { useAutoOpenTimer } from "../shared/useAutoOpenTimer";
|
import { useAutoOpenTimer } from "../shared/useAutoOpenTimer";
|
||||||
import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
||||||
|
import { SideWidgetComponentProps } from "@/model/widget/side";
|
||||||
|
|
||||||
|
|
||||||
const PADDING = 10;
|
const PADDING = 10;
|
||||||
const WIDGET_DEFAULT_WIDTH = "600px";
|
const WIDGET_DEFAULT_WIDTH = "600px";
|
||||||
const WIDGET_DEFAULT_HEIGHT = "800px";
|
const WIDGET_DEFAULT_HEIGHT = "800px";
|
||||||
|
|
||||||
interface Props {
|
|
||||||
quizId: string;
|
|
||||||
position: "left" | "right";
|
|
||||||
buttonBackgroundColor?: string;
|
|
||||||
buttonTextColor?: string;
|
|
||||||
dialogDimensions?: { width: string; height: string; };
|
|
||||||
fullScreen?: boolean;
|
|
||||||
buttonFlash?: boolean;
|
|
||||||
/**
|
|
||||||
* Скрывать виджет первые X секунд
|
|
||||||
*/
|
|
||||||
autoOpenTime?: number;
|
|
||||||
/**
|
|
||||||
* Открыть квиз через X секунд, 0 - сразу
|
|
||||||
*/
|
|
||||||
autoShowQuizTime?: number | null;
|
|
||||||
hideOnMobile?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function QuizSideButton({
|
export default function QuizSideButton({
|
||||||
quizId,
|
quizId,
|
||||||
position,
|
position,
|
||||||
@ -42,7 +24,7 @@ export default function QuizSideButton({
|
|||||||
autoOpenTime = 0,
|
autoOpenTime = 0,
|
||||||
autoShowQuizTime = null,
|
autoShowQuizTime = null,
|
||||||
hideOnMobile = false,
|
hideOnMobile = false,
|
||||||
}: Props) {
|
}: SideWidgetComponentProps) {
|
||||||
const [isQuizShown, setIsQuizShown] = useState<boolean>(false);
|
const [isQuizShown, setIsQuizShown] = useState<boolean>(false);
|
||||||
const isMobile = useMediaQuery("(max-width: 600px)");
|
const isMobile = useMediaQuery("(max-width: 600px)");
|
||||||
const isQuizCompleted = useQuizCompletionStatus(quizId);
|
const isQuizCompleted = useQuizCompletionStatus(quizId);
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
|
import { SideWidgetParams } from "@/model/widget/side";
|
||||||
import { Root, createRoot } from "react-dom/client";
|
import { Root, createRoot } from "react-dom/client";
|
||||||
import QuizSideButton from "./QuizSideButton";
|
import QuizSideButton from "./QuizSideButton";
|
||||||
import { ComponentPropsWithoutRef } from "react";
|
|
||||||
|
|
||||||
|
|
||||||
type Props = ComponentPropsWithoutRef<typeof QuizSideButton>;
|
|
||||||
|
|
||||||
export class SideWidget {
|
export class SideWidget {
|
||||||
root: Root | undefined;
|
root: Root | undefined;
|
||||||
element = document.createElement("div");
|
element = document.createElement("div");
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: SideWidgetParams) {
|
||||||
this.element.style.setProperty("display", "none");
|
this.element.style.setProperty("display", "none");
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element);
|
||||||
|
|
||||||
@ -18,7 +16,7 @@ export class SideWidget {
|
|||||||
this.render(props);
|
this.render(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props: Props) {
|
render(props: SideWidgetParams) {
|
||||||
this.root?.render(<QuizSideButton {...props} />);
|
this.root?.render(<QuizSideButton {...props} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user