88 lines
2.3 KiB
React
88 lines
2.3 KiB
React
import React, { useState, useEffect } from 'react';
|
|
import './Timer.css';
|
|
|
|
const Timer = ({ timeLimit, onTimeExpired, isActive }) => {
|
|
const [timeLeft, setTimeLeft] = useState(timeLimit);
|
|
const [isWarning, setIsWarning] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (!isActive) return;
|
|
|
|
setTimeLeft(timeLimit);
|
|
setIsWarning(false);
|
|
|
|
const timer = setInterval(() => {
|
|
setTimeLeft((prevTime) => {
|
|
if (prevTime <= 1) {
|
|
clearInterval(timer);
|
|
onTimeExpired();
|
|
return 0;
|
|
}
|
|
return prevTime - 1;
|
|
});
|
|
}, 1000);
|
|
|
|
return () => clearInterval(timer);
|
|
}, [timeLimit, isActive, onTimeExpired]);
|
|
|
|
useEffect(() => {
|
|
// Активируем предупреждение за последние 5 секунд
|
|
setIsWarning(timeLeft <= 5 && timeLeft > 0);
|
|
}, [timeLeft]);
|
|
|
|
const formatTime = (seconds) => {
|
|
const mins = Math.floor(seconds / 60);
|
|
const secs = seconds % 60;
|
|
if (mins > 0) {
|
|
return `${mins}:${secs.toString().padStart(2, '0')}`;
|
|
}
|
|
return `${secs} сек`;
|
|
};
|
|
|
|
const getTimerClass = () => {
|
|
if (!isActive) return 'timer paused';
|
|
if (isWarning) return 'timer warning';
|
|
if (timeLeft <= 10) return 'timer critical';
|
|
return 'timer';
|
|
};
|
|
|
|
const getProgressPercent = () => {
|
|
return (timeLeft / timeLimit) * 100;
|
|
};
|
|
|
|
return (
|
|
<div className={getTimerClass()}>
|
|
<div className="timer-circle">
|
|
<svg className="timer-svg" viewBox="0 0 100 100">
|
|
<circle
|
|
className="timer-bg"
|
|
cx="50"
|
|
cy="50"
|
|
r="45"
|
|
fill="none"
|
|
stroke="#e0e0e0"
|
|
strokeWidth="8"
|
|
/>
|
|
<circle
|
|
className="timer-progress"
|
|
cx="50"
|
|
cy="50"
|
|
r="45"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="8"
|
|
strokeDasharray={`${2 * Math.PI * 45}`}
|
|
strokeDashoffset={`${2 * Math.PI * 45 * (1 - getProgressPercent() / 100)}`}
|
|
transform="rotate(-90 50 50)"
|
|
/>
|
|
</svg>
|
|
<div className="timer-text">
|
|
<span className="timer-label">Осталось</span>
|
|
<span className="timer-value">{formatTime(timeLeft)}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Timer; |