Added calender
This commit is contained in:
155
src/pages/service/calender/CalendarCustomer.vue
Normal file
155
src/pages/service/calender/CalendarCustomer.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="flex">
|
||||
<div class="w-full px-10">
|
||||
<div class="text-sm breadcrumbs mb-4">
|
||||
<ul>
|
||||
<li><router-link :to="{ name: 'home' }">Home</router-link></li>
|
||||
<li><router-link :to="{ name: 'customer' }">Customers</router-link></li>
|
||||
<li v-if="customer">{{ customer.customer_first_name }} {{ customer.customer_last_name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="flex h-screen font-sans">
|
||||
<div v-if="isLoading" class="w-1/4 p-4 border-r">
|
||||
<h2 class="text-xl font-bold">Loading Customer...</h2>
|
||||
</div>
|
||||
<EventSidebar v-else-if="customer" :customer="customer" @event-scheduled="handleEventScheduled" />
|
||||
<div v-else class="w-1/4 p-4 border-r">
|
||||
<h2 class="text-xl font-bold text-red-500">Error</h2>
|
||||
<p>Could not load customer data. You can still view the master calendar.</p>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 p-4 overflow-auto">
|
||||
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
|
||||
</div>
|
||||
<EventModal v-if="selectedEvent" :event="selectedEvent" @close-modal="selectedEvent = null" @delete-event="handleEventDelete" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import Header from '../../../layouts/headers/headerauth.vue';
|
||||
import FullCalendar from '@fullcalendar/vue3';
|
||||
import dayGridPlugin from '@fullcalendar/daygrid';
|
||||
import interactionPlugin from '@fullcalendar/interaction';
|
||||
import { CalendarOptions, EventApi, EventClickArg } from '@fullcalendar/core';
|
||||
import EventSidebar from './EventSidebar.vue';
|
||||
import EventModal from './EventModal.vue';
|
||||
import axios from 'axios';
|
||||
import authHeader from '../../../services/auth.header'; // Assuming you have this service
|
||||
|
||||
// --- Interfaces (no changes) ---
|
||||
interface Customer { id: number; customer_last_name: string; customer_first_name: string; customer_town: string; customer_state: number; customer_zip: string; customer_phone_number: string; customer_address: string; customer_home_type: number; customer_apt: string; }
|
||||
interface EventExtendedProps { description: string; type_service_call: number; }
|
||||
interface AppEvent { id?: string; title: string; start: string; end?: string; extendedProps: EventExtendedProps; }
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CalendarCustomer',
|
||||
components: { Header, FullCalendar, EventSidebar, EventModal },
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
selectedEvent: null as EventApi | null,
|
||||
calendarOptions: {} as CalendarOptions,
|
||||
customer: null as Customer | null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$route.params.id': {
|
||||
handler(newId) {
|
||||
if (newId) this.getCustomer(newId as string);
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.calendarOptions = {
|
||||
plugins: [dayGridPlugin, interactionPlugin],
|
||||
initialView: 'dayGridMonth',
|
||||
weekends: true,
|
||||
events: [],
|
||||
eventClick: this.handleEventClick,
|
||||
};
|
||||
// --- KEY CHANGE: Fetch ALL events when the component is created ---
|
||||
this.fetchEvents();
|
||||
},
|
||||
methods: {
|
||||
async getCustomer(customerId: string): Promise<void> {
|
||||
this.isLoading = true;
|
||||
this.customer = null;
|
||||
try {
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/customer/${customerId}`;
|
||||
const response = await axios.get(path, { withCredentials: true });
|
||||
if (response.data && response.data.id) {
|
||||
this.customer = response.data;
|
||||
// --- REMOVED: No longer need to fetch events from here ---
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("API call to get customer FAILED:", error);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// --- KEY CHANGE: This method now fetches ALL events and is independent ---
|
||||
async fetchEvents(): Promise<void> {
|
||||
try {
|
||||
console.log("fetchEvents: Fetching ALL events for the master calendar.");
|
||||
// Call the new '/service/all' endpoint
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/service/all`;
|
||||
const response = await axios.get(path, { headers: authHeader(), withCredentials: true });
|
||||
|
||||
console.log("fetchEvents: Received all events from API:", response.data);
|
||||
this.calendarOptions.events = response.data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching all calendar events:", error);
|
||||
}
|
||||
},
|
||||
|
||||
handleEventClick(clickInfo: EventClickArg): void {
|
||||
this.selectedEvent = clickInfo.event;
|
||||
},
|
||||
|
||||
async handleEventScheduled(eventData: any): Promise<void> {
|
||||
if (!this.customer) {
|
||||
alert("Error: A customer must be loaded in the sidebar to create a new event.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const payload = {
|
||||
expected_delivery_date: eventData.start, type_service_call: eventData.type_service_call,
|
||||
customer_id: this.customer.id, description: eventData.extendedProps.description,
|
||||
};
|
||||
const path = import.meta.env.VITE_BASE_URL + "/service/create";
|
||||
const response = await axios.post(path, payload, { withCredentials: true, headers: authHeader() });
|
||||
|
||||
if (response.data.ok === true) {
|
||||
// After creating a new event, refresh the entire master calendar
|
||||
await this.fetchEvents();
|
||||
} else {
|
||||
console.error("Failed to create event:", response.data.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error creating event:", error);
|
||||
}
|
||||
},
|
||||
|
||||
async handleEventDelete(eventId: string): Promise<void> {
|
||||
// ... (no changes needed in this method)
|
||||
try {
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/service/delete/${eventId}`;
|
||||
const response = await axios.delete(path, { withCredentials: true, headers: authHeader() });
|
||||
if (response.data.ok === true) {
|
||||
const calendarApi = (this.$refs.fullCalendar as any).getApi();
|
||||
const eventToRemove = calendarApi.getEventById(eventId);
|
||||
if (eventToRemove) eventToRemove.remove();
|
||||
this.selectedEvent = null;
|
||||
}
|
||||
} catch (error) { console.error("Error deleting event:", error); }
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user