1 | import { deleteAppointment, confirmCarriedOut, getUsersByTermExcept, removeRequestAndUpdateUser, removeAppointment, makeReservation ,displayDiv} from './shared.js';
|
---|
2 |
|
---|
3 | let calendar = document.querySelector('.calendar')
|
---|
4 | let importantDate;
|
---|
5 | const month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
---|
6 | const modal = document.getElementById('popupModal');
|
---|
7 | const cancelBtn = document.getElementById('cancelBtn');
|
---|
8 | const approveBtn = document.getElementById('approveBtn');
|
---|
9 | const closeSpan = document.querySelector('.close');
|
---|
10 | const deleteBtn=document.getElementById("temporal-deletion");
|
---|
11 |
|
---|
12 | function resetFields() {
|
---|
13 | document.getElementById('start-time').selectedIndex = 0;
|
---|
14 | document.getElementById('timePicker').selectedIndex=0;
|
---|
15 | document.getElementById('end-time').selectedIndex=0;
|
---|
16 | document.getElementById('time-interval').value = '';
|
---|
17 | document.getElementById('start-date').value = '';
|
---|
18 | document.getElementById('end-date').value='';
|
---|
19 | document.getElementById('delete-date-from').value='';
|
---|
20 | document.getElementById('delete-date-to').value='';
|
---|
21 | }
|
---|
22 | function checkOverlap(existingTimes, newTime) {
|
---|
23 | const [newHour, newMinutes] = newTime.split(':').map(Number);
|
---|
24 |
|
---|
25 | const newStartTime = new Date(0, 0, 0, newHour, newMinutes);
|
---|
26 | const newEndTime = new Date(newStartTime);
|
---|
27 | newEndTime.setHours(newEndTime.getHours() + 1);
|
---|
28 |
|
---|
29 | return existingTimes.some(existingTime => {
|
---|
30 | const [existingHour, existingMinutes] = existingTime.split(':').map(Number);
|
---|
31 | const existingStartTime = new Date(0, 0, 0, existingHour, existingMinutes);
|
---|
32 | const existingEndTime = new Date(existingStartTime);
|
---|
33 | existingEndTime.setHours(existingEndTime.getHours() + 1);
|
---|
34 | return newStartTime < existingEndTime && newEndTime > existingStartTime;
|
---|
35 | });
|
---|
36 | }
|
---|
37 | async function getExistingAppointmentsMapped() {
|
---|
38 | let existingAppointments;
|
---|
39 | try {
|
---|
40 | const response = await fetch(`/api/appointments/getAllAppointments`);
|
---|
41 | if (!response.ok) {
|
---|
42 | throw new Error('Failed to fetch appointments');
|
---|
43 | }
|
---|
44 | existingAppointments = await response.json();
|
---|
45 | console.log(existingAppointments);
|
---|
46 | } catch (error) {
|
---|
47 | console.error(error);
|
---|
48 | }
|
---|
49 |
|
---|
50 | const appointmentMap = new Map();
|
---|
51 | existingAppointments.forEach(appointment => {
|
---|
52 | const dateTime = new Date(appointment.term);
|
---|
53 | const date = dateTime.toISOString().split('T')[0];
|
---|
54 | const time = dateTime.toTimeString().substring(0, 5);
|
---|
55 | if (appointmentMap.has(date)) {
|
---|
56 | appointmentMap.get(date).push(time);
|
---|
57 | } else {
|
---|
58 | appointmentMap.set(date, [time]);
|
---|
59 | }
|
---|
60 | });
|
---|
61 | return appointmentMap;
|
---|
62 | }
|
---|
63 | function createAppointments(startDate, endDate, startTime, endTime, interval) {
|
---|
64 | let appointments = [];
|
---|
65 | let currentDate = new Date(startDate);
|
---|
66 | let endDateObj = new Date(endDate);
|
---|
67 | const [startHour, startMinute] = startTime.split(':').map(Number);
|
---|
68 | const [endHour, endMinute] = endTime.split(':').map(Number);
|
---|
69 |
|
---|
70 | while (currentDate <= endDateObj) {
|
---|
71 | let currentStartTime = new Date(currentDate);
|
---|
72 | currentStartTime.setHours(startHour, startMinute, 0, 0);
|
---|
73 |
|
---|
74 | let currentEndTime = new Date(currentDate);
|
---|
75 | currentEndTime.setHours(endHour - 1, endMinute+interval, 0, 0);
|
---|
76 |
|
---|
77 | while (currentStartTime < currentEndTime) {
|
---|
78 | const formattedDate = currentDate.toISOString().split('T')[0];
|
---|
79 | appointments.push({
|
---|
80 | date: formattedDate,
|
---|
81 | time: currentStartTime.toTimeString().substring(0, 5)
|
---|
82 | });
|
---|
83 | currentStartTime.setMinutes(currentStartTime.getMinutes() + interval + 60);
|
---|
84 | }
|
---|
85 | currentDate.setDate(currentDate.getDate() + 1);
|
---|
86 | }
|
---|
87 |
|
---|
88 | return appointments;
|
---|
89 | }
|
---|
90 |
|
---|
91 | function formatConflictAlert(conflictingAppointments) {
|
---|
92 | const appointmentList = Array.isArray(conflictingAppointments) ? conflictingAppointments : [conflictingAppointments];
|
---|
93 | const formattedAppointments = appointmentList.map(appointment =>
|
---|
94 | `Датум: ${appointment.date}, Време: ${appointment.time}`
|
---|
95 | );
|
---|
96 |
|
---|
97 | const alertMessage = [
|
---|
98 | "Неуспешно креирање на термини:",
|
---|
99 | ...formattedAppointments
|
---|
100 | ].filter(Boolean).join('\n');
|
---|
101 |
|
---|
102 | return alertMessage.trim();
|
---|
103 | }
|
---|
104 |
|
---|
105 | async function createAutoAppointments(appointments) {
|
---|
106 | const requestBody = appointments.map(appointment => ({
|
---|
107 | date: appointment.date,
|
---|
108 | time: appointment.time,
|
---|
109 | }));
|
---|
110 |
|
---|
111 | await fetch(`/api/appointments/create`, {
|
---|
112 | method: 'POST',
|
---|
113 | headers: {
|
---|
114 | 'Content-Type': 'application/json',
|
---|
115 | },
|
---|
116 | body: JSON.stringify(requestBody) // Send all appointments in one request
|
---|
117 | });
|
---|
118 | }
|
---|
119 | document.getElementById('create-appointments').addEventListener('click', async function () {
|
---|
120 | const startDate = document.getElementById('start-date').value;
|
---|
121 | const endDate = document.getElementById('end-date').value;
|
---|
122 | const startTime = document.getElementById('start-time').value;
|
---|
123 | const endTime = document.getElementById('end-time').value;
|
---|
124 | const interval = parseInt(document.getElementById('time-interval').value);
|
---|
125 |
|
---|
126 | if (!startDate || !endDate || !startTime || !endTime || !interval) {
|
---|
127 | alert("Please fill out all the fields.");
|
---|
128 | return;
|
---|
129 | }
|
---|
130 |
|
---|
131 | const appointments = createAppointments(startDate, endDate, startTime, endTime, interval);
|
---|
132 | console.log('Generated Appointments:', appointments);
|
---|
133 |
|
---|
134 | const existingMapped = await getExistingAppointmentsMapped();
|
---|
135 | const conflictingAppointments = [];
|
---|
136 | const successfulAppointments = [];
|
---|
137 |
|
---|
138 | appointments.forEach(newAppointment => {
|
---|
139 | const { date, time } = newAppointment;
|
---|
140 |
|
---|
141 | if (existingMapped.has(date)) {
|
---|
142 | const existingTimes = existingMapped.get(date);
|
---|
143 | if (checkOverlap(existingTimes, time)) {
|
---|
144 | conflictingAppointments.push(newAppointment); // Add to conflict list if overlaps
|
---|
145 | } else {
|
---|
146 | successfulAppointments.push(newAppointment);
|
---|
147 | }
|
---|
148 | } else {
|
---|
149 | successfulAppointments.push(newAppointment);
|
---|
150 | }
|
---|
151 | });
|
---|
152 | console.log(conflictingAppointments);
|
---|
153 | console.log(successfulAppointments);
|
---|
154 | if(successfulAppointments.length>0){
|
---|
155 | await createAutoAppointments(successfulAppointments);
|
---|
156 | }
|
---|
157 | if (conflictingAppointments.length > 0) {
|
---|
158 | const alertMessage = formatConflictAlert(conflictingAppointments);
|
---|
159 | alert(alertMessage);
|
---|
160 | }
|
---|
161 | resetFields();
|
---|
162 | });
|
---|
163 |
|
---|
164 | cancelBtn.addEventListener('click', () => {
|
---|
165 | modal.style.display = 'none';
|
---|
166 | });
|
---|
167 |
|
---|
168 | closeSpan.addEventListener('click', () => {
|
---|
169 | modal.style.display = 'none';
|
---|
170 | });
|
---|
171 |
|
---|
172 | deleteBtn.addEventListener('click',()=>{
|
---|
173 | deleteAppointment(deleteBtn.getAttribute("term"),deleteBtn.getAttribute("type"));
|
---|
174 | })
|
---|
175 |
|
---|
176 | window.addEventListener('click', (event) => {
|
---|
177 | if (event.target === modal) {
|
---|
178 | modal.style.display = 'none';
|
---|
179 | }
|
---|
180 | });
|
---|
181 |
|
---|
182 | function cleanAssets() {
|
---|
183 | const ids = ['request-assets', 'appointment-assets'];
|
---|
184 | ids.forEach((id) => {
|
---|
185 | const element = document.getElementById(id);
|
---|
186 | if (element && element.style.display !== 'none') {
|
---|
187 | element.style.display = 'none';
|
---|
188 | }
|
---|
189 | });
|
---|
190 | }
|
---|
191 |
|
---|
192 |
|
---|
193 | async function isAppointmentReserved(dateTime) {
|
---|
194 | try {
|
---|
195 | const response = await fetch(`/api/appointments/isReserved?term=${dateTime}`);
|
---|
196 | return await response.json();
|
---|
197 | } catch (error) {
|
---|
198 | console.error('Error checking if appointment reserved:', error);
|
---|
199 | return false;
|
---|
200 | }
|
---|
201 | }
|
---|
202 | async function isAppointmentEmpty(dateTime) {
|
---|
203 | try {
|
---|
204 | const response = await fetch(`/api/requests/isEmpty?term=${dateTime}`);
|
---|
205 | return await response.json();
|
---|
206 | } catch (error) {
|
---|
207 | console.error('Error checking if no requests:', error);
|
---|
208 | return false;
|
---|
209 | }
|
---|
210 | }
|
---|
211 | function cleanData(bodyId){
|
---|
212 | const element = document.getElementById(bodyId);
|
---|
213 | while (element.firstChild) {
|
---|
214 | element.removeChild(element.firstChild);
|
---|
215 | }
|
---|
216 | }
|
---|
217 | function createLines(data,dateTime,whichOne){
|
---|
218 | cleanData(whichOne)
|
---|
219 | if(!Array.isArray(data)){
|
---|
220 | data=[data];
|
---|
221 | }
|
---|
222 |
|
---|
223 | let requestedElement=document.getElementById(whichOne);
|
---|
224 | data.forEach(item => {
|
---|
225 | const requestedRow = document.createElement('tr');
|
---|
226 | const usernameTd = document.createElement('td');
|
---|
227 | usernameTd.textContent = item.username;
|
---|
228 | requestedRow.appendChild(usernameTd);
|
---|
229 | const nameTd = document.createElement('td');
|
---|
230 | nameTd.textContent = item.name;
|
---|
231 | requestedRow.appendChild(nameTd);
|
---|
232 | const surnameTd = document.createElement('td');
|
---|
233 | surnameTd.textContent = item.surname;
|
---|
234 | requestedRow.appendChild(surnameTd);
|
---|
235 | const additionalInfoTd = document.createElement('td');
|
---|
236 | additionalInfoTd.textContent = item.additionalInfo;
|
---|
237 | requestedRow.appendChild(additionalInfoTd);
|
---|
238 | const couponCodeTd = document.createElement('td');
|
---|
239 | couponCodeTd.textContent = item.couponCode;
|
---|
240 | requestedRow.appendChild(couponCodeTd);
|
---|
241 | requestedElement.appendChild(requestedRow);
|
---|
242 | displayDiv(dateTime);
|
---|
243 | })
|
---|
244 | }
|
---|
245 | function getAllRequests(dateTime,containerId){
|
---|
246 | let url;
|
---|
247 | if(containerId === "approved"){
|
---|
248 | url = `/api/appointments/listApprovedRequest?term=${dateTime}`;
|
---|
249 | } else {
|
---|
250 | url = `/api/requests/listRequests?term=${dateTime}`;
|
---|
251 | }
|
---|
252 |
|
---|
253 | fetch(url)
|
---|
254 | .then(response => response.json())
|
---|
255 | .then(data => {
|
---|
256 | createLines(data,dateTime,containerId)
|
---|
257 | })
|
---|
258 | .catch(error => {
|
---|
259 | console.error('Error fetching requests:', error);
|
---|
260 | });
|
---|
261 | }
|
---|
262 | function createActiveAppointments(data){
|
---|
263 | const frameElement=document.getElementById("frame");
|
---|
264 | frameElement.innerHTML = '';
|
---|
265 | document.getElementById("approved-table").style.display = 'none';
|
---|
266 | document.getElementById("requested-table").style.display = 'none';
|
---|
267 | data.forEach(item => {
|
---|
268 | const itemDiv = document.createElement('div');
|
---|
269 | itemDiv.style.border = '1px solid black';
|
---|
270 | itemDiv.style.padding = '20px';
|
---|
271 | itemDiv.style.display = 'inline-block';
|
---|
272 | itemDiv.style.marginRight = '10px';
|
---|
273 |
|
---|
274 | const appointmentDate = new Date(item.localDateTime);
|
---|
275 | const timeOptions = { hour: '2-digit', minute: '2-digit', hour12: false };
|
---|
276 | itemDiv.textContent = appointmentDate.toLocaleTimeString([], timeOptions);
|
---|
277 |
|
---|
278 | itemDiv.addEventListener('click', async () => {
|
---|
279 | try{
|
---|
280 |
|
---|
281 | const isReserved=await isAppointmentReserved(item.localDateTime);
|
---|
282 | const isEmpty=await isAppointmentEmpty(item.localDateTime);
|
---|
283 | cleanAssets();
|
---|
284 | cleanData("approved")
|
---|
285 | cleanData("requested")
|
---|
286 | if (isReserved) {
|
---|
287 | document.getElementById("approved-table").style.display = 'block';
|
---|
288 | document.getElementById("requested-table").style.display = 'none';
|
---|
289 | getAllRequests(item.localDateTime,"approved","");
|
---|
290 | document.getElementById("appointment-assets").style.display='block';
|
---|
291 | deleteBtn.style.display='block';
|
---|
292 | deleteBtn.setAttribute("term",item.localDateTime);
|
---|
293 | deleteBtn.setAttribute("type","cancelledAppointmentByAdmin");
|
---|
294 | //da go isprogramirash delete-approval
|
---|
295 | document.getElementById("delete-approval").addEventListener('click', function() {
|
---|
296 | removeAppointment(item.localDateTime,"cancelledAppointmentByAdmin");
|
---|
297 | });
|
---|
298 | document.getElementById("approve-carried-out").addEventListener('click', function() {
|
---|
299 | modal.style.display = 'flex';
|
---|
300 | approveBtn.addEventListener('click', () => {
|
---|
301 | const userInput = document.getElementById('userInput').value;
|
---|
302 | confirmCarriedOut(item.localDateTime,userInput);
|
---|
303 | modal.style.display = 'none';
|
---|
304 | });
|
---|
305 |
|
---|
306 | });
|
---|
307 | }
|
---|
308 | else if(!isEmpty){
|
---|
309 | document.getElementById("approved-table").style.display = 'none';
|
---|
310 | document.getElementById("requested-table").style.display = 'block';
|
---|
311 | getAllRequests(item.localDateTime,"requested","");
|
---|
312 | document.getElementById("request-assets").style.display='block';
|
---|
313 | deleteBtn.style.display='block';
|
---|
314 | deleteBtn.setAttribute("term",item.localDateTime);
|
---|
315 | deleteBtn.setAttribute("type","rejected");
|
---|
316 | }
|
---|
317 | else{
|
---|
318 | document.getElementById("approved-table").style.display = 'none';
|
---|
319 | document.getElementById("requested-table").style.display = 'none';
|
---|
320 | deleteBtn.style.display='block';
|
---|
321 | deleteBtn.setAttribute("term",item.localDateTime);
|
---|
322 | }
|
---|
323 |
|
---|
324 |
|
---|
325 | }
|
---|
326 | catch(error){
|
---|
327 | console.error('Error checking appointment reservation:', error);
|
---|
328 | }
|
---|
329 |
|
---|
330 | });
|
---|
331 |
|
---|
332 | frameElement.appendChild(itemDiv);
|
---|
333 | });
|
---|
334 | }
|
---|
335 | function fetchAppointments(date){
|
---|
336 | deleteBtn.style.display='none';
|
---|
337 | fetch(`/api/appointments/listAppointments?date=${date}`)
|
---|
338 | .then(response => response.json())
|
---|
339 | .then(data => {
|
---|
340 | createActiveAppointments(data);
|
---|
341 | })
|
---|
342 | .catch(error => {
|
---|
343 | console.error('Error fetching appointments:', error);
|
---|
344 | });
|
---|
345 | }
|
---|
346 |
|
---|
347 | const isLeapYear = (year) => {
|
---|
348 | return (year % 4 === 0 && year % 100 !== 0 && year % 400 !== 0) || (year % 100 === 0 && year % 400 ===0)
|
---|
349 | }
|
---|
350 |
|
---|
351 | const getFebDays = (year) => {
|
---|
352 | return isLeapYear(year) ? 29 : 28
|
---|
353 | }
|
---|
354 |
|
---|
355 |
|
---|
356 | const generateCalendar = (month, year) => {
|
---|
357 |
|
---|
358 | let calendar_days = calendar.querySelector('.calendar-days')
|
---|
359 | let calendar_header_year = calendar.querySelector('#year')
|
---|
360 |
|
---|
361 | let days_of_month = [31, getFebDays(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
---|
362 |
|
---|
363 | calendar_days.innerHTML = ''
|
---|
364 |
|
---|
365 | let currDate = new Date()
|
---|
366 |
|
---|
367 | // if (!month) month = currDate.getMonth()
|
---|
368 | console.log(month);
|
---|
369 | if (typeof month !== 'number') month = currDate.getMonth();
|
---|
370 | if (!year) year = currDate.getFullYear()
|
---|
371 |
|
---|
372 | let curr_month = `${month_names[month]}`
|
---|
373 | month_picker.innerHTML = curr_month
|
---|
374 | calendar_header_year.innerHTML = year
|
---|
375 |
|
---|
376 | // get first day of month
|
---|
377 |
|
---|
378 | let first_day = new Date(year, month, 1)
|
---|
379 |
|
---|
380 | for (let i = 0; i <= days_of_month[month] + first_day.getDay() - 1; i++) {
|
---|
381 | let day = document.createElement('div')
|
---|
382 | if (i >= first_day.getDay()) {
|
---|
383 | day.classList.add('calendar-day-hover')
|
---|
384 | day.innerHTML = i - first_day.getDay() + 1;
|
---|
385 | day.innerHTML += `<span></span>
|
---|
386 | <span></span>
|
---|
387 | <span></span>
|
---|
388 | <span></span>`;
|
---|
389 | let selectedDate = `${year}-${(month + 1).toString().padStart(2, '0')}-${(i - first_day.getDay() + 1).toString().padStart(2, '0')}`;
|
---|
390 | if (i - first_day.getDay() + 1 === currDate.getDate() && year === currDate.getFullYear() && month === currDate.getMonth()) {
|
---|
391 | day.classList.add('curr-date')
|
---|
392 | importantDate=selectedDate;
|
---|
393 | document.getElementById("insert-date").innerText=importantDate;
|
---|
394 | fetchAppointments(importantDate);
|
---|
395 | }
|
---|
396 | day.addEventListener('click', () => {
|
---|
397 | let temp=document.getElementsByClassName('curr-date');
|
---|
398 | Array.from(temp).forEach(element => {
|
---|
399 | element.classList.remove('curr-date');
|
---|
400 | });
|
---|
401 | importantDate=selectedDate;
|
---|
402 | let daySpan= document.getElementById("insert-date");
|
---|
403 | daySpan.innerText="";
|
---|
404 | daySpan.innerText=importantDate;
|
---|
405 | day.classList.add('curr-date');
|
---|
406 | fetchAppointments(importantDate);
|
---|
407 | cleanAssets();
|
---|
408 | cleanData("approved")
|
---|
409 | cleanData("requested")
|
---|
410 | resetFields();
|
---|
411 | });
|
---|
412 | }
|
---|
413 | calendar_days.appendChild(day)
|
---|
414 | }
|
---|
415 | }
|
---|
416 |
|
---|
417 | let month_list = calendar.querySelector('.month-list')
|
---|
418 |
|
---|
419 | month_names.forEach((e, index) => {
|
---|
420 | let month = document.createElement('div')
|
---|
421 | month.innerHTML = `<div data-month="${index}">${e}</div>`
|
---|
422 | month.querySelector('div').onclick = () => {
|
---|
423 | month_list.classList.remove('show')
|
---|
424 | curr_month.value = index
|
---|
425 | generateCalendar(index, curr_year.value)
|
---|
426 | }
|
---|
427 | month_list.appendChild(month)
|
---|
428 | })
|
---|
429 |
|
---|
430 | let month_picker = calendar.querySelector('#month-picker')
|
---|
431 |
|
---|
432 | month_picker.onclick = () => {
|
---|
433 | month_list.classList.add('show')
|
---|
434 | }
|
---|
435 |
|
---|
436 | let currDate = new Date()
|
---|
437 |
|
---|
438 | let curr_month = {value: currDate.getMonth()}
|
---|
439 | let curr_year = {value: currDate.getFullYear()}
|
---|
440 |
|
---|
441 | generateCalendar(curr_month.value, curr_year.value)
|
---|
442 |
|
---|
443 | document.querySelector('#prev-year').onclick = () => {
|
---|
444 | --curr_year.value
|
---|
445 | generateCalendar(curr_month.value, curr_year.value)
|
---|
446 | }
|
---|
447 |
|
---|
448 | document.querySelector('#next-year').onclick = () => {
|
---|
449 | ++curr_year.value
|
---|
450 | generateCalendar(curr_month.value, curr_year.value)
|
---|
451 | }
|
---|
452 | function populateTimePicker() {
|
---|
453 | const timePicker = document.getElementById('timePicker');
|
---|
454 | const timePickerStart = document.getElementById('start-time');
|
---|
455 | const timePickerEnd = document.getElementById('end-time');
|
---|
456 |
|
---|
457 | const timePickerInterval = 10;
|
---|
458 | const otherPickersInterval = 30;
|
---|
459 |
|
---|
460 | for (let hour = 7; hour < 22; hour++) { // 0 to 23 for 24-hour format
|
---|
461 | for (let minutes = 0; minutes < 60; minutes++) {
|
---|
462 | const formattedHour = hour.toString().padStart(2, '0');
|
---|
463 | const formattedMinutes = minutes.toString().padStart(2, '0');
|
---|
464 |
|
---|
465 |
|
---|
466 | if (minutes % timePickerInterval === 0) {
|
---|
467 | let timeOption = document.createElement('option');
|
---|
468 | timeOption.value = `${formattedHour}:${formattedMinutes}`;
|
---|
469 | timeOption.text = `${formattedHour}:${formattedMinutes}`;
|
---|
470 | timePicker.appendChild(timeOption);
|
---|
471 | }
|
---|
472 |
|
---|
473 | if (minutes % otherPickersInterval === 0) {
|
---|
474 | let timeOptionStart = document.createElement('option');
|
---|
475 | timeOptionStart.value = `${formattedHour}:${formattedMinutes}`;
|
---|
476 | timeOptionStart.text = `${formattedHour}:${formattedMinutes}`;
|
---|
477 | timePickerStart.appendChild(timeOptionStart);
|
---|
478 |
|
---|
479 | let timeOptionEnd = document.createElement('option');
|
---|
480 | timeOptionEnd.value = `${formattedHour}:${formattedMinutes}`;
|
---|
481 | timeOptionEnd.text = `${formattedHour}:${formattedMinutes}`;
|
---|
482 | timePickerEnd.appendChild(timeOptionEnd);
|
---|
483 | }
|
---|
484 | }
|
---|
485 | }
|
---|
486 | }
|
---|
487 |
|
---|
488 | function createSeparateAppointment(data){
|
---|
489 | fetch('/api/appointments/add', {
|
---|
490 | method: 'POST',
|
---|
491 | headers: {
|
---|
492 | 'Content-Type': 'application/json',
|
---|
493 | },
|
---|
494 | body: JSON.stringify(data),
|
---|
495 | })
|
---|
496 | .then(response => {
|
---|
497 | if (!response.ok) {
|
---|
498 | return response.json().then(errorData => {
|
---|
499 | throw new Error(errorData.error || 'Unknown error');
|
---|
500 | });
|
---|
501 | }
|
---|
502 | return response.json();
|
---|
503 | })
|
---|
504 | .then(data => {
|
---|
505 | console.log(data.message);
|
---|
506 | })
|
---|
507 | .catch(error => {
|
---|
508 | console.error('Error:', error);
|
---|
509 | });
|
---|
510 | }
|
---|
511 |
|
---|
512 | async function deleteFreeAppointments() {
|
---|
513 | const selectedDateFrom = document.getElementById('delete-date-from').value;
|
---|
514 | const selectedDateTo = document.getElementById('delete-date-to').value;
|
---|
515 | if (!selectedDateFrom && !selectedDateTo) {
|
---|
516 | alert("Please select dates!");
|
---|
517 | return;
|
---|
518 | }
|
---|
519 |
|
---|
520 | try {
|
---|
521 | const response = await fetch(`/api/appointments/deleteFree?startDate=${selectedDateFrom}&endDate=${selectedDateTo}`, {
|
---|
522 | method: 'DELETE',
|
---|
523 | });
|
---|
524 |
|
---|
525 | if (response.ok) {
|
---|
526 | alert("Free appointments for the selected date range were deleted.");
|
---|
527 | } else {
|
---|
528 | alert("An error occurred while trying to delete the appointments.");
|
---|
529 | }
|
---|
530 | } catch (error) {
|
---|
531 | console.error("Error deleting appointments:", error);
|
---|
532 | alert("A network error occurred while trying to delete the appointments.");
|
---|
533 | }
|
---|
534 | document.getElementById('delete-date-from').value='';
|
---|
535 | document.getElementById('delete-date-to').value='';
|
---|
536 | }
|
---|
537 |
|
---|
538 | populateTimePicker();
|
---|
539 | document.addEventListener('DOMContentLoaded', () => {
|
---|
540 | const today = new Date();
|
---|
541 | const formattedDate = today.toISOString().split('T')[0];
|
---|
542 | document.getElementById('start-date').setAttribute('min', formattedDate);
|
---|
543 | document.getElementById('end-date').setAttribute('min',formattedDate);
|
---|
544 | const addTermButton = document.getElementById('add-Term');
|
---|
545 | const timePicker = document.getElementById('timePicker');
|
---|
546 | timePicker.addEventListener('click',()=>{
|
---|
547 | document.getElementById('start-time').selectedIndex = 0;
|
---|
548 | document.getElementById('end-time').selectedIndex=0;
|
---|
549 | document.getElementById('time-interval').value = '';
|
---|
550 | document.getElementById('start-date').value = '';
|
---|
551 | document.getElementById('end-date').value='';
|
---|
552 | document.getElementById('delete-date-from').value='';
|
---|
553 | document.getElementById('delete-date-to').value='';
|
---|
554 | })
|
---|
555 | addTermButton.addEventListener('click',async () => {
|
---|
556 | const selectedTime = timePicker.value;
|
---|
557 | if (importantDate && selectedTime) {
|
---|
558 | console.log(`Selected Date: ${importantDate}`);
|
---|
559 | console.log(`Selected Time: ${selectedTime}`);
|
---|
560 |
|
---|
561 | const data = {
|
---|
562 | date: importantDate,
|
---|
563 | time: selectedTime
|
---|
564 | };
|
---|
565 |
|
---|
566 |
|
---|
567 | const mapped = await getExistingAppointmentsMapped();
|
---|
568 | if (mapped.has(importantDate)) {
|
---|
569 | const existingTimes = mapped.get(importantDate);
|
---|
570 | if (checkOverlap(existingTimes, selectedTime)) {
|
---|
571 | const alertMessage = formatConflictAlert(data);
|
---|
572 | alert(alertMessage);
|
---|
573 | } else {
|
---|
574 | createSeparateAppointment(data);
|
---|
575 | }
|
---|
576 | }
|
---|
577 | else {
|
---|
578 | createSeparateAppointment(data);
|
---|
579 | }
|
---|
580 | resetFields();
|
---|
581 | } else {
|
---|
582 | console.error('Please select a date and time.');
|
---|
583 | }
|
---|
584 | });
|
---|
585 |
|
---|
586 | let tempContainer=document.getElementsByClassName('appointment-section')[0];
|
---|
587 | tempContainer.addEventListener('click',()=>{
|
---|
588 | document.getElementById('timePicker').selectedIndex=0;
|
---|
589 | })
|
---|
590 | document.getElementById('delete-free-button').addEventListener('click', deleteFreeAppointments);
|
---|
591 | });
|
---|
592 |
|
---|
593 |
|
---|