Initial commit
This commit is contained in:
166
components/timer/PomodoroTimer.vue
Normal file
166
components/timer/PomodoroTimer.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<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>
|
Reference in New Issue
Block a user