From 2126cd5d3c39efe49f56392bcb6ce9c9716f7c8e Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Wed, 3 Dec 2025 16:09:58 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(clock):=20redesign=20timer=20p?= =?UTF-8?q?age=20with=20better=20UX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Quick timer presets now work without authentication (local timers) - Added "Recently Used" section with localStorage persistence - Improved visual design with gradient backgrounds and icons - Timer cards show progress as background fill - Better spacing and visual hierarchy - Quick preset buttons in create modal - Status badges for running/paused/finished timers - Notification support when timer finishes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../apps/web/src/routes/timers/+page.svelte | 602 +++++++++++++----- 1 file changed, 456 insertions(+), 146 deletions(-) diff --git a/apps/clock/apps/web/src/routes/timers/+page.svelte b/apps/clock/apps/web/src/routes/timers/+page.svelte index 63b015a7a..28b109df1 100644 --- a/apps/clock/apps/web/src/routes/timers/+page.svelte +++ b/apps/clock/apps/web/src/routes/timers/+page.svelte @@ -1,6 +1,7 @@ -
+
-
-

{$_('timer.title')}

- +
+

{$_('timer.title')}

+

Schnelle Timer für jeden Anlass

- -
-

{$_('timer.presets')}

-
+ +
+

+ {$_('timer.presets')} +

+
{#each QUICK_TIMER_PRESETS as preset} - {/each}
- - {#if timersStore.loading} -
-
-
- {:else if timersStore.timers.length === 0} -
-

{$_('timer.noTimers')}

-
- {:else} -
- {#each timersStore.timers as timer (timer.id)} -
- {#if timer.label} -

{timer.label}

- {/if} - -
- {getTimerDisplay(timer)} -
- - -
-
-
- - -
- {#if timer.status === 'running'} - - {:else} - - {/if} - - -
-
- {/each} + + {#if recentPresets.length > 0} +
+
+

Zuletzt verwendet

+ +
+
+ {#each recentPresets as preset} + + {/each} +
{/if} - - {#if showForm} -
-
-

{$_('timer.add')}

+ +
+ +
-
{ - e.preventDefault(); - createTimer(); - }} - > - -
- -
-
- - -
-
- + {#if timersStore.loading} +
+
+
+ {:else if allTimers.length === 0} +
+
⏱️
+

{$_('timer.noTimers')}

+

+ Klicke auf einen Preset oben oder erstelle einen eigenen Timer +

+
+ {:else} +
+

+ Aktive Timer ({allTimers.length}) +

+
+ {#each allTimers as timer (timer.id)} + {@const isLocal = isLocalTimer(timer)} +
+ +
+ +
+ +
+ + {timer.label || 'Timer'} + + - + {timer.status === 'running' ? 'Läuft' : timer.status === 'paused' ? 'Pausiert' : timer.status === 'finished' ? 'Fertig' : 'Bereit'} +
-
- +
+ - + {getTimerDisplay(timer)} + +
+ + +
+
+
+ + +
+ {#if timer.status === 'running'} + + {:else if timer.status === 'finished'} + + {:else} + + {/if} + +
- - -
- - -
- - -
- - -
- + {/each}
{/if}
+ + +{#if showForm} +
+
+
+

{$_('timer.add')}

+ +
+ +
{ + e.preventDefault(); + createTimer(); + }} + > + +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+ +
+ {#each [1, 3, 5, 10, 15, 30] as mins} + + {/each} +
+
+ + +
+ + +
+ + +
+ + +
+
+
+
+{/if} + +