diff --git a/src/components/about.astro b/src/components/about.astro index 8d5af25..7e354fa 100644 --- a/src/components/about.astro +++ b/src/components/about.astro @@ -19,7 +19,7 @@ const paragraphs = [ title: 'Create Your Soundscape', }, { - body: 'Moodist offers more than ambient sounds with its suite of productivity tools to keep you organized and focused. Use the built-in pomodoro timer for structured work intervals, jot down ideas in the notepad, track tasks with the to-do list (coming soon), and set multiple timers with the distraction-free countdown timer. These tools integrate seamlessly with the ambient soundscapes, creating a personalized environment that fosters focus and relaxation.', + body: 'Moodist offers more than ambient sounds with its suite of productivity tools to keep you organized and focused. Use the built-in pomodoro timer for structured work intervals, jot down ideas in the notepad, and track tasks with the to-do list (coming soon). These tools integrate seamlessly with the ambient soundscapes, creating a personalized environment that fosters focus and relaxation.', title: 'A Productivity Toolbox', }, { diff --git a/src/components/menu/items/countdown-timer.tsx b/src/components/menu/items/countdown-timer.tsx index 68c9647..51e3714 100644 --- a/src/components/menu/items/countdown-timer.tsx +++ b/src/components/menu/items/countdown-timer.tsx @@ -2,17 +2,12 @@ import { MdOutlineTimer } from 'react-icons/md/index'; import { Item } from '../item'; -interface SleepTimerProps { - open: () => void; -} - -export function CountdownTimer({ open }: SleepTimerProps) { +export function CountdownTimer() { return ( } label="Countdown Timer" - shortcut="Shift + C" - onClick={open} /> ); } diff --git a/src/components/menu/menu.tsx b/src/components/menu/menu.tsx index 1106dee..ff3eb12 100644 --- a/src/components/menu/menu.tsx +++ b/src/components/menu/menu.tsx @@ -22,12 +22,7 @@ import { ShareLinkModal } from '@/components/modals/share-link'; import { PresetsModal } from '@/components/modals/presets'; import { ShortcutsModal } from '@/components/modals/shortcuts'; import { SleepTimerModal } from '@/components/modals/sleep-timer'; -import { - Notepad, - Pomodoro, - CountdownTimer, - BreathingExercise, -} from '@/components/toolbox'; +import { Notepad, Pomodoro, BreathingExercise } from '@/components/toolbox'; import { fade, mix, slideY } from '@/lib/motion'; import { useSoundStore } from '@/stores/sound'; @@ -43,7 +38,6 @@ export function Menu() { const initial = useMemo( () => ({ breathingExercise: false, - countdownTimer: false, notepad: false, pomodoro: false, presets: false, @@ -75,7 +69,6 @@ export function Menu() { useHotkeys('shift+m', () => setIsOpen(prev => !prev)); useHotkeys('shift+n', () => open('notepad')); useHotkeys('shift+p', () => open('pomodoro')); - useHotkeys('shift+c', () => open('countdownTimer')); useHotkeys('shift+b', () => open('breathingExercise')); useHotkeys('shift+alt+p', () => open('presets')); useHotkeys('shift+h', () => open('shortcuts')); @@ -124,7 +117,7 @@ export function Menu() { /> open('pomodoro')} /> open('notepad')} /> - open('countdownTimer')} /> + open('shortcuts')} /> @@ -159,10 +152,6 @@ export function Menu() { show={modals.breathingExercise} onClose={() => close('breathingExercise')} /> - close('countdownTimer')} - /> close('sleepTimer')} diff --git a/src/components/modals/shortcuts/shortcuts.tsx b/src/components/modals/shortcuts/shortcuts.tsx index aa8efde..d5733b7 100644 --- a/src/components/modals/shortcuts/shortcuts.tsx +++ b/src/components/modals/shortcuts/shortcuts.tsx @@ -33,10 +33,6 @@ export function ShortcutsModal({ onClose, show }: ShortcutsModalProps) { keys: ['Shift', 'B'], label: 'Breathing Exercise', }, - { - keys: ['Shift', 'C'], - label: 'Countdown Timer', - }, { keys: ['Shift', 'T'], label: 'Sleep Timer', diff --git a/src/components/toolbox/countdown-timer/countdown-timer.module.css b/src/components/toolbox/countdown-timer/countdown-timer.module.css deleted file mode 100644 index 8e73cc6..0000000 --- a/src/components/toolbox/countdown-timer/countdown-timer.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.title { - margin-bottom: 16px; - font-family: var(--font-heading); - font-size: var(--font-md); - font-weight: 600; -} diff --git a/src/components/toolbox/countdown-timer/countdown-timer.tsx b/src/components/toolbox/countdown-timer/countdown-timer.tsx deleted file mode 100644 index 30629ae..0000000 --- a/src/components/toolbox/countdown-timer/countdown-timer.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useAutoAnimate } from '@formkit/auto-animate/react'; - -import { Modal } from '@/components/modal'; - -import { Form } from './form'; -import { Timers } from './timers'; - -import styles from './countdown-timer.module.css'; - -interface TimerProps { - onClose: () => void; - show: boolean; -} - -export function CountdownTimer({ onClose, show }: TimerProps) { - const [containerRef, enableAnimations] = useAutoAnimate(); - - return ( - -

Countdown Timer

-
- - - ); -} diff --git a/src/components/toolbox/countdown-timer/form/field/field.module.css b/src/components/toolbox/countdown-timer/form/field/field.module.css deleted file mode 100644 index 585811f..0000000 --- a/src/components/toolbox/countdown-timer/form/field/field.module.css +++ /dev/null @@ -1,27 +0,0 @@ -.field { - flex-grow: 1; - - & .label { - display: block; - margin-bottom: 8px; - font-size: var(--font-sm); - font-weight: 500; - - & .optional { - font-weight: 400; - color: var(--color-foreground-subtle); - } - } - - & .input { - width: 100%; - min-width: 0; - height: 40px; - padding: 0 16px; - color: var(--color-foreground); - background-color: var(--color-neutral-50); - border: 1px solid var(--color-neutral-200); - border-radius: 4px; - outline: none; - } -} diff --git a/src/components/toolbox/countdown-timer/form/field/field.tsx b/src/components/toolbox/countdown-timer/form/field/field.tsx deleted file mode 100644 index 6b057a8..0000000 --- a/src/components/toolbox/countdown-timer/form/field/field.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import styles from './field.module.css'; - -interface FieldProps { - children?: React.ReactNode; - label: string; - onChange: (value: string | number) => void; - optional?: boolean; - type: 'text' | 'select'; - value: string | number; -} - -export function Field({ - children, - label, - onChange, - optional, - type, - value, -}: FieldProps) { - return ( -
- - - {type === 'text' && ( - onChange(e.target.value)} - /> - )} - - {type === 'select' && ( - - )} -
- ); -} diff --git a/src/components/toolbox/countdown-timer/form/field/index.ts b/src/components/toolbox/countdown-timer/form/field/index.ts deleted file mode 100644 index 497b3a7..0000000 --- a/src/components/toolbox/countdown-timer/form/field/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Field } from './field'; diff --git a/src/components/toolbox/countdown-timer/form/form.module.css b/src/components/toolbox/countdown-timer/form/form.module.css deleted file mode 100644 index 8b1cf2b..0000000 --- a/src/components/toolbox/countdown-timer/form/form.module.css +++ /dev/null @@ -1,27 +0,0 @@ -.form { - display: flex; - flex-direction: column; - row-gap: 28px; - - & .button { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 45px; - font-weight: 500; - color: var(--color-neutral-50); - cursor: pointer; - background-color: var(--color-neutral-950); - border: none; - border-radius: 4px; - outline: none; - } -} - -.timeFields { - display: flex; - column-gap: 12px; - align-items: flex-end; - justify-content: space-between; -} diff --git a/src/components/toolbox/countdown-timer/form/form.tsx b/src/components/toolbox/countdown-timer/form/form.tsx deleted file mode 100644 index 275c915..0000000 --- a/src/components/toolbox/countdown-timer/form/form.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { useState, useMemo } from 'react'; - -import { Field } from './field'; - -import { useCountdownTimers } from '@/stores/countdown-timers'; -import { waitUntil } from '@/helpers/wait'; - -import styles from './form.module.css'; - -interface FormProps { - enableAnimations: (enabled: boolean) => void; -} - -export function Form({ enableAnimations }: FormProps) { - const [name, setName] = useState(''); - const [hours, setHours] = useState(0); - const [minutes, setMinutes] = useState(10); - const [seconds, setSeconds] = useState(0); - - const totalSeconds = useMemo( - () => hours * 60 * 60 + minutes * 60 + seconds, - [hours, minutes, seconds], - ); - - const add = useCountdownTimers(state => state.add); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - - if (totalSeconds === 0) return; - - enableAnimations(false); - - const id = add({ - name, - total: totalSeconds, - }); - - setName(''); - - await waitUntil(() => !!document.getElementById(`timer-${id}`), 50); - - document - .getElementById(`timer-${id}`) - ?.scrollIntoView({ behavior: 'smooth' }); - - enableAnimations(true); - }; - - return ( - - setName(value as string)} - /> - -
- setHours(value as number)} - > - {Array(13) - .fill(null) - .map((_, index) => ( - - ))} - - - setMinutes(value as number)} - > - {Array(60) - .fill(null) - .map((_, index) => ( - - ))} - - - setSeconds(value as number)} - > - {Array(60) - .fill(null) - .map((_, index) => ( - - ))} - -
- - - - ); -} diff --git a/src/components/toolbox/countdown-timer/form/index.ts b/src/components/toolbox/countdown-timer/form/index.ts deleted file mode 100644 index 9398c9e..0000000 --- a/src/components/toolbox/countdown-timer/form/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Form } from './form'; diff --git a/src/components/toolbox/countdown-timer/index.ts b/src/components/toolbox/countdown-timer/index.ts deleted file mode 100644 index 104cbaf..0000000 --- a/src/components/toolbox/countdown-timer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CountdownTimer } from './countdown-timer'; diff --git a/src/components/toolbox/countdown-timer/timers/index.ts b/src/components/toolbox/countdown-timer/timers/index.ts deleted file mode 100644 index 0f9e27a..0000000 --- a/src/components/toolbox/countdown-timer/timers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Timers } from './timers'; diff --git a/src/components/toolbox/countdown-timer/timers/notice/index.ts b/src/components/toolbox/countdown-timer/timers/notice/index.ts deleted file mode 100644 index 64af78d..0000000 --- a/src/components/toolbox/countdown-timer/timers/notice/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Notice } from './notice'; diff --git a/src/components/toolbox/countdown-timer/timers/notice/notice.module.css b/src/components/toolbox/countdown-timer/timers/notice/notice.module.css deleted file mode 100644 index 0c82d8b..0000000 --- a/src/components/toolbox/countdown-timer/timers/notice/notice.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.notice { - padding: 16px; - margin-top: 16px; - font-size: var(--font-sm); - line-height: 1.65; - color: var(--color-foreground-subtle); - text-align: center; - background-color: var(--color-neutral-50); - border: 1px dashed var(--color-neutral-300); - border-radius: 8px; -} diff --git a/src/components/toolbox/countdown-timer/timers/notice/notice.tsx b/src/components/toolbox/countdown-timer/timers/notice/notice.tsx deleted file mode 100644 index 1f019cb..0000000 --- a/src/components/toolbox/countdown-timer/timers/notice/notice.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import styles from './notice.module.css'; - -export function Notice() { - return ( -

- Please do not close your browser tab while timers are running, otherwise - all timers will be stopped. -

- ); -} diff --git a/src/components/toolbox/countdown-timer/timers/timer/index.ts b/src/components/toolbox/countdown-timer/timers/timer/index.ts deleted file mode 100644 index 91b3f08..0000000 --- a/src/components/toolbox/countdown-timer/timers/timer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Timer } from './timer'; diff --git a/src/components/toolbox/countdown-timer/timers/timer/timer.module.css b/src/components/toolbox/countdown-timer/timers/timer/timer.module.css deleted file mode 100644 index 17345bc..0000000 --- a/src/components/toolbox/countdown-timer/timers/timer/timer.module.css +++ /dev/null @@ -1,127 +0,0 @@ -.timer { - position: relative; - padding: 8px; - overflow: hidden; - background-color: var(--color-neutral-100); - border: 1px solid var(--color-neutral-200); - border-radius: 8px; - - &:not(:last-of-type) { - margin-bottom: 24px; - } - - & .header { - position: relative; - top: -8px; - width: 100%; - - & .bar { - height: 2px; - margin: 0 -8px; - background-color: var(--color-neutral-200); - - & .completed { - height: 100%; - background-color: var(--color-neutral-500); - transition: 0.2s; - } - } - } - - & .footer { - display: flex; - column-gap: 4px; - align-items: center; - - & .control { - display: flex; - flex-grow: 1; - column-gap: 4px; - align-items: center; - height: 40px; - padding: 4px; - background-color: var(--color-neutral-50); - border: 1px solid var(--color-neutral-200); - border-radius: 4px; - - & .input { - flex-grow: 1; - width: 100%; - min-width: 0; - height: 100%; - padding: 0 8px; - color: var(--color-foreground-subtle); - background-color: transparent; - border: none; - border-radius: 4px; - outline: none; - - &.finished { - text-decoration: line-through; - } - } - - & .button { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - aspect-ratio: 1 / 1; - color: var(--color-foreground); - cursor: pointer; - background-color: var(--color-neutral-200); - border: 1px solid var(--color-neutral-300); - border-radius: 2px; - outline: none; - transition: 0.2s; - - &.reset { - background-color: var(--color-neutral-100); - border: none; - } - - &:disabled, - &.disabled { - cursor: not-allowed; - opacity: 0.6; - } - } - } - - & .delete { - display: flex; - align-items: center; - justify-content: center; - width: 38px; - min-width: 38px; - height: 38px; - color: #f43f5e; - cursor: pointer; - background-color: rgb(244 63 94 / 10%); - border: none; - border-radius: 4px; - outline: none; - transition: 0.2s; - - &.disabled { - cursor: not-allowed; - opacity: 0.6; - } - } - } - - & .left { - display: flex; - align-items: center; - justify-content: center; - height: 120px; - font-family: var(--font-mono); - font-size: var(--font-2xlg); - font-weight: 700; - cursor: pointer; - - & span { - color: var(--color-foreground-subtle); - } - } -} diff --git a/src/components/toolbox/countdown-timer/timers/timer/timer.tsx b/src/components/toolbox/countdown-timer/timers/timer/timer.tsx deleted file mode 100644 index d3a3900..0000000 --- a/src/components/toolbox/countdown-timer/timers/timer/timer.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import { useRef, useMemo, useState, useEffect } from 'react'; -import { - IoPlay, - IoPause, - IoRefresh, - IoTrashOutline, -} from 'react-icons/io5/index'; - -import { Toolbar } from './toolbar'; - -import { useCountdownTimers } from '@/stores/countdown-timers'; -import { useAlarm } from '@/hooks/use-alarm'; -import { useSnackbar } from '@/contexts/snackbar'; -import { padNumber } from '@/helpers/number'; -import { cn } from '@/helpers/styles'; - -import styles from './timer.module.css'; - -interface TimerProps { - enableAnimations: (enabled: boolean) => void; - id: string; -} - -export function Timer({ enableAnimations, id }: TimerProps) { - const intervalRef = useRef | null>(null); - const lastActiveTimeRef = useRef(null); - const lastStateRef = useRef<{ spent: number; total: number } | null>(null); - - const [isRunning, setIsRunning] = useState(false); - - const { first, last, name, spent, total } = useCountdownTimers(state => - state.getTimer(id), - ); - const tick = useCountdownTimers(state => state.tick); - const rename = useCountdownTimers(state => state.rename); - const reset = useCountdownTimers(state => state.reset); - const deleteTimer = useCountdownTimers(state => state.delete); - - const left = useMemo(() => total - spent, [total, spent]); - - const hours = useMemo(() => Math.floor(left / 3600), [left]); - const minutes = useMemo(() => Math.floor((left % 3600) / 60), [left]); - const seconds = useMemo(() => left % 60, [left]); - - const [isReversed, setIsReversed] = useState(false); - - const spentHours = useMemo(() => Math.floor(spent / 3600), [spent]); - const spentMinutes = useMemo(() => Math.floor((spent % 3600) / 60), [spent]); - const spentSeconds = useMemo(() => spent % 60, [spent]); - - const playAlarm = useAlarm(); - - const showSnackbar = useSnackbar(); - - const handleStart = () => { - if (left > 0) setIsRunning(true); - }; - - const handlePause = () => setIsRunning(false); - - const handleToggle = () => { - if (isRunning) handlePause(); - else handleStart(); - }; - - const handleReset = () => { - if (spent === 0) return; - - if (isRunning) return showSnackbar('Please first stop the timer.'); - - setIsRunning(false); - reset(id); - }; - - const handleDelete = () => { - if (isRunning) return showSnackbar('Please first stop the timer.'); - - enableAnimations(false); - - deleteTimer(id); - - setTimeout(() => enableAnimations(true), 100); - }; - - useEffect(() => { - if (isRunning) { - if (intervalRef.current) clearInterval(intervalRef.current); - - intervalRef.current = setInterval(() => tick(id), 1000); - } - - return () => { - if (intervalRef.current) clearInterval(intervalRef.current); - }; - }, [isRunning, tick, id]); - - useEffect(() => { - if (left === 0 && isRunning) { - setIsRunning(false); - playAlarm(); - - if (intervalRef.current) clearInterval(intervalRef.current); - } - }, [left, isRunning, playAlarm]); - - useEffect(() => { - const handleBlur = () => { - if (isRunning) { - lastActiveTimeRef.current = Date.now(); - lastStateRef.current = { spent, total }; - } - }; - - const handleFocus = () => { - if (isRunning && lastActiveTimeRef.current && lastStateRef.current) { - const elapsed = Math.floor( - (Date.now() - lastActiveTimeRef.current) / 1000, - ); - const previousLeft = - lastStateRef.current.total - lastStateRef.current.spent; - const currentLeft = left; - const correctedLeft = previousLeft - elapsed; - - if (correctedLeft < currentLeft) { - tick(id, currentLeft - correctedLeft); - } - - lastActiveTimeRef.current = null; - lastStateRef.current = null; - } - }; - - window.addEventListener('blur', handleBlur); - window.addEventListener('focus', handleFocus); - - return () => { - window.removeEventListener('blur', handleBlur); - window.removeEventListener('focus', handleFocus); - }; - }, [isRunning, tick, id, spent, total, left]); - - return ( -
-
-
-
-
-
- - - -
setIsReversed(prev => !prev)} - onKeyDown={() => setIsReversed(prev => !prev)} - > - {!isReversed ? ( - <> - {padNumber(hours)} - : - {padNumber(minutes)} - : - {padNumber(seconds)} - - ) : ( - <> - - - {padNumber(spentHours)} - : - {padNumber(spentMinutes)} - : - {padNumber(spentSeconds)} - - )} -
- -
-
- rename(id, e.target.value)} - /> - - - - -
- - -
-
- ); -} diff --git a/src/components/toolbox/countdown-timer/timers/timer/toolbar/index.ts b/src/components/toolbox/countdown-timer/timers/timer/toolbar/index.ts deleted file mode 100644 index dc5abb1..0000000 --- a/src/components/toolbox/countdown-timer/timers/timer/toolbar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Toolbar } from './toolbar'; diff --git a/src/components/toolbox/countdown-timer/timers/timer/toolbar/toolbar.module.css b/src/components/toolbox/countdown-timer/timers/timer/toolbar/toolbar.module.css deleted file mode 100644 index 473234c..0000000 --- a/src/components/toolbox/countdown-timer/timers/timer/toolbar/toolbar.module.css +++ /dev/null @@ -1,37 +0,0 @@ -.toolbar { - position: absolute; - top: 12px; - right: 12px; - display: flex; - column-gap: 4px; - align-items: center; - height: 30px; - padding: 4px; - background-color: var(--color-neutral-50); - border: 1px solid var(--color-neutral-200); - border-radius: 4px; - - & button { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - aspect-ratio: 1 / 1; - font-size: var(--font-xsm); - color: var(--color-foreground-subtle); - cursor: pointer; - background-color: transparent; - border: none; - transition: 0.2s; - - &:disabled { - cursor: not-allowed; - opacity: 0.2; - } - - &:not(:disabled):hover { - color: var(--color-foreground); - background-color: var(--color-neutral-100); - } - } -} diff --git a/src/components/toolbox/countdown-timer/timers/timer/toolbar/toolbar.tsx b/src/components/toolbox/countdown-timer/timers/timer/toolbar/toolbar.tsx deleted file mode 100644 index aec9535..0000000 --- a/src/components/toolbox/countdown-timer/timers/timer/toolbar/toolbar.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { IoIosArrowDown, IoIosArrowUp } from 'react-icons/io/index'; - -import { useCountdownTimers } from '@/stores/countdown-timers'; - -import styles from './toolbar.module.css'; - -interface ToolbarProps { - first: boolean; - id: string; - last: boolean; -} - -export function Toolbar({ first, id, last }: ToolbarProps) { - const moveUp = useCountdownTimers(state => state.moveUp); - const moveDown = useCountdownTimers(state => state.moveDown); - - return ( -
- - -
- ); -} diff --git a/src/components/toolbox/countdown-timer/timers/timers.module.css b/src/components/toolbox/countdown-timer/timers/timers.module.css deleted file mode 100644 index 03a3c05..0000000 --- a/src/components/toolbox/countdown-timer/timers/timers.module.css +++ /dev/null @@ -1,28 +0,0 @@ -.timers { - margin-top: 48px; - - & > header { - display: flex; - column-gap: 12px; - align-items: center; - margin-bottom: 16px; - - & .title { - font-family: var(--font-heading); - font-size: var(--font-md); - font-weight: 600; - line-height: 1; - } - - & .line { - flex-grow: 1; - height: 0; - border-top: 1px dashed var(--color-neutral-200); - } - - & .spent { - font-size: var(--font-sm); - color: var(--color-foreground-subtle); - } - } -} diff --git a/src/components/toolbox/countdown-timer/timers/timers.tsx b/src/components/toolbox/countdown-timer/timers/timers.tsx deleted file mode 100644 index 52abbc9..0000000 --- a/src/components/toolbox/countdown-timer/timers/timers.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { useMemo, forwardRef } from 'react'; - -import { Timer } from './timer'; -import { Notice } from './notice'; - -import { useCountdownTimers } from '@/stores/countdown-timers'; - -import styles from './timers.module.css'; - -interface TimersProps { - enableAnimations: (enabled: boolean) => void; -} - -export const Timers = forwardRef(function Timers( - { enableAnimations }: TimersProps, - ref: React.ForwardedRef, -) { - const timers = useCountdownTimers(state => state.timers); - const spent = useCountdownTimers(state => state.spent()); - const total = useCountdownTimers(state => state.total()); - - const spentMinutes = useMemo(() => Math.floor(spent / 60), [spent]); - const totalMinutes = useMemo(() => Math.floor(total / 60), [total]); - - return ( -
- {timers.length > 0 ? ( -
-
-

Timers

-
- {totalMinutes > 0 && ( -

- {spentMinutes} / {totalMinutes} Minute - {totalMinutes !== 1 && 's'} -

- )} -
- -
- {timers.map(timer => ( - - ))} -
- - -
- ) : null} -
- ); -}); diff --git a/src/components/toolbox/index.ts b/src/components/toolbox/index.ts index f8725ad..5eb0811 100644 --- a/src/components/toolbox/index.ts +++ b/src/components/toolbox/index.ts @@ -1,4 +1,3 @@ export { Notepad } from './notepad'; export { Pomodoro } from './pomodoro'; -export { CountdownTimer } from './countdown-timer'; export { BreathingExercise } from './breathing'; diff --git a/src/hooks/use-alarm.ts b/src/hooks/use-alarm.ts deleted file mode 100644 index b2c8f35..0000000 --- a/src/hooks/use-alarm.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useCallback } from 'react'; - -import { useSound } from './use-sound'; -import { useAlarmStore } from '@/stores/alarm'; - -export function useAlarm() { - const { play: playSound } = useSound( - '/sounds/alarm.mp3', - { volume: 1 }, - true, - ); - const isPlaying = useAlarmStore(state => state.isPlaying); - const play = useAlarmStore(state => state.play); - const stop = useAlarmStore(state => state.stop); - - const playAlarm = useCallback(() => { - if (!isPlaying) { - playSound(stop); - play(); - } - }, [isPlaying, playSound, play, stop]); - - return playAlarm; -} diff --git a/src/stores/alarm/index.ts b/src/stores/alarm/index.ts deleted file mode 100644 index 2c981d1..0000000 --- a/src/stores/alarm/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { create } from 'zustand'; - -interface AlarmStore { - isPlaying: boolean; - play: () => void; - stop: () => void; -} - -export const useAlarmStore = create()(set => ({ - isPlaying: false, - - play() { - set({ isPlaying: true }); - }, - - stop() { - set({ isPlaying: false }); - }, -}));