mirror of
https://github.com/sheptikhinv/timers.git
synced 2026-02-07 07:41:36 +05:00
- added current time
- added start and end date - removed additional sections - fixed X button - renamed + and - buttons - some renaming
This commit is contained in:
parent
b120143726
commit
981ef867fb
7 changed files with 97 additions and 49 deletions
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Гринтаймер</title>
|
||||
<title>MetaTimer</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
button.button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
min-width: 48px;
|
||||
min-height: 48px;
|
||||
border-radius: 8px;
|
||||
background-color: #AB71ED;
|
||||
color: #FFFFFF;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,29 @@
|
|||
transform: translateY(4px);
|
||||
}
|
||||
|
||||
.dates_container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.dates_item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: black;
|
||||
border-radius: 16px;
|
||||
border-color: #DCC3F8;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
|
||||
font-family: 'Montserrat';
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.presets_buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
|||
|
|
@ -6,12 +6,30 @@ import styles from './Timer.module.css'
|
|||
const Timer = () => {
|
||||
const [timeManager, recreateTimeManager] = useState(() => new TimeManager(0))
|
||||
const [remainingTime, setRemainingTime] = useState({ minutes: 0, seconds: 0 });
|
||||
const [startDate, setStartDate] = useState('00:00');
|
||||
const [endDate, setEndDate] = useState('00:00');
|
||||
|
||||
const formatTime = (date: Date) => {
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${hours}:${minutes}`;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
timeManager.start()
|
||||
console.log("timer started")
|
||||
const interval = setInterval(() => {
|
||||
setRemainingTime(timeManager.getRemainingTime())
|
||||
setRemainingTime(timeManager.getRemainingTime());
|
||||
let startString = formatTime(timeManager.getStartDate());
|
||||
let endString = formatTime(timeManager.getEndDate());
|
||||
if (startString === endString) {
|
||||
setStartDate('00:00');
|
||||
setEndDate('00:00');
|
||||
}
|
||||
else {
|
||||
setStartDate(startString);
|
||||
setEndDate(endString);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
return () => {
|
||||
|
|
@ -29,14 +47,22 @@ const Timer = () => {
|
|||
<div className={styles.timer_container}>
|
||||
<div className={styles.top_buttons}>
|
||||
<div className={styles.minute_buttons}>
|
||||
<Button label='-1' onClick={handleSubstract}/>
|
||||
<Button label='+1' onClick={handleAdd}/>
|
||||
<Button label='-1 мин' onClick={handleSubstract}/>
|
||||
<Button label='+1 мин' onClick={handleAdd}/>
|
||||
</div>
|
||||
<Button label='X'/>
|
||||
<Button label='X' onClick={() => handleRecreation(-1)}/>
|
||||
</div>
|
||||
<div className={styles.clock}>
|
||||
<a onClick={handlePause} className={styles.clock_text}>{remainingTime.minutes}:{remainingTime.seconds < 10 ? '0' : ''}{remainingTime.seconds}</a>
|
||||
</div>
|
||||
<div className={styles.dates_container}>
|
||||
<div className={styles.dates_item}>
|
||||
{startDate}
|
||||
</div>
|
||||
<div className={styles.dates_item}>
|
||||
{endDate}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.presets_buttons}>
|
||||
<Button label='15' onClick={() => handleRecreation(15)}/>
|
||||
<Button label='30' onClick={() => handleRecreation(30)}/>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class TimeManager {
|
||||
private startDate: Date;
|
||||
private endDate: Date;
|
||||
private initialTime: number;
|
||||
private endTime: number;
|
||||
private pauseTime: number | null = null;
|
||||
|
|
@ -7,8 +9,10 @@ class TimeManager {
|
|||
private isPaused: boolean = false;
|
||||
|
||||
constructor(minutes: number) {
|
||||
this.startDate = new Date();
|
||||
this.initialTime = minutes * 60;
|
||||
this.endTime = Date.now() + this.initialTime * 1000;
|
||||
this.endDate = new Date(this.endTime);
|
||||
}
|
||||
|
||||
start(): void {
|
||||
|
|
@ -53,10 +57,12 @@ class TimeManager {
|
|||
|
||||
addTime(minutes: number): void {
|
||||
this.endTime += minutes * 60 * 1000;
|
||||
this.endDate = new Date(this.endTime);
|
||||
}
|
||||
|
||||
subtractTime(minutes: number): void {
|
||||
this.endTime = Math.max(Date.now(), this.endTime - minutes * 60 * 1000);
|
||||
this.endDate = new Date(this.endTime); // Обновляем endDate
|
||||
}
|
||||
|
||||
getRemainingTime(): { minutes: number; seconds: number } {
|
||||
|
|
@ -85,6 +91,14 @@ class TimeManager {
|
|||
this.pause()
|
||||
}
|
||||
}
|
||||
|
||||
getStartDate(): Date {
|
||||
return this.startDate;
|
||||
}
|
||||
|
||||
getEndDate(): Date {
|
||||
return this.endDate;
|
||||
}
|
||||
}
|
||||
|
||||
export default TimeManager
|
||||
|
|
@ -5,6 +5,12 @@ body, html {
|
|||
font-family: 'Montserrat', serif;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 32px;
|
||||
display: flex;
|
||||
|
|
@ -31,33 +37,3 @@ body, html {
|
|||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.notes_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 32px;
|
||||
padding: 32px;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.notes_container textarea {
|
||||
height: 100%;
|
||||
border: 1px dashed #000;
|
||||
resize: none;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
background-color: #FFF;
|
||||
border-radius: 32px;
|
||||
flex-direction: column;
|
||||
padding: 32px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
footer a {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
|
@ -1,11 +1,30 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import Timer from '../../components/Timer/Timer';
|
||||
import styles from './Timers.module.css';
|
||||
|
||||
const Timers = () => {
|
||||
const [time, setTime] = useState(new Date());
|
||||
|
||||
useEffect(() => {
|
||||
const intervalId = setInterval(() => {
|
||||
setTime(new Date());
|
||||
}, 500);
|
||||
|
||||
return () => clearInterval(intervalId);
|
||||
}, [])
|
||||
|
||||
const formatTime = (date: Date) => {
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
<header>
|
||||
<a className={`${styles.header_text} ${styles.title}`}>ГринТаймер</a>
|
||||
<header className={styles.header}>
|
||||
<a className={`${styles.header_text} ${styles.title}`}>MetaTimer</a>
|
||||
<a className={`${styles.header_text} ${styles.title}`}>{formatTime(time)}</a>
|
||||
</header>
|
||||
<div className={styles.timers_container}>
|
||||
<Timer/>
|
||||
|
|
@ -13,16 +32,6 @@ const Timers = () => {
|
|||
<Timer/>
|
||||
<Timer/>
|
||||
</div>
|
||||
<div className={styles.notes_container}>
|
||||
<a className={`${styles.title} ${styles.notes_text}`}>Заметки</a>
|
||||
<textarea></textarea>
|
||||
</div>
|
||||
<footer>
|
||||
<a className={`${styles.title} ${styles.notes_text}`}>Респекты</a>
|
||||
<a>Лиза +вайбик за макет</a>
|
||||
<a>Слава сигма за всё остальное</a>
|
||||
<a>Игорь красава с нами рядом сидел</a>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue