Time Select
Some checks failed
Build BAB Application Deployment Artifact / build (push) Failing after 38s
Some checks failed
Build BAB Application Deployment Artifact / build (push) Failing after 38s
This commit is contained in:
241
src/components/scheduling/boat/CalendarHeaderComponent.vue
Normal file
241
src/components/scheduling/boat/CalendarHeaderComponent.vue
Normal file
@@ -0,0 +1,241 @@
|
||||
<template>
|
||||
<div class="title-bar" style="display: flex">
|
||||
<button
|
||||
tabindex="0"
|
||||
class="date-button direction-button direction-button__left"
|
||||
@click="onPrev"
|
||||
>
|
||||
<span class="q-calendar__focus-helper" tabindex="-1" />
|
||||
</button>
|
||||
<div class="dates-holder">
|
||||
<div :key="parsedStart?.date" class="internal-dates-holder">
|
||||
<div v-for="day in days" :key="day.date" :style="dayStyle">
|
||||
<button
|
||||
tabindex="0"
|
||||
style="width: 100%"
|
||||
:class="dayClass(day)"
|
||||
@click="selectedDate = day.date"
|
||||
>
|
||||
<span class="q-calendar__focus-helper" tabindex="-1" />
|
||||
<div style="width: 100%">
|
||||
{{ monthFormatter(day, true) }}
|
||||
</div>
|
||||
<div style="width: 100%; font-size: 16px; font-weight: 700">
|
||||
{{ dayFormatter(day, false) }}
|
||||
</div>
|
||||
<div style="width: 100%; font-size: 10px">
|
||||
{{ weekdayFormatter(day, true) }}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
tabindex="0"
|
||||
class="date-button direction-button direction-button__right"
|
||||
@click="onNext"
|
||||
>
|
||||
<span class="q-calendar__focus-helper" tabindex="-1" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Timestamp,
|
||||
addToDate,
|
||||
createDayList,
|
||||
createNativeLocaleFormatter,
|
||||
getEndOfWeek,
|
||||
getStartOfWeek,
|
||||
getWeekdaySkips,
|
||||
parseTimestamp,
|
||||
today,
|
||||
} from '@quasar/quasar-ui-qcalendar';
|
||||
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
|
||||
const selectedDate = defineModel<string>();
|
||||
|
||||
const weekdays = reactive([0, 1, 2, 3, 4, 5, 6]),
|
||||
locale = ref('en-CA'),
|
||||
monthFormatter = monthFormatterFunc(),
|
||||
dayFormatter = dayFormatterFunc(),
|
||||
weekdayFormatter = weekdayFormatterFunc();
|
||||
|
||||
const weekdaySkips = computed(() => {
|
||||
return getWeekdaySkips(weekdays);
|
||||
});
|
||||
|
||||
const parsedStart = computed(() =>
|
||||
getStartOfWeek(
|
||||
parseTimestamp(selectedDate.value || today()) as Timestamp,
|
||||
weekdays,
|
||||
today2.value as Timestamp
|
||||
)
|
||||
);
|
||||
|
||||
const parsedEnd = computed(() =>
|
||||
getEndOfWeek(
|
||||
parseTimestamp(selectedDate.value || today()) as Timestamp,
|
||||
weekdays,
|
||||
today2.value as Timestamp
|
||||
)
|
||||
);
|
||||
|
||||
const today2 = computed(() => {
|
||||
return parseTimestamp(today());
|
||||
});
|
||||
|
||||
const days = computed(() => {
|
||||
if (parsedStart.value && parsedEnd.value) {
|
||||
return createDayList(
|
||||
parsedStart.value,
|
||||
parsedEnd.value,
|
||||
today2.value as Timestamp,
|
||||
weekdaySkips.value
|
||||
);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
const dayStyle = computed(() => {
|
||||
const width = 100 / weekdays.length + '%';
|
||||
return {
|
||||
width,
|
||||
};
|
||||
});
|
||||
|
||||
function onPrev() {
|
||||
const ts = addToDate(parsedStart.value, { day: -7 });
|
||||
selectedDate.value = ts.date;
|
||||
}
|
||||
|
||||
function onNext() {
|
||||
const ts = addToDate(parsedStart.value, { day: 7 });
|
||||
selectedDate.value = ts.date;
|
||||
}
|
||||
|
||||
function dayClass(day: Timestamp) {
|
||||
return {
|
||||
'date-button': true,
|
||||
'selected-date-button': selectedDate.value === day.date,
|
||||
};
|
||||
}
|
||||
|
||||
function monthFormatterFunc() {
|
||||
const longOptions = { timeZone: 'UTC', month: 'long' };
|
||||
const shortOptions = { timeZone: 'UTC', month: 'short' };
|
||||
|
||||
return createNativeLocaleFormatter(locale.value, (_tms, short) =>
|
||||
short ? shortOptions : longOptions
|
||||
);
|
||||
}
|
||||
|
||||
function weekdayFormatterFunc() {
|
||||
const longOptions = { timeZone: 'UTC', weekday: 'long' };
|
||||
const shortOptions = { timeZone: 'UTC', weekday: 'short' };
|
||||
|
||||
return createNativeLocaleFormatter(locale.value, (_tms, short) =>
|
||||
short ? shortOptions : longOptions
|
||||
);
|
||||
}
|
||||
|
||||
function dayFormatterFunc() {
|
||||
const longOptions = { timeZone: 'UTC', day: '2-digit' };
|
||||
const shortOptions = { timeZone: 'UTC', day: 'numeric' };
|
||||
|
||||
return createNativeLocaleFormatter(locale.value, (_tms, short) =>
|
||||
short ? shortOptions : longOptions
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<style lang="sass">
|
||||
.title-bar
|
||||
position: relative
|
||||
width: 100%
|
||||
height: 70px
|
||||
background: $primary
|
||||
display: flex
|
||||
flex-direction: row
|
||||
flex: 1 0 100%
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
overflow: hidden
|
||||
border-radius: 3px
|
||||
user-select: none
|
||||
|
||||
.dates-holder
|
||||
position: relative
|
||||
width: 100%
|
||||
align-items: center
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
color: #fff
|
||||
overflow: hidden
|
||||
user-select: none
|
||||
|
||||
.internal-dates-holder
|
||||
position: relative
|
||||
width: 100%
|
||||
display: inline-flex
|
||||
flex: 1 1 100%
|
||||
flex-direction: row
|
||||
justify-content: space-between
|
||||
overflow: hidden
|
||||
user-select: none
|
||||
|
||||
.direction-button
|
||||
background: $primary
|
||||
color: white
|
||||
width: 40px
|
||||
max-width: 50px !important
|
||||
|
||||
.direction-button__left
|
||||
&:before
|
||||
content: '<'
|
||||
display: inline-flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
height: 100%
|
||||
font-weight: 900
|
||||
font-size: 3em
|
||||
|
||||
.direction-button__right
|
||||
&:before
|
||||
content: '>'
|
||||
display: inline-flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
height: 100%
|
||||
font-weight: 900
|
||||
font-size: 3em
|
||||
|
||||
.date-button
|
||||
color: white
|
||||
background: $primary
|
||||
z-index: 2
|
||||
height: 100%
|
||||
outline: 0
|
||||
cursor: pointer
|
||||
border-radius: 3px
|
||||
display: inline-flex
|
||||
flex: 1 0 auto
|
||||
flex-direction: column
|
||||
align-items: stretch
|
||||
position: relative
|
||||
border: 0
|
||||
vertical-align: middle
|
||||
padding: 0
|
||||
font-size: 14px
|
||||
line-height: 1.715em
|
||||
text-decoration: none
|
||||
font-weight: 500
|
||||
text-transform: uppercase
|
||||
text-align: center
|
||||
user-select: none
|
||||
|
||||
.selected-date-button
|
||||
color: #3f51b5 !important
|
||||
background: white !important
|
||||
</style>
|
||||
Reference in New Issue
Block a user