167 lines
4.3 KiB
Vue
167 lines
4.3 KiB
Vue
<template>
|
|
<div class="timer">
|
|
<div class="timer__phases">
|
|
<p class="tag is-focus" :class="{'is-active' : timer.settings.timer[timer.getCurrentSession].text === 'Focus'}">Focus</p>
|
|
<p class="tag is-short" :class="{'is-active' : timer.settings.timer[timer.getCurrentSession].text === 'Short Break'}">Short Break</p>
|
|
<p class="tag is-long" :class="{'is-active' : timer.settings.timer[timer.getCurrentSession].text === 'Long Break'}">Long Break</p>
|
|
</div>
|
|
<div class="timer__clock" :data-round="(timer.getCurrentSessionNumber) " :model-value="(timer.getTimeRemaining * 100) / (timer.getSessionTime * 60)" :style="'color:' + timer.getCurrentColor">
|
|
{{ String(getMinutes()).padStart(2, '0') }}:{{ String(getSeconds()).padStart(2, '0') }}
|
|
</div>
|
|
<div class="timer__controls">
|
|
<button
|
|
:variant="timer.isStarted ? 'outlined' : 'elevated'"
|
|
class="btn btn--light btn--small"
|
|
:class="{'is-active': true}"
|
|
@click="toggleTimer"
|
|
>
|
|
{{ timer.isStarted ? 'Pause' : 'Start' }}
|
|
</button>
|
|
<button
|
|
class="btn btn--light btn--icon"
|
|
:disabled="!(timer.isStarted || timer.getTimeRemaining !== timer.getSessionTime * 60)"
|
|
@click="clearTimer"
|
|
>
|
|
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21 12a9 9 0 0 1-9 9 9 9 0 0 1-.899-17.956c.495-.049.899.359.899.856s-.405.894-.898.956a7.2 7.2 0 1 0 4.948 1.19V7.5a.9.9 0 1 1-1.8 0V4a1 1 0 0 1 1-1h3.5a.9.9 0 1 1 0 1.8H17.4A8.99 8.99 0 0 1 21 12Z" fill="currentColor" /></svg>
|
|
</button>
|
|
<button
|
|
class="btn btn--light btn--icon"
|
|
@click="timer.nextSession()"
|
|
>
|
|
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 4.503a1.5 1.5 0 0 1 2.367-1.224l10.5 7.444a1.5 1.5 0 0 1 .01 2.442l-10.5 7.556A1.5 1.5 0 0 1 3 19.505V4.502Zm18-.753a.75.75 0 0 0-.22-.53C20.64 3.079 20.2 3 20 3c-.199 0-.594.079-.735.22-.14.14-.265.331-.265.53v16.5c0 .199.143.39.284.53.14.141.517.22.716.22.199 0 .64-.079.78-.22a.75.75 0 0 0 .22-.53V3.75Z" fill="currentColor" /></svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import { onBeforeUnmount } from 'vue'
|
|
import { useTimerStore } from '~/stores/timer'
|
|
import { useTimerControls } from '~/composables/useTimerControls'
|
|
|
|
export default {
|
|
name: 'PomodoroTimer',
|
|
setup () {
|
|
const timer = useTimerStore()
|
|
const { toggleTimer, clearTimer } = useTimerControls()
|
|
|
|
const getMinutes = () => Math.floor(timer.getTimeRemaining / 60)
|
|
const getSeconds = () => timer.getTimeRemaining - 60 * getMinutes()
|
|
|
|
onBeforeUnmount(() => {
|
|
clearTimer()
|
|
})
|
|
|
|
return {
|
|
timer,
|
|
getMinutes,
|
|
getSeconds,
|
|
toggleTimer,
|
|
clearTimer
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style scoped>
|
|
.timer {
|
|
padding-top: 1em;
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
|
|
.timer__phases {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 0.75em;
|
|
}
|
|
|
|
.timer__clock {
|
|
font-size: 3em;
|
|
font-weight: 700;
|
|
text-align: center;
|
|
padding: 16px 0;
|
|
position: relative;
|
|
align-self: center;
|
|
color: attr(color);
|
|
|
|
&::before {
|
|
content: '#'attr(data-round);
|
|
position: absolute;
|
|
left: -3em;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
color: #b1b1b1;
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.timer__controls {
|
|
display: flex;
|
|
gap: 0.5em;
|
|
justify-content: center;
|
|
}
|
|
|
|
.timer__progress {
|
|
width: 100%;
|
|
background-color: white;
|
|
|
|
.progress {
|
|
background-color: #72A5ED;
|
|
}
|
|
}
|
|
}
|
|
|
|
.is-focus {
|
|
color: #72A5ED;
|
|
}
|
|
.is-short {
|
|
color: #FBA9A9;
|
|
}
|
|
.is-long {
|
|
color: #D77574;
|
|
}
|
|
|
|
.tag {
|
|
border-radius: 3px;
|
|
padding: 0.25em 0.5em;
|
|
font-weight: 700;
|
|
font-size: 12px;
|
|
flex: 1;
|
|
|
|
&.is-active {
|
|
background-color: white;
|
|
}
|
|
}
|
|
|
|
.btn--light {
|
|
background-color: white;
|
|
color: #585C5E;
|
|
}
|
|
|
|
.btn--light:hover {
|
|
background-color: #e9c046;
|
|
color: white;
|
|
}
|
|
|
|
.btn--light:disabled {
|
|
background-color: white;
|
|
color: #585C5E;
|
|
opacity: 0.4;
|
|
border: none;
|
|
}
|
|
|
|
.btn--small {
|
|
min-width: 100px;
|
|
}
|
|
|
|
.btn--light[variant="outlined"] {
|
|
color: #e9c046;
|
|
border-color: white;
|
|
}
|
|
.btn--light[variant="outlined"]:hover {
|
|
background-color: white;
|
|
border-color: white;
|
|
color: #585C5E;
|
|
}
|
|
</style>
|