feat: add reverse timer

This commit is contained in:
MAZE 2024-08-31 19:39:31 +03:30
parent f3cea66847
commit 105f53ea02
8 changed files with 97 additions and 33 deletions

View file

@ -1,7 +1,7 @@
import { useEffect, useState, useRef, useMemo } from 'react';
import { Modal } from '@/components/modal';
import { Timer } from '@/components/timer';
import { Timer } from './timer';
import { dispatch } from '@/lib/event';
import { useSoundStore } from '@/stores/sound';
import { cn } from '@/helpers/styles';
@ -63,7 +63,7 @@ export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) {
useEffect(() => {
if (timeLeft === 0) {
setRunning(false);
// pause();
dispatch(FADE_OUT, { duration: 1000 });
setTimeSpent(0);
@ -107,7 +107,7 @@ export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) {
)}
</div>
{running ? <Timer displayHours={true} timer={timeLeft} /> : null}
{running ? <Timer reverse={timeSpent} timer={timeLeft} /> : null}
<div className={styles.buttons}>
{running && (

View file

@ -0,0 +1 @@
export { Reverse } from './reverse';

View file

@ -0,0 +1,30 @@
.reverse {
position: absolute;
top: 8px;
left: 8px;
padding: 4px 8px;
font-size: var(--font-2xsm);
color: var(--color-foreground-subtle);
background: linear-gradient(
var(--color-neutral-50),
var(--color-neutral-100)
);
border: 1px solid var(--color-neutral-200);
border-radius: 4px;
&::after {
position: absolute;
bottom: -1px;
left: 50%;
width: 75%;
height: 1px;
content: '';
background: linear-gradient(
90deg,
transparent,
var(--color-neutral-300),
transparent
);
transform: translateX(-50%);
}
}

View file

@ -0,0 +1,27 @@
import { padNumber } from '@/helpers/number';
import styles from './reverse.module.css';
interface ReverseProps {
time: number;
}
export function Reverse({ time }: ReverseProps) {
let hours = Math.floor(time / 3600);
let minutes = Math.floor((time % 3600) / 60);
let seconds = time % 60;
hours = isNaN(hours) ? 0 : hours;
minutes = isNaN(minutes) ? 0 : minutes;
seconds = isNaN(seconds) ? 0 : seconds;
const formattedHours = padNumber(hours);
const formattedMinutes = padNumber(minutes);
const formattedSeconds = padNumber(seconds);
return (
<div className={styles.reverse}>
- {formattedHours}:{formattedMinutes}:{formattedSeconds}
</div>
);
}

View file

@ -0,0 +1,29 @@
.timer {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 48px 0;
font-size: var(--font-xlg);
font-weight: 500;
background-color: var(--color-neutral-50);
border: 1px solid var(--color-neutral-200);
border-radius: 12px;
&::after {
position: absolute;
bottom: -1px;
left: 50%;
width: 75%;
height: 1px;
content: '';
background: linear-gradient(
90deg,
transparent,
var(--color-neutral-400),
transparent
);
transform: translateX(-50%);
}
}

View file

@ -1,15 +1,15 @@
import { Reverse } from './reverse';
import { padNumber } from '@/helpers/number';
import { cn } from '@/helpers/styles';
import styles from './timer.module.css';
interface TimerProps {
displayHours?: boolean;
tall?: boolean;
reverse: number;
timer: number;
}
export function Timer({ displayHours = false, tall, timer }: TimerProps) {
export function Timer({ reverse, timer }: TimerProps) {
let hours = Math.floor(timer / 3600);
let minutes = Math.floor((timer % 3600) / 60);
let seconds = timer % 60;
@ -23,16 +23,9 @@ export function Timer({ displayHours = false, tall, timer }: TimerProps) {
const formattedSeconds = padNumber(seconds);
return (
<div className={cn(styles.timer, tall && styles.tall)}>
{displayHours ? (
<>
{formattedHours}:{formattedMinutes}:{formattedSeconds}
</>
) : (
<>
{formattedMinutes}:{formattedSeconds}
</>
)}
<div className={styles.timer}>
<Reverse time={reverse} />
{formattedHours}:{formattedMinutes}:{formattedSeconds}
</div>
);
}

View file

@ -1,16 +0,0 @@
.timer {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 30px 0;
font-size: var(--font-xlg);
font-weight: 500;
background-color: var(--color-neutral-50);
border: 1px solid var(--color-neutral-200);
border-radius: 8px;
&.tall {
padding: 60px 0;
}
}