|
|
@@ -1,59 +1,150 @@
|
|
|
<script lang="ts">
|
|
|
- import { api_host, authToken } from "$lib";
|
|
|
- import type { Appointment } from "$lib/dbdata";
|
|
|
- import { onMount } from "svelte";
|
|
|
-
|
|
|
- let appointmentData: Appointment[] = [];
|
|
|
- let ready: boolean = false;
|
|
|
-
|
|
|
- async function fetchAppointments() {
|
|
|
- try {
|
|
|
- const response = await fetch(`${api_host}/api/users/appointments`, {
|
|
|
- method: "GET",
|
|
|
- headers: {
|
|
|
- "Authorization": "Bearer " + $authToken
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- if (!response.ok) {
|
|
|
- throw new Error(`HTTP error! Status: ${response.status}`);
|
|
|
- }
|
|
|
+ import { goto } from '$app/navigation';
|
|
|
+ import { api_host, authToken } from '$lib';
|
|
|
+ import type { Appointment } from '$lib/dbdata';
|
|
|
+ import { isDueDatePassed } from '$lib/funcs';
|
|
|
+ import { onMount } from 'svelte';
|
|
|
+
|
|
|
+ let appointmentData: Appointment[] = [];
|
|
|
+ let ready: boolean = false;
|
|
|
+ let errorMessage: string = '';
|
|
|
+ let actionCounter: number = 0;
|
|
|
+ let action: {action: string, id: string} = {action: '', id: ''};
|
|
|
+
|
|
|
+ async function fetchAppointments() {
|
|
|
+ try {
|
|
|
+ const response = await fetch(`${api_host}/api/users/appointments`, {
|
|
|
+ method: 'GET',
|
|
|
+ headers: {
|
|
|
+ Authorization: 'Bearer ' + $authToken
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ throw new Error(`HTTP error! Status: ${response.status}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ const data: Appointment[] = await response.json();
|
|
|
+ appointmentData = data;
|
|
|
+ console.log(appointmentData);
|
|
|
+ } catch (error) {
|
|
|
+ console.log('Error during fetch:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function copyShareLink(appointmentId: string) {
|
|
|
+ window.navigator.clipboard.writeText(
|
|
|
+ `${window.location.origin}/appointment?id=${appointmentId}`
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- const data: Appointment[] = await response.json();
|
|
|
- appointmentData = data;
|
|
|
- } catch (error) {
|
|
|
- console.log('Error during fetch:', error);
|
|
|
+ async function deleteEntry(appointmentId: string) {
|
|
|
+ manageAppointment(appointmentId, "DELETE", "delete");
|
|
|
+ }
|
|
|
+
|
|
|
+ async function lockAppointment(appointmentId: string) {
|
|
|
+ manageAppointment(appointmentId, "POST", "lock");
|
|
|
+ }
|
|
|
+
|
|
|
+ async function manageAppointment(appointmentId: string, method: 'DELETE' | 'POST', path: string) {
|
|
|
+ actionCounter += 1;
|
|
|
+ if (action.action !== method || action.id !== appointmentId) {
|
|
|
+ actionCounter = 1;
|
|
|
+ action = {action: method, id: appointmentId};
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
+ if (actionCounter !== 3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ actionCounter = 0;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await fetch(`${api_host}/api/users/${path}`, {
|
|
|
+ method: method,
|
|
|
+ headers: {
|
|
|
+ Authorization: 'Bearer ' + $authToken,
|
|
|
+ 'Content-Type': 'application/json'
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ appointmentId
|
|
|
+ })
|
|
|
+ });
|
|
|
|
|
|
- onMount(async () => {
|
|
|
- await fetchAppointments();
|
|
|
-
|
|
|
- ready = true;
|
|
|
- });
|
|
|
+ if (response.status === 404) {
|
|
|
+ console.log(`entry not found`);
|
|
|
+ errorMessage = `entry not found`;
|
|
|
+ await fetchAppointments();
|
|
|
+ setTimeout(() => errorMessage = "", 4000);
|
|
|
+ }
|
|
|
|
|
|
+ if (response.status === 200 && path === "delete") {
|
|
|
+ appointmentData = appointmentData.filter((element) => element._id !== appointmentId);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (response.status === 200 && path === "lock") {
|
|
|
+ await fetchAppointments();
|
|
|
+ errorMessage = "";
|
|
|
+
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log('Error during fetch:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function redirectEditCreator(appointmentId: string) {
|
|
|
+ goto(`/user/creator?${appointmentId}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ onMount(async () => {
|
|
|
+ await fetchAppointments();
|
|
|
+
|
|
|
+ ready = true;
|
|
|
+ });
|
|
|
</script>
|
|
|
|
|
|
{#each appointmentData as data}
|
|
|
- <tr>
|
|
|
- <td>{data.title}</td>
|
|
|
- <td class="center-align">14/21</td>
|
|
|
- <td class="center-align">
|
|
|
- <button class="medium">
|
|
|
- <span>Sperren</span>
|
|
|
- </button>
|
|
|
- </td>
|
|
|
- <td class="center-align">
|
|
|
- <button class="medium secondary">
|
|
|
+ <tr>
|
|
|
+ <td>{data.title}</td>
|
|
|
+ <td on:click={() => copyShareLink(data._id)} class="center-align">
|
|
|
+ <button class="medium cyan">
|
|
|
+ <span>Teilen</span>
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ {#if !isDueDatePassed(data.dueDate)}
|
|
|
+ <td on:click={() => lockAppointment(data._id)} class="center-align">
|
|
|
+ <button class="medium">
|
|
|
+ <span>Sperren</span>
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ {:else}
|
|
|
+ <td class="center-align">
|
|
|
+ <button class="medium secondary">
|
|
|
+ <span>Gesperrt</span>
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ {/if}
|
|
|
+
|
|
|
+ <!-- load into the creator -->
|
|
|
+ <td on:click={() => redirectEditCreator(data._id)} class="center-align">
|
|
|
+ <button class="medium secondary blue">
|
|
|
<span>Bearbeiten</span>
|
|
|
</button>
|
|
|
</td>
|
|
|
|
|
|
- <td class="center-align">
|
|
|
- <button class="medium red">
|
|
|
- <span>Loeschen</span>
|
|
|
- </button>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
-{/each}
|
|
|
+ <!-- send a delete request -->
|
|
|
+ <td on:click={() => deleteEntry(data._id)} class="center-align">
|
|
|
+ <button class="medium red">
|
|
|
+ <span>Loeschen</span>
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+{/each}
|
|
|
+
|
|
|
+{#if errorMessage.length > 0}
|
|
|
+ <div class="snackbar error active">{errorMessage}</div>
|
|
|
+{/if}
|
|
|
+
|
|
|
+{#if actionCounter > 0}
|
|
|
+ <div class="snackbar active">Click another two times to confirm</div>
|
|
|
+{/if}
|