purityselect_admin/resources/js/views/apps/calendar/CalendarEventHandler.vue
2024-10-25 19:58:19 +05:00

328 lines
8.4 KiB
Vue

<script setup>
import { PerfectScrollbar } from 'vue3-perfect-scrollbar'
import { VForm } from 'vuetify/components/VForm'
import { useCalendarStore } from './useCalendarStore'
import avatar1 from '@images/avatars/avatar-1.png'
import avatar2 from '@images/avatars/avatar-2.png'
import avatar3 from '@images/avatars/avatar-3.png'
import avatar5 from '@images/avatars/avatar-5.png'
import avatar6 from '@images/avatars/avatar-6.png'
import avatar7 from '@images/avatars/avatar-7.png'
// 👉 store
const props = defineProps({
isDrawerOpen: {
type: Boolean,
required: true,
},
event: {
type: null,
required: true,
},
})
const emit = defineEmits([
'update:isDrawerOpen',
'addEvent',
'updateEvent',
'removeEvent',
])
const store = useCalendarStore()
const refForm = ref()
// 👉 Event
const event = ref(JSON.parse(JSON.stringify(props.event)))
const resetEvent = () => {
event.value = JSON.parse(JSON.stringify(props.event))
nextTick(() => {
refForm.value?.resetValidation()
})
}
watch(() => props.isDrawerOpen, resetEvent)
const removeEvent = () => {
emit('removeEvent', String(event.value.id))
// Close drawer
emit('update:isDrawerOpen', false)
}
const handleSubmit = () => {
refForm.value?.validate().then(({ valid }) => {
if (valid) {
// If id exist on id => Update event
if ('id' in event.value)
emit('updateEvent', event.value)
// Else => add new event
else
emit('addEvent', event.value)
// Close drawer
emit('update:isDrawerOpen', false)
}
})
}
const guestsOptions = [
{
avatar: avatar1,
name: 'Jane Foster',
},
{
avatar: avatar3,
name: 'Donna Frank',
},
{
avatar: avatar5,
name: 'Gabrielle Robertson',
},
{
avatar: avatar7,
name: 'Lori Spears',
},
{
avatar: avatar6,
name: 'Sandy Vega',
},
{
avatar: avatar2,
name: 'Cheryl May',
},
]
// 👉 Form
const onCancel = () => {
// Close drawer
emit('update:isDrawerOpen', false)
nextTick(() => {
refForm.value?.reset()
resetEvent()
refForm.value?.resetValidation()
})
}
const startDateTimePickerConfig = computed(() => {
const config = {
enableTime: !event.value.allDay,
dateFormat: `Y-m-d${ event.value.allDay ? '' : ' H:i' }`,
}
if (event.value.end)
config.maxDate = event.value.end
return config
})
const endDateTimePickerConfig = computed(() => {
const config = {
enableTime: !event.value.allDay,
dateFormat: `Y-m-d${ event.value.allDay ? '' : ' H:i' }`,
}
if (event.value.start)
config.minDate = event.value.start
return config
})
const dialogModelValueUpdate = val => {
emit('update:isDrawerOpen', val)
}
</script>
<template>
<VNavigationDrawer
temporary
location="end"
:model-value="props.isDrawerOpen"
width="420"
class="scrollable-content"
@update:model-value="dialogModelValueUpdate"
>
<!-- 👉 Header -->
<AppDrawerHeaderSection
:title="event.id ? 'Update Event' : 'Add Event'"
@cancel="$emit('update:isDrawerOpen', false)"
>
<template #beforeClose>
<IconBtn
v-show="event.id"
@click="removeEvent"
>
<VIcon
size="18"
icon="ri-delete-bin-7-line"
/>
</IconBtn>
</template>
</AppDrawerHeaderSection>
<VDivider />
<PerfectScrollbar :options="{ wheelPropagation: false }">
<VCard flat>
<VCardText>
<!-- SECTION Form -->
<VForm
ref="refForm"
@submit.prevent="handleSubmit"
>
<VRow>
<!-- 👉 Title -->
<VCol cols="12">
<VTextField
v-model="event.title"
label="Title"
placeholder="Meeting with Jane"
:rules="[requiredValidator]"
/>
</VCol>
<!-- 👉 Calendar -->
<VCol cols="12">
<VSelect
v-model="event.extendedProps.calendar"
label="Label"
placeholder="Select Event Label"
:rules="[requiredValidator]"
:items="store.availableCalendars"
:item-title="item => item.label"
:item-value="item => item.label"
>
<template #selection="{ item }">
<div
v-show="event.extendedProps.calendar"
class="align-center"
:class="event.extendedProps.calendar ? 'd-flex' : ''"
>
<VIcon
size="8"
icon="ri-circle-fill"
:color="item.raw.color"
class="me-2"
/>
<span>{{ item.raw.label }}</span>
</div>
</template>
<template #item="{ item, props: itemProps }">
<VListItem v-bind="itemProps">
<template #prepend>
<VIcon
size="8"
icon="ri-circle-fill"
:color="item.raw.color"
/>
</template>
</VListItem>
</template>
</VSelect>
</VCol>
<!-- 👉 Start date -->
<VCol cols="12">
<AppDateTimePicker
:key="JSON.stringify(startDateTimePickerConfig)"
v-model="event.start"
:rules="[requiredValidator]"
label="Start date"
placeholder="Select Date"
:config="startDateTimePickerConfig"
/>
</VCol>
<!-- 👉 End date -->
<VCol cols="12">
<AppDateTimePicker
:key="JSON.stringify(endDateTimePickerConfig)"
v-model="event.end"
:rules="[requiredValidator]"
label="End date"
placeholder="Select End Date"
:config="endDateTimePickerConfig"
/>
</VCol>
<!-- 👉 All day -->
<VCol cols="12">
<VSwitch
v-model="event.allDay"
label="All day"
/>
</VCol>
<!-- 👉 Event URL -->
<VCol cols="12">
<VTextField
v-model="event.url"
label="Event URL"
placeholder="https://event.com/meeting"
:rules="[urlValidator]"
type="url"
/>
</VCol>
<!-- 👉 Guests -->
<VCol cols="12">
<VSelect
v-model="event.extendedProps.guests"
label="Guests"
placeholder="Select guests"
:items="guestsOptions"
:item-title="item => item.name"
:item-value="item => item.name"
chips
multiple
eager
/>
</VCol>
<!-- 👉 Location -->
<VCol cols="12">
<VTextField
v-model="event.extendedProps.location"
label="Location"
placeholder="Meeting room"
/>
</VCol>
<!-- 👉 Description -->
<VCol cols="12">
<VTextarea
v-model="event.extendedProps.description"
label="Description"
placeholder="Meeting description"
/>
</VCol>
<!-- 👉 Form buttons -->
<VCol cols="12">
<VBtn
type="submit"
class="me-3"
>
Submit
</VBtn>
<VBtn
variant="outlined"
color="secondary"
@click="onCancel"
>
Cancel
</VBtn>
</VCol>
</VRow>
</VForm>
<!-- !SECTION -->
</VCardText>
</VCard>
</PerfectScrollbar>
</VNavigationDrawer>
</template>