first commit
This commit is contained in:
175
resources/js/pages/apps/calendar.vue
Normal file
175
resources/js/pages/apps/calendar.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<script setup>
|
||||
import FullCalendar from '@fullcalendar/vue3'
|
||||
import {
|
||||
blankEvent,
|
||||
useCalendar,
|
||||
} from '@/views/apps/calendar/useCalendar'
|
||||
import { useCalendarStore } from '@/views/apps/calendar/useCalendarStore'
|
||||
|
||||
// Components
|
||||
import CalendarEventHandler from '@/views/apps/calendar/CalendarEventHandler.vue'
|
||||
|
||||
// 👉 Store
|
||||
const store = useCalendarStore()
|
||||
|
||||
// 👉 Event
|
||||
const event = ref(structuredClone(blankEvent))
|
||||
const isEventHandlerSidebarActive = ref(false)
|
||||
|
||||
watch(isEventHandlerSidebarActive, val => {
|
||||
if (!val)
|
||||
event.value = structuredClone(blankEvent)
|
||||
})
|
||||
|
||||
const { isLeftSidebarOpen } = useResponsiveLeftSidebar()
|
||||
|
||||
// 👉 useCalendar
|
||||
const { refCalendar, calendarOptions, addEvent, updateEvent, removeEvent, jumpToDate } = useCalendar(event, isEventHandlerSidebarActive, isLeftSidebarOpen)
|
||||
|
||||
// SECTION Sidebar
|
||||
|
||||
// 👉 Check all
|
||||
const checkAll = computed({
|
||||
|
||||
/*GET: Return boolean `true` => if length of options matches length of selected filters => Length matches when all events are selected
|
||||
SET: If value is `true` => then add all available options in selected filters => Select All
|
||||
Else if => all filters are selected (by checking length of both array) => Empty Selected array => Deselect All
|
||||
*/
|
||||
get: () => store.selectedCalendars.length === store.availableCalendars.length,
|
||||
set: val => {
|
||||
if (val)
|
||||
store.selectedCalendars = store.availableCalendars.map(i => i.label)
|
||||
else if (store.selectedCalendars.length === store.availableCalendars.length)
|
||||
store.selectedCalendars = []
|
||||
},
|
||||
})
|
||||
|
||||
// !SECTION
|
||||
const calendarApi = ref(null)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<VCard>
|
||||
<!-- `z-index: 0` Allows overlapping vertical nav on calendar -->
|
||||
<VLayout style="z-index: 0;">
|
||||
<!-- 👉 Navigation drawer -->
|
||||
<VNavigationDrawer
|
||||
v-model="isLeftSidebarOpen"
|
||||
width="292"
|
||||
absolute
|
||||
touchless
|
||||
location="start"
|
||||
class="calendar-add-event-drawer"
|
||||
:temporary="$vuetify.display.mdAndDown"
|
||||
>
|
||||
<div class="pa-5">
|
||||
<VBtn
|
||||
block
|
||||
prepend-icon="ri-add-line"
|
||||
@click="isEventHandlerSidebarActive = true"
|
||||
>
|
||||
Add event
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<div class="d-flex align-center justify-center pa-2">
|
||||
<AppDateTimePicker
|
||||
v-model="calendarApi"
|
||||
:config="{ inline: true }"
|
||||
class="calendar-date-picker"
|
||||
@update:model-value="jumpToDate($event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VDivider />
|
||||
<div class="pa-5">
|
||||
<h5 class="text-h5 mb-4">
|
||||
Event Filters
|
||||
</h5>
|
||||
|
||||
<div class="d-flex flex-column calendars-checkbox">
|
||||
<VCheckbox
|
||||
v-model="checkAll"
|
||||
label="View all"
|
||||
/>
|
||||
<VCheckbox
|
||||
v-for="calendar in store.availableCalendars"
|
||||
:key="calendar.label"
|
||||
v-model="store.selectedCalendars"
|
||||
:value="calendar.label"
|
||||
:color="calendar.color"
|
||||
:label="calendar.label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</VNavigationDrawer>
|
||||
|
||||
<VMain>
|
||||
<VCard flat>
|
||||
<FullCalendar
|
||||
ref="refCalendar"
|
||||
:options="calendarOptions"
|
||||
/>
|
||||
</VCard>
|
||||
</VMain>
|
||||
</VLayout>
|
||||
</VCard>
|
||||
<CalendarEventHandler
|
||||
v-model:isDrawerOpen="isEventHandlerSidebarActive"
|
||||
:event="event"
|
||||
@add-event="addEvent"
|
||||
@update-event="updateEvent"
|
||||
@remove-event="removeEvent"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@core-scss/template/libs/full-calendar";
|
||||
|
||||
.calendars-checkbox {
|
||||
.v-label {
|
||||
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
|
||||
opacity: var(--v-high-emphasis-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-add-event-drawer {
|
||||
&.v-navigation-drawer:not(.v-navigation-drawer--temporary) {
|
||||
border-end-start-radius: 0.375rem;
|
||||
border-start-start-radius: 0.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-date-picker {
|
||||
display: none;
|
||||
|
||||
+.flatpickr-input {
|
||||
+.flatpickr-calendar.inline {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
|
||||
.flatpickr-months {
|
||||
border-block-end: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& ~ .flatpickr-calendar .flatpickr-weekdays {
|
||||
margin-block: 0 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-layout {
|
||||
overflow: visible !important;
|
||||
|
||||
.v-card {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user