Files
astra-frontend/src/components/base/BaseCalendar.vue
2023-06-08 17:03:09 +03:00

222 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template lang="pug">
.calendar-wrapper.bg-white
.header.px-6.pt-5.pb-18px.flex.items-center.justify-between
.text-smm.font-semibold {{ internalMonth }}
.arrows.flex.items-center.justify-center.gap-x-6
q-btn(
flat,
size="10px",
dense,
icon="arrow_back_ios_new",
text-color="black",
round,
@click="previousMonth"
)
q-btn(
flat,
icon="arrow_forward_ios",
size="10px",
text-color="black",
dense,
round,
@click="nextMonth"
)
.week.py-4.px-5.grid.grid-rows-1.grid-cols-7
.flex.items-center.justify-center.week-item.text-xsx.py-1(v-for="day of week", :key="day") {{ day }}
.body.pb-7.px-5
.flex.items-center.justify-center.cursor-pointer.w-full.h-full(
v-for="date of internalDatesList",
@click="selectDate(date)",
:key="date",
:style="calculateRangeStyle(date)",
)
.flex.items-center.justify-center.rounded-full.w-full.h-full(
:class="calculateCellClasses(date)",
) {{ date.format("D") }}
</template>
<script>
import * as moment from "moment/moment";
import { mapState } from "vuex";
export default {
name: "BaseCalendar",
props: {
modelValue: Object,
range: Boolean,
rangeCount: Number,
},
data() {
return {
week: ["ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ", "ВС"],
internalDate: moment(),
selectedDate: null,
datesRange: [],
};
},
computed: {
value: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
},
},
...mapState({
today: (state) => state.calendar.currentDate,
}),
internalMonth() {
let formattedMonth = this.internalDate.format("MMMM");
return `${
formattedMonth[0].toUpperCase() + formattedMonth.slice(1)
} ${this.internalDate.format("YYYY")}`;
},
internalStartDate() {
return this.internalDate
.clone()
.startOf("month")
.startOf("week")
.subtract(1, "day");
},
internalDatesList() {
return [...Array(42)].map(() =>
this.internalStartDate.add(1, "day").clone()
);
},
},
methods: {
previousMonth() {
this.internalDate = this.internalDate.clone().subtract(1, "month");
},
nextMonth() {
this.internalDate = this.internalDate.clone().add(1, "month");
},
calculateCellClasses(date) {
if (this.defineDateRange(date))
return {
"date-active": true,
};
if (
this.calculateRangeStyle(date) &&
Object.keys(this.calculateRangeStyle(date) === 1)
)
return {
"text-white": true,
"date-range": true,
};
if (date.isSame(this.today, "day"))
return {
"date-today": true,
};
if (date.isSame(this.internalDate, "month"))
return {
"date-month": true,
};
return {
"date-other": true,
};
},
calculateRangeStyle(date) {
if (
this.range &&
this.value?.from &&
this.value?.to &&
!this.value?.from.isSame(this.value?.to?.format("YYYY-MM-DD"))
) {
if (date.isSame(this.value?.from?.format("YYYY-MM-DD")))
return {
"border-top-left-radius": "9999px",
"border-bottom-left-radius": "9999px",
"background-color": "var(--btn-blue-color-5)",
};
if (date.isSame(this.value?.to?.format("YYYY-MM-DD")))
return {
"border-top-right-radius": "9999px",
"border-bottom-right-radius": "9999px",
"background-color": "var(--btn-blue-color-5)",
};
if (date.isAfter(this.value?.from) && date.isBefore(this.value?.to))
return {
"background-color": "var(--btn-blue-color-5)",
};
}
},
selectDate(date) {
if (!this.range) {
this.value = date;
return;
}
if (this.rangeCount) {
this.value.from = date;
this.value.to = this.value.from.clone().add(this.rangeCount - 1, "day");
return;
}
if (this.value?.to) {
this.value.from = date;
this.value.to = null;
return;
}
if (date.isAfter(this.value?.from)) {
this.value.to = date;
return;
}
this.value.to = this.value.from;
this.value.from = date;
return;
},
defineDateRange(date) {
if (!this.range) {
return date.isSame(this.value?.format("YYYY-MM-DD"));
}
return (
date.isSame(this.value?.from?.format("YYYY-MM-DD")) ||
date.isSame(this.value?.to?.format("YYYY-MM-DD"))
);
},
},
mounted() {
if (this.value) {
if (this.range) {
this.internalDate = this.value?.from?.clone();
} else this.internalDate = this.value?.clone();
}
},
};
</script>
<style scoped lang="sass">
.calendar-wrapper
width: 286px
.header
border-bottom: 1px solid var(--border-light-grey-color)
.week-item
color: var(--font-grey-color)
&:nth-last-child(-n+2)
color: var(--border-red-color)
.date-active
color: var(--default-white),
background-color: var(--btn-blue-color)
&:hover
opacity: 0.5
.date-other
color: var(--font-grey-color)
&:hover
background-color: var(--border-light-grey-color)
.date-month
color: var(--font-black-color)
&:hover
background-color: var(--border-light-grey-color)
.date-today:hover, .date-range:hover
background-color: var(--btn-blue-color-2)
.date-today
border: 1px dashed var(--btn-blue-color)
color: var(--btn-blue-color)
.body
display: grid
grid-template-columns: repeat(7, 35px)
grid-template-rows: repeat(6, 35px)
row-gap: 4px
justify-content: center
align-items: center
</style>