|
|
@@ -1,17 +1,50 @@
|
|
|
<script lang="ts">
|
|
|
- import { goto } from '$app/navigation';
|
|
|
import { api_host, authToken } from '$lib';
|
|
|
import type { Appointment } from '$lib/dbdata';
|
|
|
import { authFetch, isDueDatePassed } from '$lib/funcs';
|
|
|
import { t } from '$lib/translations';
|
|
|
import { onMount } from 'svelte';
|
|
|
|
|
|
+ /**
|
|
|
+ * An array of appointments fetched from the server.
|
|
|
+ *
|
|
|
+ * @type {Appointment[]}
|
|
|
+ */
|
|
|
let appointmentData: Appointment[] = [];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A flag indicating whether the component is ready to render.
|
|
|
+ *
|
|
|
+ * @type {boolean}
|
|
|
+ */
|
|
|
let ready: boolean = false;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * An error message that will be displayed if an error occurs while fetching appointments.
|
|
|
+ *
|
|
|
+ * @type {string}
|
|
|
+ */
|
|
|
let errorMessage: string = '';
|
|
|
- let actionCounter: number = 0;
|
|
|
- let action: {action: string, id: string} = {action: '', id: ''};
|
|
|
|
|
|
+ /**
|
|
|
+ * A counter tracking the number of actions performed on an appointment.
|
|
|
+ *
|
|
|
+ * @type {number}
|
|
|
+ */
|
|
|
+ let actionCounter: number = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * An object containing information about the current action being performed.
|
|
|
+ *
|
|
|
+ * @type {{action: 'DELETE' | 'POST', id: string}}
|
|
|
+ */
|
|
|
+ let action: { action: 'DELETE' | 'POST'; id: string } = { action: 'POST', id: '' };
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fetches appointments from the server and updates the local data.
|
|
|
+ *
|
|
|
+ * @async
|
|
|
+ */
|
|
|
async function fetchAppointments() {
|
|
|
try {
|
|
|
const response = await authFetch(`${api_host}/api/users/appointments`, {
|
|
|
@@ -29,32 +62,54 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Copies the share link for a given appointment ID to the clipboard.
|
|
|
+ *
|
|
|
+ * @param {string} appointmentId - The ID of the appointment to copy the link for.
|
|
|
+ */
|
|
|
function copyShareLink(appointmentId: string) {
|
|
|
window.navigator.clipboard.writeText(
|
|
|
`${window.location.origin}/appointment?id=${appointmentId}`
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Deletes an appointment from the server and updates the local data.
|
|
|
+ *
|
|
|
+ * @param {string} appointmentId - The ID of the appointment to delete.
|
|
|
+ */
|
|
|
async function deleteEntry(appointmentId: string) {
|
|
|
- manageAppointment(appointmentId, "DELETE", "delete");
|
|
|
+ manageAppointment(appointmentId, 'DELETE', 'delete');
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Locks an appointment on the server and updates the local data.
|
|
|
+ *
|
|
|
+ * @param {string} appointmentId - The ID of the appointment to lock.
|
|
|
+ */
|
|
|
async function lockAppointment(appointmentId: string) {
|
|
|
- manageAppointment(appointmentId, "POST", "lock");
|
|
|
+ manageAppointment(appointmentId, 'POST', 'lock');
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Manages an appointment by sending a request to the server.
|
|
|
+ *
|
|
|
+ * @param {string} appointmentId - The ID of the appointment to manage.
|
|
|
+ * @param {'DELETE' | 'POST'} method - The type of request to send (either DELETE or POST).
|
|
|
+ * @param {string} path - The path on the server to send the request to.
|
|
|
+ */
|
|
|
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};
|
|
|
- }
|
|
|
+ actionCounter += 1;
|
|
|
+ if (action.action !== method || action.id !== appointmentId) {
|
|
|
+ actionCounter = 1;
|
|
|
+ action = { action: method, id: appointmentId };
|
|
|
+ }
|
|
|
|
|
|
- if (actionCounter !== 3) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (actionCounter !== 3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- actionCounter = 0;
|
|
|
+ actionCounter = 0;
|
|
|
|
|
|
try {
|
|
|
const response = await fetch(`${api_host}/api/users/${path}`, {
|
|
|
@@ -70,29 +125,24 @@
|
|
|
|
|
|
if (response.status === 404) {
|
|
|
console.log(`entry not found`);
|
|
|
- errorMessage = $t("common.error-server");
|
|
|
+ errorMessage = $t('common.error-server');
|
|
|
await fetchAppointments();
|
|
|
- setTimeout(() => errorMessage = "", 4000);
|
|
|
+ setTimeout(() => (errorMessage = ''), 4000);
|
|
|
}
|
|
|
|
|
|
- if (response.status === 200 && path === "delete") {
|
|
|
+ if (response.status === 200 && path === 'delete') {
|
|
|
appointmentData = appointmentData.filter((element) => element._id !== appointmentId);
|
|
|
}
|
|
|
|
|
|
- if (response.status === 200 && path === "lock") {
|
|
|
+ if (response.status === 200 && path === 'lock') {
|
|
|
await fetchAppointments();
|
|
|
- errorMessage = "";
|
|
|
-
|
|
|
- }
|
|
|
+ errorMessage = '';
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
console.log('Error during fetch:', error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function redirectEditCreator(appointmentId: string) {
|
|
|
- goto(`/user/creator?${appointmentId}`);
|
|
|
- }
|
|
|
-
|
|
|
onMount(async () => {
|
|
|
await fetchAppointments();
|
|
|
|
|
|
@@ -103,41 +153,41 @@
|
|
|
{#each appointmentData as data}
|
|
|
<tr>
|
|
|
<td>{data.title}</td>
|
|
|
-
|
|
|
+
|
|
|
<td class="center-align">
|
|
|
<span>{data.participants}</span>
|
|
|
</td>
|
|
|
|
|
|
<td class="center-align">
|
|
|
<a href={`/appointment?id=${data._id}`} class="button medium cyan">
|
|
|
- <span>{$t("common.share")}</span>
|
|
|
+ <span>{$t('common.share')}</span>
|
|
|
</a>
|
|
|
</td>
|
|
|
- {#if !isDueDatePassed(data.dueDate)}
|
|
|
- <td on:click={() => lockAppointment(data._id)} class="center-align">
|
|
|
- <button class="medium">
|
|
|
- <span>{$t("common.lock")}</span>
|
|
|
- </button>
|
|
|
- </td>
|
|
|
- {:else}
|
|
|
- <td class="center-align">
|
|
|
- <button class="medium secondary">
|
|
|
- <span>{$t("common.locked")}</span>
|
|
|
- </button>
|
|
|
- </td>
|
|
|
- {/if}
|
|
|
-
|
|
|
+ {#if !isDueDatePassed(data.dueDate)}
|
|
|
+ <td on:click={() => lockAppointment(data._id)} class="center-align">
|
|
|
+ <button class="medium">
|
|
|
+ <span>{$t('common.lock')}</span>
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ {:else}
|
|
|
+ <td class="center-align">
|
|
|
+ <button class="medium secondary">
|
|
|
+ <span>{$t('common.locked')}</span>
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ {/if}
|
|
|
+
|
|
|
<!-- load into the creator -->
|
|
|
- <td class="center-align">
|
|
|
- <a href={`/user/creator?id=${data._id}`} class="button medium secondary blue">
|
|
|
- <span>{$t("common.edit")}</span>
|
|
|
+ <td class="center-align">
|
|
|
+ <a href={`/user/creator?id=${data._id}`} class="button medium secondary blue">
|
|
|
+ <span>{$t('common.edit')}</span>
|
|
|
</a>
|
|
|
- </td>
|
|
|
+ </td>
|
|
|
|
|
|
<!-- send a delete request -->
|
|
|
<td on:click={() => deleteEntry(data._id)} class="center-align">
|
|
|
<button class="medium red">
|
|
|
- <span>{$t("common.delete")}</span>
|
|
|
+ <span>{$t('common.delete')}</span>
|
|
|
</button>
|
|
|
</td>
|
|
|
</tr>
|
|
|
@@ -148,5 +198,5 @@
|
|
|
{/if}
|
|
|
|
|
|
{#if actionCounter > 0}
|
|
|
- <div class="snackbar active">{$t("common.action-confirm")}</div>
|
|
|
-{/if}
|
|
|
+ <div class="snackbar active">{$t('common.action-confirm')}</div>
|
|
|
+{/if}
|