[DONE] clone a course

This commit is contained in:
Rotimi Best
2021-12-30 22:30:30 +02:00
parent a1f6c5728b
commit 23c68c9d78
24 changed files with 834 additions and 195 deletions
+1 -1
View File
@@ -164,7 +164,7 @@
<main>
{#if $preloading && $delayedPreloading}
<Backdrop>
<Firework size="60" color="#fff" unit="px" duration="1s" />
<Firework size="60" color="#1d4ed8" unit="px" duration="1s" />
</Backdrop>
{/if}
{#if !['login', 'signup'].includes(path) && !isCoursePage(path)}
+11 -129
View File
@@ -19,93 +19,25 @@
<script>
import { onMount } from 'svelte';
// import { stores } from '@sapper/app';
import PageNav from '../components/PageNav/index.svelte';
import Courses from '../components/Courses/index.svelte';
import NewCourseModal from '../components/Courses/components/NewCourseModal/index.svelte';
import PrimaryButton from '../components/PrimaryButton/index.svelte';
import Modal from '../components/Modal/index.svelte';
import TextField from '../components/Form/TextField.svelte';
import TextArea from '../components/Form/TextArea.svelte';
import { courses, createCourseModal } from '../components/Courses/store';
import { validateForm } from '../components/Courses/functions';
import { ROLE } from '../utils/constants/roles';
import { addGroupMember } from '../utils/services/courses';
import { supabase } from '../utils/functions/supabase';
import {
courses,
createCourseModal,
courseMetaDeta,
} from '../components/Courses/store';
import { setProfileIdOfGroupMember } from '../utils/services/courses';
// const { page } = stores();
export let allCourses = [];
export let cantFetch;
let errors = {
emails: '',
};
// let tab = '';
async function createCourse(e) {
const { hasError, fieldErrors, students, tutors } =
validateForm($createCourseModal);
errors = fieldErrors;
if (hasError) return;
const { title, description } = $createCourseModal;
// Create group from course_id
const { data: newGroup } = await supabase
.from('group')
.insert({ name: title, description });
console.log(`newGroup`, newGroup);
const { id: group_id } = newGroup[0];
// Create course with group_id
const { data: newCourse } = await supabase.from('course').insert({
title,
description,
group_id,
});
console.log(`newCourse`, newCourse);
courses.update((_courses) => [..._courses, newCourse[0]]);
// Get profile of author and add as member
await addGroupMember({
profile_id: $profile.id,
email: $profile.email,
group_id,
role_id: ROLE.TUTOR,
});
let membersStack = [];
// Create groupmemebers from group_id and add teachers and students
for (const student of students) {
membersStack.push({
email: student,
group_id,
role_id: ROLE.STUDENT,
});
}
for (const tutor of tutors) {
membersStack.push({
email: tutor,
group_id,
role_id: ROLE.TUTOR,
});
}
addGroupMember(membersStack).then((membersAdded) => {
console.log(`membersAdded`, membersAdded);
$createCourseModal.open = false;
});
}
async function getCourses(userId) {
if (process.browser) {
if (cantFetch && typeof cantFetch === 'boolean' && !allCourses.length) {
$courseMetaDeta.isLoading = true;
const updatedProfile = await setProfileIdOfGroupMember(
$profile.email,
userId
@@ -114,6 +46,7 @@
const coursesResult = await fetchCourses(userId);
console.log(`coursesResult`, coursesResult);
$courseMetaDeta.isLoading = false;
if (!coursesResult) return;
// organizationId = coursesResult.organizationId;
@@ -122,7 +55,7 @@
}
}
onMount(async () => {
onMount(() => {
courses.set(allCourses);
});
@@ -145,58 +78,7 @@
</div>
</PageNav>
<Modal
onClose={() => ($createCourseModal.open = false)}
bind:open={$createCourseModal.open}
width="w-2/5"
modalHeading="Create a Course"
>
<form on:submit|preventDefault={createCourse}>
<TextField
label="Course name"
bind:value={$createCourseModal.title}
autofocus={true}
placeholder="Your course name"
className="mb-4"
isRequired={true}
errorMessage={errors.title}
autoComplete={false}
/>
<TextArea
label="Invite Tutors"
bind:value={$createCourseModal.tutors}
rows="2"
maxRows="3"
placeholder="tutor@company.com, john@gmail.com"
helperMessage="To invite people, add their emails separated by a comma"
errorMessage={errors.tutors}
className="mb-4"
/>
<TextArea
label="Invite Students"
bind:value={$createCourseModal.students}
rows="2"
maxRows="3"
placeholder="student@gmail.com, john@gmail.com"
helperMessage="To invite people, add their emails separated by a comma"
errorMessage={errors.students}
className="mb-4"
/>
<TextArea
label="Short description"
bind:value={$createCourseModal.description}
rows="4"
maxRows="4"
placeholder="A little description about this course"
className="mb-4"
isRequired={true}
/>
<div class="mt-5 flex items-center">
<PrimaryButton className="px-6 py-2" label="Finish" type="submit" />
</div>
</form>
</Modal>
<NewCourseModal />
<Courses />
</section>
@@ -44,12 +44,14 @@
let mode = MODES.view;
let prevMode;
let prevLessonId;
let isFetching = false;
const { page } = stores();
async function fetchReqData(lessonId) {
let lessonData;
isFetching = true;
let lessonData;
if (!$course.id) {
const [_course, lesson] = await Promise.all([
fetchCourse(courseId),
@@ -69,6 +71,7 @@
const totalExercises =
lessonData.totalExercises[0] && lessonData.totalExercises[0].count;
setLesson(lessonData, totalExercises);
isFetching = false;
}
function setLesson(lessonData, totalExercises) {
@@ -92,7 +95,11 @@
}
</script>
<CourseContainer {path} isExercisePage={!isMaterialsTabActive && exerciseId}>
<CourseContainer
{isFetching}
{path}
isExercisePage={!isMaterialsTabActive && exerciseId}
>
<PageNav
navItems={[
{
+5 -2
View File
@@ -18,7 +18,10 @@
group,
} from '../../../components/Course/store';
import { lessons } from '../../../components/Course/components/Lesson/store/lessons';
import { fetchCourse, fetchExercises } from '../../../utils/services/courses';
import {
fetchCourse,
fetchExercisesByMarks,
} from '../../../utils/services/courses';
import { getLectureNo } from '../../../components/Course/function';
import { fetchMarks } from '../../../utils/services/marks';
import { profile } from '../../../utils/store/user';
@@ -67,7 +70,7 @@
}
});
const { data: exercises } = await fetchExercises(courseId);
const { data: exercises } = await fetchExercisesByMarks(courseId);
// Map exercises to { lessonId: { exerciseId: exerciseTitle, ... }, ... }
exercises.forEach((exercise) => {
+3 -13
View File
@@ -64,7 +64,7 @@
data-atf="1"
/>
-->
<div>
<div>
<h3 class="text-4xl text-center">
Classroom<span class="text-blue-700">IO</span>
</h3>
@@ -87,18 +87,8 @@
isRequired={true}
isDisabled={isAdding}
/>
<PrimaryButton
type="submit"
variant={isAdding ? VARIANTS.OUTLINED : VARIANTS.CONTAINED}
className="py-2 w-full justify-center sm:w-auto {isAdding &&
'py-4 border-blue-700'}"
isDisabled={isAdding}
>
{#if isAdding}
<BarLoader size="30" color="#1d4ed8" unit="px" duration="1s" />
{:else}
Join waiting list
{/if}
<PrimaryButton type="submit" isLoading={isAdding}>
Join waiting list
</PrimaryButton>
{/if}
</div>
-5
View File
@@ -1,15 +1,10 @@
<script context="module">
export function preload({ params }) {
console.log(`params`, params);
return { profileId: params.id };
}
</script>
<script>
// import { goto } from '$app/navigation';
import { onMount } from 'svelte';
import { Chasing } from 'svelte-loading-spinners';
import Search32 from 'carbon-icons-svelte/lib/Search32';
import UserAvatar16 from 'carbon-icons-svelte/lib/UserAvatar16';
import Book16 from 'carbon-icons-svelte/lib/Book16';
import TextField from '../../components/Form/TextField.svelte';