From b7429a13250c2b6942f8627166323b56a24b9358 Mon Sep 17 00:00:00 2001 From: Ethan Seys Date: Tue, 12 Nov 2024 11:22:11 -0600 Subject: [PATCH 01/11] Added student rescheduling functionality --- src/lib/emails/AppointmentBooked.svelte | 9 ++- src/lib/emails/AppointmentBooked.txt | 2 +- src/lib/emails/appointment_booked.ts | 4 +- .../dash/sessions/[sessionId]/+page.svelte | 56 ++++++++++++++----- src/routes/(authed)/schedule/+page.server.ts | 28 +++++++--- src/routes/(authed)/schedule/+page.svelte | 4 +- 6 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/lib/emails/AppointmentBooked.svelte b/src/lib/emails/AppointmentBooked.svelte index cafb587..48e5f3c 100644 --- a/src/lib/emails/AppointmentBooked.svelte +++ b/src/lib/emails/AppointmentBooked.svelte @@ -2,11 +2,14 @@ import type { AppointmentBookedProps } from '$lib/emails/appointment_booked'; import { DateTime } from 'luxon'; - let { startTime, duration, mentorName, sessionId, type, timezone }: AppointmentBookedProps = + let { startTime, duration, mentorName, sessionId, type, timezone, reschedule }: AppointmentBookedProps = $props(); + + let reschedule_link = `https://scheddy.ztlartcc.org/sessions/${sessionId}`; + let title = reschedule ? 'Appointment updated' : 'Appointment booked'; -

Appointment booked!

+

{title}

This is your confirmation email for your upcoming session.

Session type: {type}

@@ -14,7 +17,7 @@

Timezone: {timezone}

Duration: {duration} minutes

Mentor: {mentorName}

-Please reach out to your mentor directly if you need to cancel or reschedule this lesson. +Cancel/Reschedule

---

diff --git a/src/lib/emails/AppointmentBooked.txt b/src/lib/emails/AppointmentBooked.txt index 69d9216..8b92e2b 100644 --- a/src/lib/emails/AppointmentBooked.txt +++ b/src/lib/emails/AppointmentBooked.txt @@ -8,7 +8,7 @@ This is your confirmation email for your upcoming session. -- Duration: {duration} minutes -- Mentor: {mentorName} -Please reach out to your mentor directly if you need to cancel or reschedule this lesson. +Cancel/Reschedule --- diff --git a/src/lib/emails/appointment_booked.ts b/src/lib/emails/appointment_booked.ts index 5fab21b..2c7607c 100644 --- a/src/lib/emails/appointment_booked.ts +++ b/src/lib/emails/appointment_booked.ts @@ -11,6 +11,7 @@ export interface AppointmentBookedProps { mentorName: string; sessionId: string; timezone: string; + reschedule?: boolean; } export function appointment_booked(props: AppointmentBookedProps): EmailContent { @@ -21,7 +22,8 @@ export function appointment_booked(props: AppointmentBookedProps): EmailContent duration: props.duration.toString(), mentorName: props.mentorName, sessionId: props.sessionId, - timezone: props.timezone + timezone: props.timezone, + reschedule: props.reschedule ? 'rescheduled' : '' }), html: render(AppointmentBooked, { props: props diff --git a/src/routes/(authed)/dash/sessions/[sessionId]/+page.svelte b/src/routes/(authed)/dash/sessions/[sessionId]/+page.svelte index a307db9..ecf9955 100644 --- a/src/routes/(authed)/dash/sessions/[sessionId]/+page.svelte +++ b/src/routes/(authed)/dash/sessions/[sessionId]/+page.svelte @@ -21,6 +21,18 @@ let hour: number = $state(0); let minute: number = $state(0); + function check_time(t: string) { + const start_time = DateTime.fromISO(t); + const now = DateTime.now(); + const interval = start_time.diff(now, 'hours'); + + if (interval.hours < 24) { + return false; + } else { + return true; + } + } + async function cancel() { await fetch('?/cancel', { method: 'POST', @@ -31,6 +43,19 @@ await goto('/dash'); await invalidateAll(); } + + function reschedule_helper() { + if (!data.isMentor) { + rescheduleOpen = true; + } else { + const queryParam = new URLSearchParams(); + queryParam.set('sessionId', data.sessionInfo.session.id); + queryParam.set('reschedule', 'true'); + queryParam.set('type', data.sessionInfo.sessionType.id); + goto(`/schedule?${queryParam.toString()}`); + } + } + async function reschedule() { let udata = new URLSearchParams(); @@ -91,8 +116,8 @@ {data.sessionInfo.sessionType.category} - {data.sessionInfo.sessionType.name}

Duration: {data.sessionInfo.sessionType.length} minutes

- {#if data.isMentor} -

Mentor/Staff Actions

+ {#if data.isMentor || check_time(data.sessionInfo.session.start)} +

Session Actions

+ {:else} +

+ You cannot cancel or reschedule this session as it is less than 24 hours away. Please contact + your instructor if you need to cancel or reschedule. +

{/if} -{#if data.isMentor} +{#if data.isMentor || check_time(data.sessionInfo.session.start)} { cancelOpen = false; @@ -127,13 +155,15 @@ }} title="Confirm cancellation" /> - -
-

- It is your responsibility to inform the student of the cancellation. -

-
-
+ {#if data.isMentor} + +
+

+ It is your responsibility to inform the student of the cancellation. +

+
+
+ {/if} - {:else} -

- You cannot cancel or reschedule this session as it is less than 24 hours away. Please contact - your instructor if you need to cancel or reschedule. -

{/if} -{#if data.isMentor || check_time(data.sessionInfo.session.start)} +{#if data.isMentor} { cancelOpen = false; @@ -151,15 +127,13 @@ }} title="Confirm cancellation" /> - {#if data.isMentor} - -
-

- It is your responsibility to inform the student of the cancellation. -

-
-
- {/if} + +
+

+ It is your responsibility to inform the student of the cancellation. +

+
+
+ {#if data.originalSessionType} + + {/if} {/if} {:else if step === 2} {#each Object.entries(categories) as [k, v]} @@ -159,16 +170,6 @@ > Next - {#if data.originalSessionType} - - {/if} {/if} {:else if step === 2} {#if sessionType} - {#each data.slotData[sessionType] as slot}