Add Reset button and move End Day to right side of actions bar

Reset clears the current block's elapsed time to zero and immediately
starts the timer. A shared compute_block_elapsed() utility (utils/timer.py)
handles the elapsed calculation in both the sessions and dashboard routers,
and correctly treats "reset" events as zero-elapsed restart markers so
page reloads after a reset show accurate times.

Layout: Start/Pause/Resume/Reset are grouped on the left; End Day sits
on the right via justify-content: space-between.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 00:17:02 -08:00
parent cc599603cf
commit 1420d57e7e
6 changed files with 104 additions and 86 deletions

View File

@@ -101,6 +101,13 @@ export const useScheduleStore = defineStore('schedule', () => {
blockStartedAt.value = Date.now()
isPaused.value = false
}
// Reset — clear elapsed to 0 and start counting immediately
if (event.event === 'reset') {
if (event.block_id) blockElapsedCache.value[event.block_id] = 0
blockElapsedOffset.value = 0
blockStartedAt.value = Date.now()
isPaused.value = false
}
// Select — switch current block but keep timer stopped (manual start required)
if (event.event === 'select') {
// Sync the previous block's cache
@@ -204,6 +211,17 @@ export const useScheduleStore = defineStore('schedule', () => {
sendTimerAction(sessionId, 'start', session.value.current_block_id)
}
// Reset the current block's timer to 0 and start counting immediately.
function resetCurrentBlock(sessionId) {
if (!session.value?.current_block_id) return
const blockId = session.value.current_block_id
blockElapsedCache.value[blockId] = 0
blockElapsedOffset.value = 0
isPaused.value = false
blockStartedAt.value = Date.now()
sendTimerAction(sessionId, 'reset', blockId)
}
return {
session,
blocks,
@@ -226,5 +244,6 @@ export const useScheduleStore = defineStore('schedule', () => {
switchBlock,
selectBlock,
startCurrentBlock,
resetCurrentBlock,
}
})

View File

@@ -42,21 +42,28 @@
/>
</div>
<div class="session-actions">
<button
class="btn-sm"
v-if="scheduleStore.session.current_block_id && !scheduleStore.isPaused"
@click="sendAction('pause')"
>Pause</button>
<button
class="btn-sm btn-start"
v-if="scheduleStore.isPaused && scheduleStore.blockElapsedOffset === 0 && scheduleStore.session.current_block_id"
@click="scheduleStore.startCurrentBlock(scheduleStore.session.id)"
>Start</button>
<button
class="btn-sm"
v-if="scheduleStore.isPaused && scheduleStore.blockElapsedOffset > 0"
@click="sendAction('resume')"
>Resume</button>
<div class="session-actions-left">
<button
class="btn-sm"
v-if="scheduleStore.session.current_block_id && !scheduleStore.isPaused"
@click="sendAction('pause')"
>Pause</button>
<button
class="btn-sm btn-start"
v-if="scheduleStore.isPaused && scheduleStore.blockElapsedOffset === 0 && scheduleStore.session.current_block_id"
@click="scheduleStore.startCurrentBlock(scheduleStore.session.id)"
>Start</button>
<button
class="btn-sm"
v-if="scheduleStore.isPaused && scheduleStore.blockElapsedOffset > 0"
@click="sendAction('resume')"
>Resume</button>
<button
class="btn-sm"
v-if="scheduleStore.session.current_block_id"
@click="scheduleStore.resetCurrentBlock(scheduleStore.session.id)"
>Reset</button>
</div>
<button class="btn-sm btn-danger" @click="sendAction('complete')">End Day</button>
</div>
</div>
@@ -306,7 +313,8 @@ h1 { font-size: 1.75rem; font-weight: 700; }
}
.current-block-timer { display: flex; justify-content: center; margin: 1rem 0; }
.session-actions { display: flex; gap: 0.5rem; margin-top: 1rem; flex-wrap: wrap; }
.session-actions { display: flex; align-items: center; justify-content: space-between; margin-top: 1rem; gap: 0.5rem; }
.session-actions-left { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.btn-sm {
padding: 0.4rem 0.9rem;