add opportunity to see how much time till shift ends

This commit is contained in:
Вячеслав 2025-07-13 18:31:21 +05:00
parent 54cb4607c5
commit 359e3c7483
4 changed files with 77 additions and 14 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "timers", "name": "timers",
"private": true, "private": true,
"version": "1.1.0", "version": "1.2.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View file

@ -8,6 +8,12 @@ interface ReleaseListProps {
const ReleaseList = ({isOpen, onClose}: ReleaseListProps) => { const ReleaseList = ({isOpen, onClose}: ReleaseListProps) => {
return ( return (
<Surface isOpen={isOpen} onClose={onClose}> <Surface isOpen={isOpen} onClose={onClose}>
<h1>v1.2.0 - А когда домой?</h1>
<h2>13.07.2025</h2>
При нажатии на время в верхней части страницы будет показываться оставшееся время до коцна смены
<hr/>
<h1>v1.1.0 - Я все помню</h1> <h1>v1.1.0 - Я все помню</h1>
<h2>14.06.2025</h2> <h2>14.06.2025</h2>
При обновлении страницы все таймеры сохранят свое состояние, при условии что были созданы сегодня При обновлении страницы все таймеры сохранят свое состояние, при условии что были созданы сегодня

View file

@ -19,3 +19,42 @@ export const isToday = (date: Date) => {
date.getDate() === today.getDate() date.getDate() === today.getDate()
); );
} }
export const timeTillDate = (date: Date): string => {
const now = new Date();
let diff = date.getTime() - now.getTime();
if (diff <= 0) return "00:00:00";
const hours = Math.floor(diff / (1000 * 60 * 60));
diff %= 1000 * 60 * 60;
const minutes = Math.floor(diff / (1000 * 60));
diff %= 1000 * 60;
const seconds = Math.floor(diff / 1000);
const pad = (num: number) => String(num).padStart(2, '0');
return `-${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
};
export const getClosestTime = (hour: number, minute: number): Date => {
const now = new Date();
const target = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
hour,
minute,
0,
0
);
if (target <= now) {
// Добавляем 1 день, если время уже прошло
target.setDate(target.getDate() + 1);
}
return target;
};

View file

@ -1,14 +1,14 @@
import {useEffect, useState} from 'react'; import {useEffect, useState} from 'react';
import Timer from '../../components/Timer/Timer'; import Timer from '../../components/Timer/Timer';
import styles from './Timers.module.css'; import styles from './Timers.module.css';
import {formatFullTime} from "../../helpers/DateFunctions.ts"; import {formatFullTime, getClosestTime, timeTillDate} from "../../helpers/DateFunctions.ts";
import ReleaseList from "../../components/ReleaseList/ReleaseList.tsx"; import ReleaseList from "../../components/ReleaseList/ReleaseList.tsx";
import Button from "../../components/Button/Button.tsx"; import Button from "../../components/Button/Button.tsx";
const Timers = () => { const Timers = () => {
const [time, setTime] = useState(new Date()); const [time, setTime] = useState(new Date());
const [isReleasesListOpen, setIsReleasesListOpen] = useState(false); const [isReleasesListOpen, setIsReleasesListOpen] = useState(false);
const [isReverseTime, setIsReverseTime] = useState(false);
useEffect(() => { useEffect(() => {
const intervalId = setInterval(() => { const intervalId = setInterval(() => {
@ -16,27 +16,45 @@ const Timers = () => {
}, 500); }, 500);
return () => clearInterval(intervalId); return () => clearInterval(intervalId);
}, []) }, []);
const handleToggleTime = () => {
setIsReverseTime((prev) => !prev);
};
const targetTime = getClosestTime(22, 0);
const displayTime = isReverseTime ? timeTillDate(targetTime) : formatFullTime(time);
return ( return (
<> <>
<div className={styles.content}> <div className={styles.content}>
<header className={styles.header}> <header className={styles.header}>
<a className={`${styles.header_text} ${styles.title} ${styles.header_item}`}>MetaTimer</a> <a className={`${styles.header_text} ${styles.title} ${styles.header_item}`}>
<a className={`${styles.header_text} ${styles.title} ${styles.header_item}`}>{formatFullTime(time)}</a> MetaTimer
<Button className={styles.header_item} label={"?"} onClick={() => setIsReleasesListOpen(!isReleasesListOpen)}/> </a>
<a
className={`${styles.header_text} ${styles.title} ${styles.header_item}`}
onClick={handleToggleTime}
style={{ cursor: 'pointer' }}
>
{displayTime}
</a>
<Button
className={styles.header_item}
label={"?"}
onClick={() => setIsReleasesListOpen(!isReleasesListOpen)}
/>
</header> </header>
<div className={styles.timers_container}> <div className={styles.timers_container}>
<Timer id={"timer_1"}/> <Timer id={"timer_1"} />
<Timer id={"timer_2"}/> <Timer id={"timer_2"} />
<Timer id={"timer_3"}/> <Timer id={"timer_3"} />
<Timer id={"timer_4"}/> <Timer id={"timer_4"} />
</div> </div>
</div> </div>
<ReleaseList isOpen={isReleasesListOpen} onClose={() => setIsReleasesListOpen(false)} /> <ReleaseList isOpen={isReleasesListOpen} onClose={() => setIsReleasesListOpen(false)} />
</> </>
) );
} };
export default Timers; export default Timers;