<!-- ResourceCalendarView.vue -->
<template>
<div>
<!-- View Switcher -->
<div class="btn-group mb-4">
<button class="btn" :class="activeView === 'calendar' ? 'btn-primary' : 'btn-outline-primary'" @click="activeView = 'calendar'">
Calendar View
</button>
<button class="btn" :class="activeView === 'timeline' ? 'btn-primary' : 'btn-outline-primary'" @click="activeView = 'timeline'">
Resource Timeline View
</button>
</div>
<!-- Loading Indicator -->
<div v-if="isLoading" class="text-center my-5">
<div class="spinner-border" role="status"></div>
</div>
<!-- Main Content -->
<div v-else>
<calendar-view v-if="activeView === 'calendar'"
:month-data="calendarMonthData"
:month-name="currentMonthName"
:year="currentYear"
@navigate-prev="handlePrevMonth"
@navigate-next="handleNextMonth"
@navigate-today="handleGoToToday"
@event-click="(event) => $emit('event-click', event)"
/>
<div v-if="activeView === 'timeline'">
<resource-timeline-view
:events="timelineVisibleEvents"
:resources="resources"
:current-date="currentDate"
@navigate-prev="handlePrevDay"
@navigate-next="handleNextDay"
@navigate-today="handleGoToToday"
@event-click="(event) => $emit('event-click', event)"
/>
<nav v-if="resourcePagination.last_page > 1" class="mt-4">
<ul class="pagination justify-content-center">
<li class="page-item" :class="{ disabled: resourcePagination.current_page <= 1 }">
<a class="page-link" href="#" @click.prevent="changeResourcePage(resourcePagination.current_page - 1)">Previous</a>
</li>
<li class="page-item" :class="{ disabled: resourcePagination.current_page >= resourcePagination.last_page }">
<a class="page-link" href="#" @click.prevent="changeResourcePage(resourcePagination.current_page + 1)">Next</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import CalendarView from './components/CalendarView.vue';
import ResourceTimelineView from './components/ResourceTimelineView.vue';
function toYmd(date) { return date.toISOString().split('T')[0]; }
export default {
name: 'ResourceCalendarView',
// Props for API endpoints would be defined here
data() {
return {
activeView: 'calendar',
currentDate: new Date(),
allEvents: [],
resources: [],
isLoading: true,
resourcePage: 1,
resourcePagination: {},
};
},
watch: {
currentDate: 'fetchDataForView',
activeView: 'fetchDataForView'
},
mounted() {
this.fetchDataForView();
},
computed: {
currentYear() { return this.currentDate.getFullYear(); },
currentMonth() { return this.currentDate.getMonth(); },
currentMonthName() { return this.currentDate.toLocaleString('default', { month: 'long' }); },
timelineVisibleEvents() { return this.allEvents; },
calendarMonthData() {
// Logic to build the grid of days and assign events to each day
// This part processes the `allEvents` array fetched from the API
},
},
methods: {
fetchDataForView() {
if (this.activeView === 'calendar') this.fetchEventsForCalendar();
else if (this.activeView === 'timeline') this.fetchPaginatedResourcesAndEvents();
},
async fetchEventsForCalendar() { /* ... API call logic ... */ },
async fetchPaginatedResourcesAndEvents() { /* ... API call logic ... */ },
handlePrevMonth() { this.currentDate = new Date(this.currentYear, this.currentMonth - 1, 1); },
handleNextMonth() { this.currentDate = new Date(this.currentYear, this.currentMonth + 1, 1); },
handlePrevDay() { const d = new Date(this.currentDate); d.setDate(d.getDate() - 1); this.currentDate = d; },
handleNextDay() { const d = new Date(this.currentDate); d.setDate(d.getDate() + 1); this.currentDate = d; },
handleGoToToday() { this.currentDate = new Date(); },
changeResourcePage(page) {
if (page >= 1 && page <= this.resourcePagination.last_page) {
this.resourcePage = page;
this.fetchPaginatedResourcesAndEvents();
}
},
}
};
</script>