Untitled

mail@pastecode.io avatar
unknown
plain_text
2 months ago
5.6 kB
3
Indexable
Never
<template>
    <section class="section -calendar-of-activities">
      <div class="row">
        <div class="col-lg-12">
          <div class="card -card-no-top-shadow">
            <div class="card-body pt-3">
                <div class="row">
                    <div class="col-md-10">
                        <div class="d-flex flex-wrap">
                            <div class="d-flex justify-content-start align-items-center me-3 mb-2" v-for="(c, i) in categoryOptions" :key="i">
                                <div class="me-1" :style="`width: 20px; height: 20px; background-color: ${c.color}`"></div>
                                <div class="text-nowrap">{{ c.name }}</div>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-2">
                        <div class="d-flex justify-content-end mb-3">
                            <button type="button" class="btn btn-success" @click="resetForm(); $emit('showCreateActivityModal')">Create Activity</button>
                        </div>  
                    </div>
                </div>
                
                <FullCalendar :options="calendarOptions">
                    <template v-slot:eventContent='arg'>
                        <div class="-event-holder px-2" :style="`border-left: 15px solid ${arg.event.extendedProps.category_color}; background-color: ${hexToRgbWithOpacity(arg.event.extendedProps.category_color, '0.2')}`">
                            <div class="row">
                                <b class="event-title">{{ arg.event.title }}</b>
                                <br>
                                <p class="m-0">{{ arg.event.extendedProps.start_time }}</p>
                            </div>
                        </div>
                    </template>
                </FullCalendar>
            </div>
          </div>
        </div>
      </div>
    </section>
</template>


<script>
import useActivityState from '@/store/useActivityState'
import useActivityCategoryState from '@/store/useActivityCategoryState'
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import { hexToRgbWithOpacity } from '@/boot/global'

export default {
    components: {
        FullCalendar,
    },
    data() {
        return {
            calendarOptions: {
                plugins: [
                    dayGridPlugin,
                    timeGridPlugin,
                    interactionPlugin // needed for dateClick
                ],
                headerToolbar: {
                    left: 'prev',
                    center: 'title',
                    right: 'next'
                },
                initialView: 'dayGridMonth',
                events: [],
                selectable: true,
                selectMirror: true,
                dayMaxEvents: 2, // Allow grid to adjust based on number of events
                weekends: true,
                datesSet: this.handleDateSet,
                eventClick: this.handleEventClick,
            },
        }
    },
    watch: {
        activities: function(value){
            this.calendarOptions.events = value.map(d => {
                return {
                    id: d.id,
                    title: d.title,
                    start: d.start_date_time,
                    extendedProps: d,
                }
            })
        }
    },
    methods: {
        handleDateSet(dateInfo){
            this.filter.start_date =  dateInfo.startStr.split('T')[0]
            this.filter.end_date =  dateInfo.endStr.split('T')[0]
            this.fetchActivities()
        },
        handleEventClick(clickInfo){
            const closeBtn = document.querySelector('.fc-popover-close')
            if(closeBtn) closeBtn.click()
            this.setForm(clickInfo.event.extendedProps)
            this.$emit('showCreateActivityModal')
        },
    },
    setup() {
        const {
            setForm,
            getFilter,
            resetForm,
            getActivities,
            fetchActivities,
        } = useActivityState()
        const filter = getFilter()

        const { getCategoryOptions } = useActivityCategoryState()

        return {
            filter,
            setForm,
            resetForm,
            fetchActivities,
            hexToRgbWithOpacity,
            activities: getActivities(),
            categoryOptions: getCategoryOptions(),
        }
    }
}
</script>

<style>
.-calendar-of-activities {
    --primary-font: #2E2E2E;
    --primary-color: #286BAE;
    --white-font: #FFF;
}

.fc-event:hover {
    background: none;
}

.fc .fc-daygrid-day.fc-day-today {
    background-color: #ebebeb;
}

.-event-holder {
    border-radius: 5px;
    color: var(--primary-font);
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin: 0.3rem;
    padding: 0.7rem 0;
    border-radius: 12px;
}

.-event-holder:hover {
    background-color: rgba(0, 0, 0, 0.1) !important;
}

.fc .fc-button {
    background-color: var(--primary-color);
    border: none;
}

.fc .fc-button:hover {
    background-color: var(--primary-color);
}

.fc .fc-button:active {
    background-color: var(--primary-color);
}

.fc .fc-button .fc-icon {
    font-size: 2.5em;
    color: var(--white-font);
}

.fc .fc-daygrid-day-number,.fc .fc-col-header-cell-cushion {
    color: var(--primary-font);
    text-decoration: none;
    font-weight: bold;
}
</style>
Leave a Comment