feat: add pomodoro timer tool

This commit is contained in:
MAZE 2024-08-30 22:21:23 +03:30
parent 1fd02f927c
commit bee391acfe
4 changed files with 67 additions and 51 deletions

View file

@ -9,4 +9,8 @@
background-color: var(--color-neutral-50); background-color: var(--color-neutral-50);
border: 1px solid var(--color-neutral-200); border: 1px solid var(--color-neutral-200);
border-radius: 8px; border-radius: 8px;
&.tall {
padding: 60px 0;
}
} }

View file

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

View file

@ -2,7 +2,6 @@ import { useState, useEffect, useRef, useMemo } from 'react';
import { FaUndo, FaPlay, FaPause } from 'react-icons/fa/index'; import { FaUndo, FaPlay, FaPause } from 'react-icons/fa/index';
import { IoMdSettings } from 'react-icons/io/index'; import { IoMdSettings } from 'react-icons/io/index';
import { Modal } from '@/components/modal';
import { Button } from '../generics/button'; import { Button } from '../generics/button';
import { Timer } from '@/components/timer'; import { Timer } from '@/components/timer';
import { Tabs } from './tabs'; import { Tabs } from './tabs';
@ -14,14 +13,9 @@ import { usePomodoroStore } from '@/stores/pomodoro';
import { useCloseListener } from '@/hooks/use-close-listener'; import { useCloseListener } from '@/hooks/use-close-listener';
import styles from './pomodoro.module.css'; import styles from './pomodoro.module.css';
import { Container } from '@/components/container';
interface PomodoroProps { export function Pomodoro() {
onClose: () => void;
open: () => void;
show: boolean;
}
export function Pomodoro({ onClose, open, show }: PomodoroProps) {
const [showSetting, setShowSetting] = useState(false); const [showSetting, setShowSetting] = useState(false);
const [selectedTab, setSelectedTab] = useState('pomodoro'); const [selectedTab, setSelectedTab] = useState('pomodoro');
@ -120,46 +114,43 @@ export function Pomodoro({ onClose, open, show }: PomodoroProps) {
}; };
return ( return (
<> <Container tight>
<Modal show={show} onClose={onClose}> <header className={styles.header}>
<header className={styles.header}> <h2 className={styles.title}>Pomodoro Timer</h2>
<h2 className={styles.title}>Pomodoro Timer</h2>
<div className={styles.button}> <div className={styles.button}>
<Button <Button
icon={<IoMdSettings />} icon={<IoMdSettings />}
tooltip="Change Times" tooltip="Change Times"
onClick={() => { onClick={() => {
onClose(); setShowSetting(true);
setShowSetting(true); }}
}} />
/>
</div>
</header>
<Tabs selectedTab={selectedTab} tabs={tabs} onSelect={setSelectedTab} />
<Timer timer={timer} />
<div className={styles.control}>
<p className={styles.completed}>
{completions[selectedTab] || 0} completed
</p>
<div className={styles.buttons}>
<Button
icon={<FaUndo />}
smallIcon
tooltip="Restart"
onClick={restart}
/>
<Button
icon={running ? <FaPause /> : <FaPlay />}
smallIcon
tooltip={running ? 'Pause' : 'Start'}
onClick={toggleRunning}
/>
</div>
</div> </div>
</Modal> </header>
<Tabs selectedTab={selectedTab} tabs={tabs} onSelect={setSelectedTab} />
<Timer tall timer={timer} />
<div className={styles.control}>
<p className={styles.completed}>
{completions[selectedTab] || 0} completed
</p>
<div className={styles.buttons}>
<Button
icon={<FaUndo />}
smallIcon
tooltip="Restart"
onClick={restart}
/>
<Button
icon={running ? <FaPause /> : <FaPlay />}
smallIcon
tooltip={running ? 'Pause' : 'Start'}
onClick={toggleRunning}
/>
</div>
</div>
<Setting <Setting
show={showSetting} show={showSetting}
@ -167,13 +158,11 @@ export function Pomodoro({ onClose, open, show }: PomodoroProps) {
onChange={times => { onChange={times => {
setShowSetting(false); setShowSetting(false);
setTimes(times); setTimes(times);
open();
}} }}
onClose={() => { onClose={() => {
setShowSetting(false); setShowSetting(false);
open();
}} }}
/> />
</> </Container>
); );
} }

View file

@ -0,0 +1,21 @@
---
import Layout from '@/layouts/layout.astro';
import Donate from '@/components/donate.astro';
import Hero from '@/components/tools/hero.astro';
import { Pomodoro as PomodoroTimer } from '@/components/tools/pomodoro';
import Footer from '@/components/footer.astro';
import About from '@/components/tools/about.astro';
import Source from '@/components/source.astro';
---
<Layout title="Pomodoro Timer — Moodist">
<Donate />
<Hero desc="Super simple Pomodoro timer." title="Pomodoro Timer" />
<PomodoroTimer client:load />
<About
text="Boost your productivity with our simple Pomodoro timer. Designed to help you stay focused, it breaks your work into manageable intervals with regular breaks, making it easier to stay on track and avoid burnout."
/>
<Source />
<Footer />
</Layout>