Sfoglia il codice sorgente

fixed date formatting issues and added appointment editing

liontix 1 anno fa
parent
commit
3520f1d70a

+ 2 - 1
src/lib/dbdata.ts

@@ -7,7 +7,8 @@ export interface Appointment {
     place: string;
     duration: number;
     times: AppointmentDateTimes[];
-    inputs: DynamicJson[];
+    inputs: AppointmentInputs[];
+    timeSpans: AppointmentList[];
 }  
 
 export interface AppointmentTimes {

+ 16 - 7
src/lib/funcs.ts

@@ -1,5 +1,5 @@
 import moment from "moment";
-import type { AppointmentTimes, WeekSelection } from "./dbdata";
+import type { AppointmentDateTimes, AppointmentTimes, WeekSelection } from "./dbdata";
 import { goto } from "$app/navigation";
 
 export function isSameDate(dateA: Date, dateB: Date) {
@@ -9,15 +9,19 @@ export function isSameDate(dateA: Date, dateB: Date) {
     return date1 === date2;
 }
 
-export function extractTime(date: string): string {
-    return new Date(date).toLocaleTimeString();
+export function getDateString(date: Date): string {
+    return moment(date).format('YYYY-MM-DD');
 }
 
-export function extractDate(date: string): string {
-    return new Date(date).toLocaleDateString();
+export function extractTime(date: Date): string {
+    return date.toLocaleTimeString();
 }
 
-export function getTimeSlots(startDate: string, startTime: string, endTime: string, intervalMinutes: number = 15): AppointmentTimes[] {
+export function extractDate(date: Date): string {
+    return date.toLocaleDateString();
+}
+
+export function getTimeSlots(startDate: string, startTime: string, endTime: string, intervalMinutes: number = 15, appointmentTimes: AppointmentDateTimes[] = []): AppointmentTimes[] {
     let start = moment(`${startDate} ${startTime}`, "YYYY-MM-DD HH:mm");
     let end = moment(`${startDate} ${endTime}`, "YYYY-MM-DD HH:mm");
     let timeSlots: AppointmentTimes[] = [];
@@ -27,7 +31,12 @@ export function getTimeSlots(startDate: string, startTime: string, endTime: stri
             break; // Ensures the last slot does not exceed end time
         }
 
-        timeSlots.push({date: start.format('YYYY-MM-DDTHH:mm'), available: true}); // ISO-like format
+        // check if the appointment time is already booked
+        // to avoid double booking
+        const ix: number = appointmentTimes.findIndex(element => moment(element.date).toISOString() === start.toISOString() && element.available === false);
+        const isAvailable: boolean = ix === -1;
+
+        timeSlots.push({date: start.format('YYYY-MM-DDTHH:mm'), available: isAvailable}); // ISO-like format
         start.add(intervalMinutes, "minutes");
     }
 

+ 1 - 1
src/lib/modules/AppointmentConfirmDialog.svelte

@@ -45,7 +45,7 @@
 	}
 
 	$: {
-		time = extractTime(date);
+		time = extractTime(new Date(date));
 	}
 </script>
 

+ 1 - 1
src/lib/modules/AppointmentInfo.svelte

@@ -15,7 +15,7 @@
     <p><i>pin_drop</i> {location}</p>
     <p><i>description</i> {description}</p>
     {#if isConfirmation}
-        <p><i>event</i> {extractDate(date)}</p>
+        <p><i>event</i> {extractDate(new Date(date))}</p>
         <p><i>schedule</i> {time}</p>
     {/if}
 </article>  

+ 1 - 1
src/lib/modules/CreatorBaseInputs.svelte

@@ -6,7 +6,7 @@
     export let selectedWeek: number;
     export let duration: number;
     export let description: string;
-    export let dueDate: Date;
+    export let dueDate: string;
     export let weeks: WeekSelection[];
 
     export let changeWeek = function a(){};

+ 1 - 1
src/lib/modules/DateTimes.svelte

@@ -23,7 +23,7 @@
     {#each availableTimes as time}
         {#if isSameDate(time.date, selectedDate)}
             <button on:click={() => redirectToBooking(time.date)} 
-                class="responsive wave border bottom-margin">{extractTime(time.date)}</button>
+                class="responsive wave border bottom-margin">{extractTime(new Date(time.date))}</button>
         {/if}
     {/each}
 </article>

+ 3 - 3
src/lib/modules/EventTables.svelte

@@ -122,10 +122,10 @@
         {/if}
 		
 		<!-- load into the creator -->
-        <td on:click={() => redirectEditCreator(data._id)} class="center-align">
-            <button class="medium secondary blue">
+        <td class="center-align">
+            <a href={`/user/creator?id=${data._id}`} class="button medium secondary blue">
                 <span>Bearbeiten</span>
-            </button>
+			</a>
         </td>
 
 		<!-- send a delete request -->

+ 2 - 0
src/routes/appointment/+page.svelte

@@ -42,6 +42,8 @@
         dynamicInputs = js.inputs;
 	}
 
+	$: console.log(selectedDate);
+
 	onMount(async () => {
 		const id = $page.url.searchParams.get('id');
 		if (!id) {

+ 59 - 17
src/routes/user/creator/+page.svelte

@@ -1,7 +1,10 @@
 <script lang="ts">
+	import { goto } from '$app/navigation';
+	import { page } from '$app/stores';
 	import { api_host, authToken } from '$lib';
-	import type { AppointmentInputs, AppointmentList, AppointmentTimes, WeekdayAppointment, WeekSelection } from '$lib/dbdata';
-	import { authFetch, generateDateArray, getTimeSlots } from '$lib/funcs';
+	import type { Appointment, AppointmentDateTimes, AppointmentInputs, AppointmentList, AppointmentTimes, WeekdayAppointment, WeekSelection } from '$lib/dbdata';
+	import { authFetch, generateDateArray, getDateString, getTimeSlots } from '$lib/funcs';
+	import AppointmentConfirmDialog from '$lib/modules/AppointmentConfirmDialog.svelte';
 	import CreatorBaseInputs from '$lib/modules/CreatorBaseInputs.svelte';
 	import CreatorInputs from '$lib/modules/CreatorInputs.svelte';
 	import CreatorTimeInputs from '$lib/modules/CreatorTimeInputs.svelte';
@@ -14,11 +17,15 @@
 	let selectedWeek: number = parseInt(moment().startOf("isoWeek").format("YYYYWW"), 10);
 	let previousWeek: number = selectedWeek;
 	let duration: number = 15;
-	let dueDate: Date = new Date();
+	let dueDate: string = "";
 	let description: string = "test";
 	let renderTimeSelection: boolean = false;
 	let appointmentSaved: boolean = false;
 	let weekSelection: WeekSelection[] = generateDateArray(50);
+	let endpoint: "create" | "modify" = "create";
+	let appointmentId: string = "";
+	let oldAppointmentTimes: AppointmentDateTimes[] = [];
+
 
 	let appointmentList: AppointmentList[] = [
 		{
@@ -61,14 +68,6 @@
 		console.log(selectedWeek);
 		renderTimeSelection = false;
 
-		/*
-		const index = appointmentList.findIndex((entry) => entry.week === selectedWeek);
-		if (index !== -1 && selectedWeekAppointments !== undefined) {
-			appointmentList[index].appointments = selectedWeekAppointments;
-			//console.log(appointmentList[index].appointments);
-		}
-		*/
-
         const ix = appointmentList.findIndex((entry) => entry.week === selectedWeek);
 		if (ix === -1) {
             const tmp = {
@@ -112,11 +111,14 @@
 	function convertAppointmentList() {
 		let times: AppointmentTimes[] = [];
 
+		// on update match with existing booked appointments
+		console.log(oldAppointmentTimes);
+
 		appointmentList.forEach(entry => {
 			entry.appointments.filter(element => element.active !== false).forEach(day => {
 				day.times.forEach(time => {
 					// if (!time.start || !time.end)
-					times = [... times, ...getTimeSlots(day.date, time.start, time.end, duration)];
+					times = [... times, ...getTimeSlots(day.date, time.start, time.end, duration, oldAppointmentTimes)];
 				});
 				
 			});
@@ -129,24 +131,27 @@
 		if (!topic || !description || !dueDate || !location || !duration || !creatorInputs || !appointmentList) {
 			return;
 		}
+		console.log(appointmentList);
 		const convertedTimes: AppointmentTimes[] = convertAppointmentList();
 		console.log(convertedTimes);
 
 		try {
-            const response = await authFetch(`${api_host}/api/users/create`, {
+            const response = await authFetch(`${api_host}/api/users/${endpoint}`, {
                 method: "POST",
                 headers: {
                     "Content-Type": "application/json",
                     "Authorization": "Bearer " + $authToken
                 },
                 body: JSON.stringify({
+					appointmentId: appointmentId,
                     title: topic,
 					description: description,
 					dueDate: dueDate,
 					place: location,
 					duration: duration,
 					times: convertedTimes,
-					inputs: creatorInputs 
+					inputs: creatorInputs,
+					timeSpans: appointmentList
                 })
             });
 
@@ -161,9 +166,46 @@
         }
 	}
 
-	onMount(() => {
-		// implement editor if query id param was detected
+	async function loadAppointment(appointmentId: string) {
+		selectedWeekAppointments = undefined;
+		const response = await fetch(`${api_host}/api/schedule?appointmentId=${appointmentId}&isUser=true`, {
+			method: 'GET',
+			headers: {
+				'Content-Type': 'application/json'
+			}
+		});
+
+		if (response.status === 404) {
+			goto('/errors/404');
+		}
+		const resp = await response.json();
+		const js: Appointment = resp;
+		appointmentList = js.timeSpans;
 		
+		topic = js.title;
+		creatorInputs = js.inputs;
+		location = js.place;
+		duration = js.duration;
+		dueDate = getDateString(js.dueDate);
+		console.log(js.dueDate);
+		description = js.description;
+		oldAppointmentTimes = js.times;
+		endpoint = "modify";
+
+		selectedWeekAppointments = appointmentList.find(
+			(entry) => entry.week === selectedWeek
+		)?.appointments;
+	}
+
+	$: console.log(dueDate);
+
+	onMount(async () => {
+		// implement editor if query id param was detected
+		const id = $page.url.searchParams.get('id');
+		if (id) {
+			appointmentId = id;
+			await loadAppointment(id);
+		}
 	});
 
 	// get time slots before sending
@@ -189,7 +231,7 @@
 </div>
 
 {#if appointmentSaved}
-	<div class="snackbar green active">Erfolgreich erstellt</div>
+	<div class="snackbar green active">Erfolgreich gespeichert</div>
 {/if}
 
 <style>

+ 2 - 2
src/routes/user/participants/+page.svelte

@@ -82,8 +82,8 @@
         <tbody>
             {#each bookingData as data}
                 <tr>
-                    <td class="center-align">{extractDate(data.time)}</td>
-                    <td class="center-align">{extractTime(data.time)}</td>
+                    <td class="center-align">{extractDate(new Date(data.time))}</td>
+                    <td class="center-align">{extractTime(new Date(data.time))}</td>
                     {#each data.inputs as input}
                         <td class="center-align">{input.value}</td>    
                     {/each}