Added price for service
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
<div class="flex h-screen font-sans">
|
||||
<div class="flex-1 p-4 overflow-auto">
|
||||
<!-- The 'ref' is important for accessing the calendar's API -->
|
||||
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,6 +59,7 @@ interface ServiceCall {
|
||||
customer_town: string;
|
||||
type_service_call: number;
|
||||
description: string;
|
||||
service_cost: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
@@ -71,77 +73,80 @@ export default defineComponent({
|
||||
plugins: [dayGridPlugin, interactionPlugin],
|
||||
initialView: 'dayGridMonth',
|
||||
weekends: true,
|
||||
events: [] as any[],
|
||||
// Instead of a static array, we use a function source.
|
||||
// This is the standard way FullCalendar fetches events.
|
||||
events: `${import.meta.env.VITE_BASE_URL}/service/all`,
|
||||
eventClick: this.handleEventClick,
|
||||
// Add headers for authentication if needed by your API
|
||||
eventSourceSuccess: (content, response) => {
|
||||
// This is where you could transform data if needed
|
||||
return content;
|
||||
},
|
||||
eventSourceFailure: (error) => {
|
||||
console.error("Failed to fetch calendar events:", error);
|
||||
}
|
||||
} as CalendarOptions,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus();
|
||||
this.fetchEvents();
|
||||
// We no longer need to call fetchEvents() here because FullCalendar does it automatically.
|
||||
},
|
||||
methods: {
|
||||
async fetchEvents(): Promise<void> {
|
||||
try {
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/service/all`;
|
||||
const response = await axios.get(path, { headers: authHeader(), withCredentials: true });
|
||||
this.calendarOptions.events = response.data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching all calendar events:", error);
|
||||
}
|
||||
},
|
||||
// We can remove the fetchEvents method as FullCalendar now handles it.
|
||||
// async fetchEvents(): Promise<void> { ... }
|
||||
|
||||
// --- THIS IS THE FIX ---
|
||||
handleEventClick(clickInfo: EventClickArg): void {
|
||||
const events = (this.calendarOptions.events as any[]) || [];
|
||||
const originalEvent = events.find(e => e.id == clickInfo.event.id);
|
||||
|
||||
if (originalEvent) {
|
||||
// We "flatten" the nested object from the calendar into the simple,
|
||||
// flat structure that the modal expects.
|
||||
this.selectedServiceForEdit = {
|
||||
id: originalEvent.id,
|
||||
scheduled_date: originalEvent.start,
|
||||
customer_id: originalEvent.customer_id,
|
||||
// Extract the customer name from the title
|
||||
customer_name: originalEvent.title.split(': ')[1] || 'Unknown Customer',
|
||||
// Pull the properties out of the nested extendedProps
|
||||
type_service_call: originalEvent.extendedProps.type_service_call,
|
||||
description: originalEvent.extendedProps.description,
|
||||
|
||||
// Add dummy values for other fields the ServiceCall interface expects
|
||||
customer_address: '',
|
||||
customer_town: '',
|
||||
};
|
||||
}
|
||||
// This logic remains the same, as it correctly pulls data from extendedProps
|
||||
this.selectedServiceForEdit = {
|
||||
id: parseInt(clickInfo.event.id),
|
||||
scheduled_date: clickInfo.event.startStr,
|
||||
customer_name: clickInfo.event.title.split(': ')[1] || 'Unknown Customer',
|
||||
customer_id: clickInfo.event.extendedProps.customer_id,
|
||||
type_service_call: clickInfo.event.extendedProps.type_service_call,
|
||||
description: clickInfo.event.extendedProps.description,
|
||||
service_cost: clickInfo.event.extendedProps.service_cost,
|
||||
};
|
||||
},
|
||||
|
||||
closeEditModal() {
|
||||
this.selectedServiceForEdit = null;
|
||||
},
|
||||
|
||||
// =================== THIS IS THE CORRECTED SECTION ===================
|
||||
async handleSaveChanges(updatedService: ServiceCall) {
|
||||
try {
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/service/update/${updatedService.id}`;
|
||||
await axios.put(path, updatedService, { headers: authHeader(), withCredentials: true });
|
||||
await this.fetchEvents();
|
||||
|
||||
// Get the FullCalendar component instance from the ref
|
||||
const calendarApi = (this.$refs.fullCalendar as any).getApi();
|
||||
if (calendarApi) {
|
||||
// Tell FullCalendar to re-fetch its events from the source.
|
||||
// This is the most reliable way to refresh the view immediately.
|
||||
calendarApi.refetchEvents();
|
||||
}
|
||||
|
||||
this.closeEditModal();
|
||||
} catch (error) {
|
||||
console.error("Failed to save changes:", error);
|
||||
alert("An error occurred while saving. Please check the console.");
|
||||
}
|
||||
},
|
||||
// =================== END OF CORRECTED SECTION ===================
|
||||
|
||||
async handleDeleteService(serviceId: number) {
|
||||
try {
|
||||
const path = `${import.meta.env.VITE_BASE_URL}/service/delete/${serviceId}`;
|
||||
const response = await axios.delete(path, { withCredentials: true, headers: authHeader() });
|
||||
if (response.data.ok === true) {
|
||||
await this.fetchEvents();
|
||||
this.closeEditModal();
|
||||
} else {
|
||||
console.error("Failed to delete event:", response.data.error);
|
||||
await axios.delete(path, { withCredentials: true, headers: authHeader() });
|
||||
|
||||
// Also refresh the calendar after a delete
|
||||
const calendarApi = (this.$refs.fullCalendar as any).getApi();
|
||||
if (calendarApi) {
|
||||
calendarApi.refetchEvents();
|
||||
}
|
||||
|
||||
this.closeEditModal();
|
||||
} catch (error) {
|
||||
console.error("Error deleting event:", error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user