feat: course news feed (#136)
* style: Improved font size of the answers in the FAQ section of the landing page * woking on the anouncement page * working on the anouncement feature * fixed some bugs in the emoji and comment * minor cleanup * Delete .github/workflows/test-pull-request.yml This commit was stashed but it seems i accidentally applied on this commit * updated the navicon for the anouncement * added role level security * still working on the emoji click * everything works now * cleaned up the code * cleaned up the code * cleaned up the code * cleaned up the code * refined the formatTime function using dayjs * refined the formatTime function using dayjs * typed,the code,created a migration file * increase editor width/height * added the confirmation modal and also the edit functionality for a improve UX * some cleanup * handle edge case,only tutor or admin can edit or delete * improved the fetchNews function and also added role level access for deleting the comment * chore: refactor code * clean up * feat: add pinned feed * feat: remove overview on sidebar * fix formatting of todo * feat: prevent async block when sending email * feat: notify teacher and student of new post/comment * refactoring --------- Co-authored-by: Rotimi Best <[email protected]> Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
Rotimi Best
parent
474e83c3d9
commit
5cdb74a6b5
@@ -24,12 +24,12 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <notify@classroomio.com>`,
|
||||
to,
|
||||
subject: `[Submitted]: ${exerciseTitle}`,
|
||||
content
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import { sendEmail } from '$lib/utils/services/notification/send';
|
||||
import { getFeedForNotification } from '$lib/utils/services/newsfeed/index';
|
||||
|
||||
const supabase = getSupabase();
|
||||
|
||||
const sendEmailNotification = async (feedId: string, authorId: string, comment?: string) => {
|
||||
const feed = await getFeedForNotification(feedId, authorId);
|
||||
|
||||
if (!feed) return;
|
||||
|
||||
const postLink = `https://${feed.org.siteName}.classroomio.com/courses/${feed.courseId}?feedId=${feed.id}`;
|
||||
|
||||
if (comment) {
|
||||
// send only to teacher
|
||||
sendEmail({
|
||||
from: `"${feed.org.name} - ClassroomIO" <[email protected]>`,
|
||||
to: feed.teacherEmail,
|
||||
subject: `[${feed.courseTitle}] - News feed comment`,
|
||||
content: `
|
||||
<p>A student left you a comment on your newsfeed post</p>
|
||||
|
||||
<div style="font-style: italic; margin-top: 10px;">${comment}</div>
|
||||
<div>
|
||||
<a class="button" href="${postLink}">View comment</a>
|
||||
</div>
|
||||
`
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
// dont continue
|
||||
return;
|
||||
}
|
||||
|
||||
// else send to everyone except the author of the post
|
||||
Promise.all(
|
||||
feed.courseMembers.map((member) => {
|
||||
return sendEmail({
|
||||
from: `"${feed.org.name} - ClassroomIO" <[email protected]>`,
|
||||
to: member.email,
|
||||
replyTo: feed.teacherEmail,
|
||||
subject: `[${feed.courseTitle}] - New post in course`,
|
||||
content: `
|
||||
<p>${feed.teacherName} made a post in a course you are taking: ${feed.courseTitle}.</p>
|
||||
|
||||
<div style="font-style: italic; margin-top: 10px;">${feed.content}</div>
|
||||
<div>
|
||||
<a class="button" href="${postLink}">View post</a>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
})
|
||||
).then((emails) => console.log(`Sent emails to ${emails.length} students`));
|
||||
};
|
||||
|
||||
export async function POST({ request }) {
|
||||
const { authorId, feedId, comment } = await request.json();
|
||||
const accessToken = request.headers.get('Authorization') || '';
|
||||
console.log('/POST api/email/course/newsfeed');
|
||||
|
||||
if (!authorId || !feedId || !accessToken) {
|
||||
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 });
|
||||
}
|
||||
|
||||
sendEmailNotification(feedId, authorId, comment);
|
||||
// TODO: Support sending to other platforms like telegram and discord
|
||||
// sendDiscordNotification(); sendTelegramNotification();
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
message: 'Email sent'
|
||||
});
|
||||
}
|
||||
@@ -32,8 +32,8 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
from: `"${orgName} - ClassroomIO" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `"${orgName} - ClassroomIO" <notify@classroomio.com>`,
|
||||
to,
|
||||
replyTo: teacherEmail,
|
||||
subject: `[${courseName}] One more step left`,
|
||||
@@ -44,7 +44,7 @@ export async function POST({ request }) {
|
||||
<p>Talk to you soon and see you in class.</p>
|
||||
<p>${orgName}</p>
|
||||
`
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -26,8 +26,8 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <notify@classroomio.com>`,
|
||||
to,
|
||||
subject: `${orgName} - Welcome to Class 🎉`,
|
||||
content: `
|
||||
@@ -38,7 +38,7 @@ export async function POST({ request }) {
|
||||
<p>Cheers,</p>
|
||||
<p>${orgName}</p>
|
||||
`
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -24,12 +24,12 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <notify@classroomio.com>`,
|
||||
to,
|
||||
subject: 'Submission Update',
|
||||
content
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -31,8 +31,8 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
from: `ClassroomIO" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `ClassroomIO" <notify@classroomio.com>`,
|
||||
to,
|
||||
subject: `[${courseName}] Request to Join Course!`,
|
||||
content: `
|
||||
@@ -44,7 +44,7 @@ export async function POST({ request }) {
|
||||
Email: ${studentEmail}
|
||||
</p>
|
||||
`
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -25,8 +25,8 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
from: `"ClassroomIO" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `"ClassroomIO" <notify@classroomio.com>`,
|
||||
to,
|
||||
subject: `[${courseName}] You've got a new student 🎉!`,
|
||||
content: `
|
||||
@@ -36,7 +36,7 @@ export async function POST({ request }) {
|
||||
<p>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.</p>
|
||||
`
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -28,8 +28,8 @@ export async function POST({ request }) {
|
||||
const origin = request.headers.get('origin');
|
||||
const inviteLink = `${origin}/org/${orgSiteName}/courses`;
|
||||
|
||||
await sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <help@classroomio.com>`,
|
||||
sendEmail({
|
||||
from: `"${orgName} (via ClassroomIO.com)" <notify@classroomio.com>`,
|
||||
to,
|
||||
subject: `You have been invited to a course in ${orgName}!`,
|
||||
content: `
|
||||
@@ -40,7 +40,7 @@ export async function POST({ request }) {
|
||||
<a class="button" href="${inviteLink}">Open Dashboard</a>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -12,7 +12,7 @@ export async function POST({ request }) {
|
||||
const accessToken = request.headers.get('Authorization');
|
||||
console.log('/POST api/email/invite', body);
|
||||
|
||||
if (!org || !Object.keys(org).length || !email) {
|
||||
if (!org || !Object.keys(org).length || !email || !accessToken) {
|
||||
return json(
|
||||
{ success: false, message: 'Org data and Teacher name are required' },
|
||||
{ status: 400 }
|
||||
@@ -42,7 +42,7 @@ export async function POST({ request }) {
|
||||
const inviteLink = `${origin}/invite/t/${encodeURIComponent(btoa(inviteData))}`;
|
||||
console.log('inviteData', inviteData);
|
||||
|
||||
await sendEmail({
|
||||
sendEmail({
|
||||
to: email,
|
||||
subject: `Join ${name} on ClassroomIO 😃`,
|
||||
content: `
|
||||
@@ -53,7 +53,7 @@ export async function POST({ request }) {
|
||||
</div>
|
||||
`,
|
||||
isPersonalEmail: true
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
@@ -9,7 +9,7 @@ export async function POST({ request }) {
|
||||
const accessToken = request.headers.get('Authorization');
|
||||
console.log('/POST api/email/welcome', to, name);
|
||||
|
||||
if (!to || !name) {
|
||||
if (!to || !name || !accessToken) {
|
||||
return json({ success: false, message: 'Name and To are required fields' }, { status: 400 });
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function POST({ request }) {
|
||||
return json({ success: false, message: 'Unauthenticated user' }, { status: 401 });
|
||||
}
|
||||
|
||||
await sendEmail({
|
||||
sendEmail({
|
||||
to,
|
||||
subject: 'Thank you so so so much for choosing ClassroomIO!',
|
||||
content: `
|
||||
@@ -48,7 +48,7 @@ export async function POST({ request }) {
|
||||
</div>
|
||||
`,
|
||||
isPersonalEmail: true
|
||||
});
|
||||
}).then((info) => console.log('Email sent:', info));
|
||||
|
||||
return json({
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user