diff --git a/CHANGELOG.md b/CHANGELOG.md index dee49d8..6bf84bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +1.0.3 Добавлена функция отсчёта до конца жизни квиза 1.0.2 Страничка результатов способна показать историю и правильность ответов для балловго квиза 1.0.1 Отображение для баллового квиза на страничке результатов списка 1.0.0 Добавлены фичи "мультиответ", "перенос строки в своём ответе", "свой ответ", "плейсхолдер своего ответа" diff --git a/lib/components/ViewPublicationPage/StartPageViewPublication/OverTime.tsx b/lib/components/ViewPublicationPage/StartPageViewPublication/OverTime.tsx new file mode 100644 index 0000000..430cb1c --- /dev/null +++ b/lib/components/ViewPublicationPage/StartPageViewPublication/OverTime.tsx @@ -0,0 +1,213 @@ +import { Box, Typography, useTheme, SxProps, Theme } from "@mui/material"; +import { useQuizStore } from "@stores/useQuizStore"; +import moment from "moment"; +import React from "react"; +import { useTranslation } from "react-i18next"; + +type OverTimeProps = { + sx?: SxProps; +}; + +export const OverTime = ({ sx }: OverTimeProps) => { + const theme = useTheme(); + const { settings } = useQuizStore(); + const { t } = useTranslation(); + const [currentTime, setCurrentTime] = React.useState(moment()); + + // Реактивный таймер с useEffect + React.useEffect(() => { + const interval = setInterval(() => { + setCurrentTime(moment()); + }, 1000); + + return () => clearInterval(interval); + }, []); + + // Проверяем, включен ли overTime + const overTimeConfig = settings?.cfg?.overTime; + const isEnabled = overTimeConfig?.enabled; + + // Если не включен, не показываем карточку + if (!isEnabled) { + return null; + } + + // Функция для расчета времени до окончания + const calculateTimeLeft = (now: moment.Moment) => { + // Для тестирования: добавляем 2 часа к текущему времени + const testEndsAt = moment().add(2, "hours"); + const endsAt = overTimeConfig?.endsAt ? moment(overTimeConfig.endsAt) : testEndsAt; + + if (endsAt.isBefore(now) || endsAt.isSame(now)) { + return { days: 0, hours: 0, minutes: 0, seconds: 0 }; + } + + const duration = moment.duration(endsAt.diff(now)); + + return { + days: Math.floor(duration.asDays()), + hours: duration.hours(), + minutes: duration.minutes(), + seconds: duration.seconds(), + }; + }; + + const { days, hours, minutes, seconds } = calculateTimeLeft(currentTime); + + return ( + + + {overTimeConfig?.description || t("Quiz will become unavailable in")} + + + + + {days} + + + {t("days")} + + + : + + + {hours} + + + {t("hours")} + + + : + + + {minutes} + + + {t("minutes")} + + + : + + + {seconds} + + + {t("seconds")} + + + + + ); +}; diff --git a/lib/components/ViewPublicationPage/StartPageViewPublication/index.tsx b/lib/components/ViewPublicationPage/StartPageViewPublication/index.tsx index 5985654..b3f813d 100644 --- a/lib/components/ViewPublicationPage/StartPageViewPublication/index.tsx +++ b/lib/components/ViewPublicationPage/StartPageViewPublication/index.tsx @@ -18,6 +18,9 @@ import { useYandexMetricsGoals } from "@/utils/hooks/metrics/useYandexMetricsGoa import QuizVideo from "@/ui_kit/VideoIframe/VideoIframe"; import { isProduction } from "@/utils/defineDomain"; +import { useEffect, useState } from "react"; +import moment from "moment"; +import { OverTime } from "./OverTime"; export const StartPageViewPublication = () => { const theme = useTheme(); @@ -32,6 +35,17 @@ export const StartPageViewPublication = () => { const vkMetrics = useVkMetricsGoals(settings.cfg.vkMetricsNumber); const yandexMetrics = useYandexMetricsGoals(settings.cfg.yandexMetricsNumber); + const [currentTime, setCurrentTime] = useState(moment()); + + // Реактивный таймер для обновления времени + useEffect(() => { + const interval = setInterval(() => { + setCurrentTime(moment()); + }, 1000); + + return () => clearInterval(interval); + }, []); + const handleCopyNumber = () => { navigator.clipboard.writeText(settings.cfg.info.phonenumber); @@ -39,15 +53,6 @@ export const StartPageViewPublication = () => { yandexMetrics.phoneNumberOpened(); }; - console.log("------------------------------------------------"); - console.log("Background type:", settings.cfg.startpage.background.type); - console.log("Is image type:", settings.cfg.startpage.background.type === "image"); - console.log("Is video type:", settings.cfg.startpage.background.type === "video"); - console.log("Video URL:", settings.cfg.startpage.background.video); - console.log("Desktop background:", settings.cfg.startpage.background.desktop); - console.log("Startpage type:", settings.cfg.startpageType); - console.log("------------------------------------------------"); - const background = settings.cfg.startpage.background.type === "image" ? ( { { {settings.cfg.info.orgname} + {((settings.cfg.startpageType === "expanded" && settings.cfg.startpage.position !== "center") || + (isMobile && settings.cfg.startpageType === "expanded")) && } ); @@ -159,13 +172,6 @@ export const StartPageViewPublication = () => { alignItems: "center", gap: "7px", textDecoration: "none", - marginLeft: - settings.cfg.startpageType === "expanded" && - settings.cfg.startpage.position === "center" && - !isTablet && - !isMobile - ? "61px" - : undefined, }} > {settings.cfg.startpageType === "expanded" ? ( @@ -182,6 +188,14 @@ export const StartPageViewPublication = () => { (question) => question.type !== null && question.type !== "result" ).length; + // Проверяем, истекло ли время для overTime + const overTimeConfig = settings?.cfg?.overTime; + const isOverTimeEnabled = overTimeConfig?.enabled; + const isTimeExpired = + isOverTimeEnabled && overTimeConfig?.endsAt + ? currentTime.isAfter(moment(overTimeConfig.endsAt)) || currentTime.isSame(moment(overTimeConfig.endsAt)) + : false; + const onQuizStart = () => { setCurrentQuizStep("question"); @@ -289,7 +303,7 @@ export const StartPageViewPublication = () => {