frontAnswerer/lib/components/ViewPublicationPage/StartPageViewPublication/OverTime.tsx

214 lines
5.6 KiB
TypeScript
Raw Normal View History

2025-10-22 18:07:27 +00:00
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<Theme>;
};
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 (
<Box
sx={{
width: "225px",
backgroundColor: (theme.palette as any).paperBackground,
boxShadow: "1px 1px 4px 0px rgba(51, 54, 71, 0.29)",
borderRadius: "8px",
p: "10px",
...sx,
}}
>
<Typography
sx={{
fontSize: "12px",
color: (theme.palette as any).paperText,
textAlign: "center",
}}
>
{overTimeConfig?.description || t("Quiz will become unavailable in")}
</Typography>
<Box
sx={{
display: "inline-flex",
justifyContent: "space-around",
alignItems: "center",
width: "100%",
mt: "8px",
color: (theme.palette as any).paperSecondaryText,
}}
>
<Box
sx={{
bgcolor: (theme.palette as any).paperBlockBackground,
width: "42px",
height: "45px",
display: "flex",
flexDirection: "column",
alignItems: "center",
borderRadius: "8px",
justifyContent: "center",
}}
>
<Typography
sx={{
fontSize: "16px",
color: (theme.palette as any).paperText,
lineHeight: 1.2,
}}
>
{days}
</Typography>
<Typography
sx={{
fontSize: "10px",
lineHeight: 1.2,
}}
>
{t("days")}
</Typography>
</Box>
:
<Box
sx={{
bgcolor: (theme.palette as any).paperBlockBackground,
width: "42px",
height: "45px",
display: "flex",
flexDirection: "column",
alignItems: "center",
borderRadius: "8px",
justifyContent: "center",
}}
>
<Typography
sx={{
fontSize: "16px",
color: (theme.palette as any).paperText,
lineHeight: 1.2,
}}
>
{hours}
</Typography>
<Typography
sx={{
fontSize: "10px",
lineHeight: 1.2,
}}
>
{t("hours")}
</Typography>
</Box>
:
<Box
sx={{
bgcolor: (theme.palette as any).paperBlockBackground,
width: "42px",
height: "45px",
display: "flex",
flexDirection: "column",
alignItems: "center",
borderRadius: "8px",
justifyContent: "center",
}}
>
<Typography
sx={{
fontSize: "16px",
color: (theme.palette as any).paperText,
lineHeight: 1.2,
}}
>
{minutes}
</Typography>
<Typography
sx={{
fontSize: "10px",
lineHeight: 1.2,
}}
>
{t("minutes")}
</Typography>
</Box>
:
<Box
sx={{
bgcolor: (theme.palette as any).paperBlockBackground,
width: "42px",
height: "45px",
display: "flex",
flexDirection: "column",
alignItems: "center",
borderRadius: "8px",
justifyContent: "center",
}}
>
<Typography
sx={{
fontSize: "16px",
color: (theme.palette as any).paperText,
lineHeight: 1.2,
}}
>
{seconds}
</Typography>
<Typography
sx={{
fontSize: "10px",
lineHeight: 1.2,
}}
>
{t("seconds")}
</Typography>
</Box>
</Box>
</Box>
);
};