diff --git a/src/lib/components/Course/components/People/utils.ts b/src/lib/components/Course/components/People/utils.ts
index 58240efa..5b2e9f39 100644
--- a/src/lib/components/Course/components/People/utils.ts
+++ b/src/lib/components/Course/components/People/utils.ts
@@ -11,7 +11,7 @@ export async function sendTeacherCourseWelcome(params: {
const accessToken = data.session?.access_token || '';
try {
- const response = await fetch('/api/email/course/welcome', {
+ const response = await fetch('/api/email/course/teacher_welcome', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
diff --git a/src/routes/api/email/course/student_welcome/+server.js b/src/routes/api/email/course/student_welcome/+server.js
new file mode 100644
index 00000000..0deb5ef4
--- /dev/null
+++ b/src/routes/api/email/course/student_welcome/+server.js
@@ -0,0 +1,51 @@
+import { render } from 'svelte-email';
+import { json } from '@sveltejs/kit';
+import WelcomeTemplate from './template.svelte';
+import { getSendgrid, SENDGRID_FROM_NOTIFY } from '$lib/utils/services/sendgrid';
+import { getSupabase } from '$lib/utils/functions/supabase';
+
+const sendgrid = getSendgrid();
+const supabase = getSupabase();
+
+// Sends email to student when they successfully join a course
+export async function POST({ request }) {
+ const { to, orgName, courseName } = await request.json();
+ const accessToken = request.headers.get('Authorization') || '';
+ console.log('/POST api/email/course/student_welcome', to, orgName);
+
+ if (!to || !orgName || !courseName) {
+ return json({ success: false, message: 'Missing required fields' }, { status: 400 });
+ }
+
+ let user;
+ try {
+ const { data } = await supabase.auth.getUser(accessToken);
+ user = data.user;
+ } catch (error) {
+ console.error(error);
+ }
+
+ if (!user) {
+ return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
+ }
+
+ const options = {
+ from: SENDGRID_FROM_NOTIFY,
+ to,
+ subject: `[${orgName}] Welcome to Class`,
+ html: render({
+ template: WelcomeTemplate,
+ props: {
+ orgName,
+ courseName
+ }
+ })
+ };
+
+ sendgrid.send(options);
+
+ return json({
+ success: true,
+ message: 'Email sent'
+ });
+}
diff --git a/src/routes/api/email/course/student_welcome/template.svelte b/src/routes/api/email/course/student_welcome/template.svelte
new file mode 100644
index 00000000..7b63c5f3
--- /dev/null
+++ b/src/routes/api/email/course/student_welcome/template.svelte
@@ -0,0 +1,15 @@
+
+
+
diff --git a/src/routes/api/email/course/student_welcome/welcome.svelte b/src/routes/api/email/course/student_welcome/welcome.svelte
new file mode 100644
index 00000000..682838ef
--- /dev/null
+++ b/src/routes/api/email/course/student_welcome/welcome.svelte
@@ -0,0 +1,37 @@
+
+
+Hey there,
+
+ Congratulations, you’ve successfully joined “{courseName}"
+
+
+ Everything has been set up for you to have an amazing learning experience.
+
+
+ If you run into any issues, don’t fail to reach out to your instructor(s).
+
+Cheers,
+{orgName}
diff --git a/src/routes/api/email/course/teacher_student_joined/+server.js b/src/routes/api/email/course/teacher_student_joined/+server.js
new file mode 100644
index 00000000..47cc09f7
--- /dev/null
+++ b/src/routes/api/email/course/teacher_student_joined/+server.js
@@ -0,0 +1,49 @@
+import { render } from 'svelte-email';
+import { json } from '@sveltejs/kit';
+import WelcomeTemplate from './template.svelte';
+import { getSendgrid, SENDGRID_FROM_NOTIFY } from '$lib/utils/services/sendgrid';
+import { getSupabase } from '$lib/utils/functions/supabase';
+
+const sendgrid = getSendgrid();
+const supabase = getSupabase();
+
+export async function POST({ request }) {
+ const { to, courseName } = await request.json();
+ const accessToken = request.headers.get('Authorization') || '';
+ console.log('/POST api/email/course/teacher_student_joined', to, courseName);
+
+ if (!to || !courseName) {
+ return json({ success: false, message: 'Missing required fields' }, { status: 400 });
+ }
+
+ let user;
+ try {
+ const { data } = await supabase.auth.getUser(accessToken);
+ user = data.user;
+ } catch (error) {
+ console.error(error);
+ }
+
+ if (!user) {
+ return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
+ }
+
+ const options = {
+ from: SENDGRID_FROM_NOTIFY,
+ to,
+ subject: `[${courseName}] You've got a new student!`,
+ html: render({
+ template: WelcomeTemplate,
+ props: {
+ courseName
+ }
+ })
+ };
+
+ sendgrid.send(options);
+
+ return json({
+ success: true,
+ message: 'Email sent'
+ });
+}
diff --git a/src/routes/api/email/course/teacher_student_joined/template.svelte b/src/routes/api/email/course/teacher_student_joined/template.svelte
new file mode 100644
index 00000000..1b981877
--- /dev/null
+++ b/src/routes/api/email/course/teacher_student_joined/template.svelte
@@ -0,0 +1,13 @@
+
+
+
diff --git a/src/routes/api/email/course/teacher_student_joined/welcome.svelte b/src/routes/api/email/course/teacher_student_joined/welcome.svelte
new file mode 100644
index 00000000..f27db4ba
--- /dev/null
+++ b/src/routes/api/email/course/teacher_student_joined/welcome.svelte
@@ -0,0 +1,44 @@
+
+
+Hi amazing tutor,
+
+ Congratulations, a new student has joined a course you are teaching: “{courseName}""
+
+
+ We hope they have a great experience learning from the best (YOU).
+
+
+ If you run into any issues, please don’t fail to reach out to us, we’d love to make your teaching
+ experience as easy as possible.
+
+
+Cheers
+
+ ClassroomIO
+
diff --git a/src/routes/api/email/course/welcome/+server.js b/src/routes/api/email/course/teacher_welcome/+server.js
similarity index 94%
rename from src/routes/api/email/course/welcome/+server.js
rename to src/routes/api/email/course/teacher_welcome/+server.js
index cce9d134..6ed86ed0 100644
--- a/src/routes/api/email/course/welcome/+server.js
+++ b/src/routes/api/email/course/teacher_welcome/+server.js
@@ -10,7 +10,7 @@ const supabase = getSupabase();
export async function POST({ request }) {
const { to, name, orgName, courseName, orgSiteName } = await request.json();
const accessToken = request.headers.get('Authorization') || '';
- console.log('/POST api/email/course/welcome', to, name, orgName);
+ console.log('/POST api/email/course/teacher_welcome', to, name, orgName);
if (!to || !name || !orgName || !courseName || !orgSiteName) {
return json({ success: false, message: 'Missing required fields' }, { status: 400 });
diff --git a/src/routes/api/email/course/welcome/template.svelte b/src/routes/api/email/course/teacher_welcome/template.svelte
similarity index 100%
rename from src/routes/api/email/course/welcome/template.svelte
rename to src/routes/api/email/course/teacher_welcome/template.svelte
diff --git a/src/routes/api/email/course/welcome/welcome.svelte b/src/routes/api/email/course/teacher_welcome/welcome.svelte
similarity index 100%
rename from src/routes/api/email/course/welcome/welcome.svelte
rename to src/routes/api/email/course/teacher_welcome/welcome.svelte
diff --git a/src/routes/invite/s/[hash]/+page.svelte b/src/routes/invite/s/[hash]/+page.svelte
index 18f29853..0318682b 100644
--- a/src/routes/invite/s/[hash]/+page.svelte
+++ b/src/routes/invite/s/[hash]/+page.svelte
@@ -10,6 +10,7 @@
import type { CurrentOrg } from '$lib/utils/types/org.js';
import { ROLE } from '$lib/utils/constants/roles';
import { profile } from '$lib/utils/store/user.js';
+ import { sendStudentCourseWelcome, sendTeacherStudentJoinedCourse } from './utils';
export let data;
@@ -27,6 +28,18 @@
group_id: data.groupId,
role_id: ROLE.STUDENT
};
+
+ const teacherMembers = await supabase
+ .from('groupmember')
+ .select('id, profile(email)')
+ .eq('group_id', data.groupId)
+ .eq('role_id', ROLE.TUTOR);
+
+ const teachers: Array =
+ teacherMembers.data?.map((teacher) => {
+ return teacher.profile?.email || '';
+ }) || [];
+
addGroupMember(member).then((addedMember) => {
loading = false;
if (addedMember.error) {
@@ -34,8 +47,19 @@
return;
}
+ // Send email welcoming student to the course
+ sendStudentCourseWelcome({
+ to: $profile.email,
+ orgName: data.currentOrg?.name,
+ courseName: data.name
+ });
+
// Send notification to teacher(s) that a student has joined the course.
- // also send welcome email to students when they join the course
+ sendTeacherStudentJoinedCourse({
+ to: teachers,
+ courseName: data.name
+ });
+
// go to lms
return goto('/lms');
});
@@ -46,7 +70,7 @@
currentOrg.set(cOrg);
}
- onMount(() => {
+ onMount(async () => {
setTheme(data.currentOrg?.theme || '');
});
diff --git a/src/routes/invite/s/[hash]/utils.ts b/src/routes/invite/s/[hash]/utils.ts
new file mode 100644
index 00000000..dfbc3f1a
--- /dev/null
+++ b/src/routes/invite/s/[hash]/utils.ts
@@ -0,0 +1,56 @@
+import { supabase } from '$lib/utils/functions/supabase';
+
+export async function sendStudentCourseWelcome(params: {
+ to: string;
+ orgName: string;
+ courseName: string;
+}) {
+ const { data } = await supabase.auth.getSession();
+ const accessToken = data.session?.access_token || '';
+
+ try {
+ const response = await fetch('/api/email/course/student_welcome', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: accessToken
+ },
+ body: JSON.stringify(params)
+ });
+ if (!response.ok) {
+ throw new Error(await response.text());
+ }
+ const result = await response.json();
+
+ console.log('Sent invite email', result);
+ } catch (error) {
+ console.error('Error sending invite email', error);
+ }
+}
+
+export async function sendTeacherStudentJoinedCourse(params: {
+ to: Array;
+ courseName: string;
+}) {
+ const { data } = await supabase.auth.getSession();
+ const accessToken = data.session?.access_token || '';
+
+ try {
+ const response = await fetch('/api/email/course/teacher_student_joined', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: accessToken
+ },
+ body: JSON.stringify(params)
+ });
+ if (!response.ok) {
+ throw new Error(await response.text());
+ }
+ const result = await response.json();
+
+ console.log('Sent invite email', result);
+ } catch (error) {
+ console.error('Error sending invite email', error);
+ }
+}
diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte
index 5882ce77..ee1a63b7 100644
--- a/src/routes/login/+page.svelte
+++ b/src/routes/login/+page.svelte
@@ -1,4 +1,5 @@