feat: 🚀 😃 convert repo into a monorepo 🚀 😃 (#51)

* Merge main into turbo-monrepo

* feat: rename apps

* feat: remove supbase videos and serve all from project

* feat: move supabase to root

* feat: update README

* docs: update link
This commit is contained in:
Rotimi Best
2023-11-25 21:56:02 +00:00
committed by GitHub
parent 03ca379094
commit 41e29014ef
806 changed files with 85853 additions and 5746 deletions
@@ -0,0 +1,43 @@
import { Configuration, OpenAIApi } from 'openai-edge';
import { OpenAIStream, StreamingTextResponse } from 'ai';
import { OPENAI_API_KEY } from '$env/static/private';
// Create an OpenAI API client (that's edge friendly!)
const openAIConfig = new Configuration({
apiKey: OPENAI_API_KEY
});
const openai = new OpenAIApi(openAIConfig);
// Set the runtime to edge for best performance
export const config = {
runtime: 'edge'
};
const instruction = {
outline: 'a structured lesson outline',
note: 'a sample lesson note',
activities: 'few interactive lesson activities to my lecture'
};
export async function POST({ request }) {
const { prompt } = await request.json();
const { courseTitle, lessonTitle, type } = JSON.parse(prompt);
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content: 'Act like an assistant of a lecturer'
},
{
role: 'user',
content: `Generate ${instruction[type]} given the course title is "${courseTitle}" and the title of the lesson is "${lessonTitle}". Format in HTML without any styling. MOST IMPORTANT DON'T include the title of the course and don't include the lesson title: "${lessonTitle}" in your output. Please make sure the content is well detailed.`
}
],
stream: true
});
// Convert the response into a friendly text-stream
const stream = OpenAIStream(response);
// Respond with the stream
return new StreamingTextResponse(stream);
}
@@ -0,0 +1,37 @@
import { Configuration, OpenAIApi } from 'openai-edge';
import { OpenAIStream, StreamingTextResponse } from 'ai';
import { OPENAI_API_KEY } from '$env/static/private';
// Create an OpenAI API client (that's edge friendly!)
const openAIConfig = new Configuration({
apiKey: OPENAI_API_KEY
});
const openai = new OpenAIApi(openAIConfig);
// Set the runtime to edge for best performance
export const config = {
runtime: 'edge'
};
export async function POST({ request }) {
const { prompt } = await request.json();
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content: 'Act like an assistant of a lecturer or an educator'
},
{
role: 'user',
content: `${prompt}. DONT ADD ANY CSS STYLE TO THE HTML FORMATTING AND DON'T USE CODE HTML TAG`
}
],
stream: true
});
// Convert the response into a friendly text-stream
const stream = OpenAIStream(response);
// Respond with the stream
return new StreamingTextResponse(stream);
}
@@ -0,0 +1,81 @@
import { Configuration, OpenAIApi } from 'openai-edge';
import { OpenAIStream, StreamingTextResponse } from 'ai';
import { OPENAI_API_KEY } from '$env/static/private';
// Create an OpenAI API client (that's edge friendly!)
const openAIConfig = new Configuration({
apiKey: OPENAI_API_KEY
});
const openai = new OpenAIApi(openAIConfig);
// Set the runtime to edge for best performance
export const config = {
runtime: 'edge'
};
export async function POST({ request }) {
const { prompt } = await request.json();
const { questionNumber, optionNumber, lessonNote } = JSON.parse(prompt);
const refinedPrompt = `
Please note this typescript interface:
interface Question_type {
id: number;
label: any;
}
const QuestionTypes: Question_type[] = [
{
id: 1,
label: 'RADIO'
},
{
id: 2,
label: 'CHECKBOX'
},
{
id: 3,
label: 'TEXTAREA'
}
];
interface ExerciseTemplate {
title: string;
description: string;
questionnaire: {
questions: {
title: string;
name: string;
points: number; // a number out of 10 to score the student if student gets the correct answer
order: number; // a unique number from 0 to n+1, that orders the question in ascending order
question_type: Question_type;
options: {
label: string;
is_correct: boolean;
};
}[]
};
}
I am a teacher and I need your help evaluating my students after I have taught a lesson. Please generate a test with ${questionNumber} questions and ${optionNumber} options. The sourse of this test should come from my lesson note in thripple quotes: """${lessonNote}""". Format the quiz to match the ExerciseTemplate interface above and VERY IMPORTANTANTLY: ONLY RETURN JSON FORMAT AND DO NOT EXPLAIN ANTHING.
NB: Ask a mixture of ${optionNumber} options and ${questionNumber} DIFFERENT Question Types(RADIO, CHECKBOX AND TEXTAREA), mark the correct answer.`;
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content: 'You only spit out JSON and nothing else, dont give any explanation.'
},
{
role: 'user',
content: refinedPrompt
}
],
stream: true
});
// Convert the response into a friendly text-stream
const stream = OpenAIStream(response);
// Respond with the stream
return new StreamingTextResponse(stream);
}
@@ -0,0 +1,38 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
const supabase = getSupabase();
export async function POST({ request }) {
const { to, content, orgName, exerciseTitle } = await request.json();
const accessToken = request.headers.get('Authorization') || '';
if (!to || !content || !orgName) {
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 });
}
await sendEmail({
from: `"${orgName} (via ClassroomIO.com)" <[email protected]>`,
to,
subject: `[Submitted]: ${exerciseTitle}`,
content
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,53 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
const supabase = getSupabase();
export async function POST({ request }) {
const { to, courseName, teacherEmail, studentFullname, orgName } = await request.json();
const accessToken = request.headers.get('Authorization') || '';
console.log(
'/POST api/email/course/student_prove_payment',
to,
courseName,
teacherEmail,
studentFullname,
orgName
);
if (!to || !courseName || !teacherEmail || !studentFullname || !orgName) {
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 });
}
await sendEmail({
from: `"${orgName} - ClassroomIO" <[email protected]>`,
to,
replyTo: teacherEmail,
subject: `[${courseName}] One more step left`,
content: `
<p>Hi ${studentFullname},</p>
<p>You are one step closer to joining: ${courseName}</p>
<p>Please send your proof of payment to: ${teacherEmail}, in order to join the course.</p>
<p>Talk to you soon and see you in class.</p>
<p>${orgName}</p>
`
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,47 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
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 });
}
await sendEmail({
from: `"${orgName} (via ClassroomIO.com)" <[email protected]>`,
to,
subject: `${orgName} - Welcome to Class 🎉`,
content: `
<p>Hi there,</p>
<p>Congratulations 🎉, you’ve successfully joined: <strong>${courseName}</strong></p>
<p>Everything has been set up for you to have an amazing learning experience.</p>
<p>If you run into any issues, don’t fail to reach out to your instructor(s).</p>
<p>Cheers,</p>
<p>${orgName}</p>
`
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,38 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
const supabase = getSupabase();
export async function POST({ request }) {
const { to, content, orgName } = await request.json();
const accessToken = request.headers.get('Authorization') || '';
if (!to || !content || !orgName) {
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 });
}
await sendEmail({
from: `"${orgName} (via ClassroomIO.com)" <[email protected]>`,
to,
subject: 'Submission Update',
content
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,53 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
const supabase = getSupabase();
export async function POST({ request }) {
const { to, courseName, studentEmail, studentFullname } = await request.json();
const accessToken = request.headers.get('Authorization') || '';
console.log(
'/POST api/email/course/teacher_student_buycourse',
to,
courseName,
studentEmail,
studentFullname
);
if (!to || !courseName || !studentEmail || !studentFullname) {
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 });
}
await sendEmail({
from: `ClassroomIO" <[email protected]>`,
to,
subject: `[${courseName}] Request to Join Course!`,
content: `
<p>Hi amazing tutor,</p>
<p> A new student has requested to join a course you are teaching: “${courseName}"</p>
<p style="font: bold;">Student details</p>
<p>
Name: ${studentFullname}<br />
Email: ${studentEmail}
</p>
`
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,45 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
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 });
}
await sendEmail({
from: `"ClassroomIO" <[email protected]>`,
to,
subject: `[${courseName}] You've got a new student 🎉!`,
content: `
<p>Hi amazing tutor,</p>
<p>Congratulations 🎉, a new student has joined a course you are teaching: ${courseName}</p>
<p>We hope they have a great experience learning from the best (YOU).</p>
<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>
`
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,49 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
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/teacher_welcome', to, name, orgName);
if (!to || !name || !orgName || !courseName || !orgSiteName) {
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 origin = request.headers.get('origin');
const inviteLink = `${origin}/org/${orgSiteName}/courses`;
await sendEmail({
from: `"${orgName} (via ClassroomIO.com)" <[email protected]>`,
to,
subject: `You have been invited to a course in ${orgName}!`,
content: `
<p>Hey ${name},</p>
<p> You have been given access to teach a course by ${orgName}</p>
<p>The course is titled: ${courseName}</p>
<div>
<a class="button" href="${inviteLink}">Open Dashboard</a>
</div>
`
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,62 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
const supabase = getSupabase();
// API to send invite to teacher
export async function POST({ request }) {
const body = await request.json();
const { org, email } = body;
const accessToken = request.headers.get('Authorization');
console.log('/POST api/email/invite', body);
if (!org || !Object.keys(org).length || !email) {
return json(
{ success: false, message: 'Org data and Teacher name are required' },
{ 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 { id, name, siteName } = org;
const origin = request.headers.get('origin');
const inviteData = JSON.stringify({
email,
orgId: id,
orgSiteName: siteName
});
const inviteLink = `${origin}/invite/t/${encodeURIComponent(btoa(inviteData))}`;
console.log('inviteData', inviteData);
await sendEmail({
to: email,
subject: `Join ${name} on ClassroomIO 😃`,
content: `
<p>Hey there,</p>
<p> You have been invited to join ${name} on ClassroomIO 🎉🎉🎉.</p>
<div>
<a class="button" href="${inviteLink}">Accept Invitation</a>
</div>
`,
isPersonalEmail: true
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,57 @@
import { json } from '@sveltejs/kit';
import { getSupabase } from '$lib/utils/functions/supabase';
import { sendEmail } from '$lib/utils/services/notification/send';
const supabase = getSupabase();
export async function POST({ request }) {
const { to, name } = await request.json();
const accessToken = request.headers.get('Authorization');
console.log('/POST api/email/welcome', to, name);
if (!to || !name) {
return json({ success: false, message: 'Name and To are 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 });
}
await sendEmail({
to,
subject: 'Thank you so so so much for choosing ClassroomIO!',
content: `
<p>Dear ${name},</p>
<p>My name is Best the CEO of ClassroomIO and I will personally like to welcome to the vibrant community of ClassroomIO!</p>
<p>
We're thrilled to have you join us in shaping the future of education. Your decision to embark on
this journey with us is deeply appreciated, and we're genuinely excited about the possibilities
that lie ahead.
</p>
<p>
Once again, welcome to the ClassroomIO family. We're here to help, to listen, and to celebrate
your successes. Get ready to unlock a world of possibilities in education!
</p>
<p>
If you have any question or face any issues just send me an email [email protected] 😃
</p>
<div>
<a href="https://app.classroomio.com">Go to Dashboard</a>
</div>
`,
isPersonalEmail: true
});
return json({
success: true,
message: 'Email sent'
});
}
@@ -0,0 +1,24 @@
import { json } from '@sveltejs/kit';
const downloadTranscript = async () => {};
const uploadTranscriptToS3 = async () => {};
export async function GET({ url }) {
const museFid = url.searchParams.get('museFid');
console.log('museFid');
// check the transcript table and see if we find a record
// if we find one
// check if downloaded = true
// if true
// return the transcript
// if false
// download the transcript from muse
// upload it to S3
// return the transcript
// if we dont
return json({ success: true, museFid });
}
@@ -0,0 +1,36 @@
import { json } from '@sveltejs/kit';
import { UNSPLASH_API_KEY } from '$env/static/private';
const UNSPLASH_API_URL = `https://api.unsplash.com/search/photos?page=2&per_page=15&auto=format&fit=crop&w=2970&q=80&client_id=${UNSPLASH_API_KEY}`;
// API to fetch photos from Unsplash
export async function POST({ request }) {
const body = await request.json();
const { searchQuery } = body;
const query = searchQuery || 'rocks';
try {
const response = await fetch(`${UNSPLASH_API_URL}&query=${encodeURIComponent(query)}`, {
method: 'GET'
});
if (!response.ok) {
throw new Error('Unable to fetch photos from Unsplash API');
}
const data = await response.json();
return json({
success: true,
photos: data.results
});
} catch (error) {
console.error(error);
return json(
{ success: false, message: 'Error fetching photos from Unsplash' },
{ status: 500 }
);
}
}