CLASSROOMIO-T-80: Replace sapper with sveltekit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+33
-46
@@ -1,52 +1,39 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { stores } from '@sapper/app';
|
||||
import { page } from '$app/stores';
|
||||
import { dndzone } from 'svelte-dnd-action';
|
||||
import Time24 from 'carbon-icons-svelte/lib/Time24';
|
||||
import Edit24 from 'carbon-icons-svelte/lib/Edit24';
|
||||
import Save24 from 'carbon-icons-svelte/lib/Save24';
|
||||
import Phone24 from 'carbon-icons-svelte/lib/Phone24';
|
||||
import Delete24 from 'carbon-icons-svelte/lib/Delete24';
|
||||
import CheckmarkFilled24 from 'carbon-icons-svelte/lib/CheckmarkFilled24';
|
||||
import PageNav from '../../../../components/PageNav/index.svelte';
|
||||
import RoleBasedSecurity from '../../../../components/RoleBasedSecurity/index.svelte';
|
||||
import Box from '../../../../components/Box/index.svelte';
|
||||
import PageBody from '../../../../components/PageBody/index.svelte';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import TextField from '../../../../components/Form/TextField.svelte';
|
||||
import IconButton from '../../../../components/IconButton/index.svelte';
|
||||
import Select from '../../../../components/Form/Select.svelte';
|
||||
import {
|
||||
fetchCourse,
|
||||
updateLesson,
|
||||
} from '../../../../utils/services/courses';
|
||||
import CourseContainer from '../../../../components/CourseContainer/index.svelte';
|
||||
import { profile } from '../../../../utils/store/user';
|
||||
import TimeIcon from 'carbon-icons-svelte/lib/Time.svelte';
|
||||
import EditIcon from 'carbon-icons-svelte/lib/Edit.svelte';
|
||||
import SaveIcon from 'carbon-icons-svelte/lib/Save.svelte';
|
||||
import PhoneIcon from 'carbon-icons-svelte/lib/Phone.svelte';
|
||||
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
|
||||
import CheckmarkFilled24 from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import IconButton from '$lib/components/IconButton/index.svelte';
|
||||
import Select from '$lib/components/Form/Select.svelte';
|
||||
import { fetchCourse, updateLesson } from '$lib/utils/services/courses';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import {
|
||||
lessons,
|
||||
handleAddLesson,
|
||||
handleSaveLesson,
|
||||
handleDelete,
|
||||
} from '../../../../components/Course/components/Lesson/store/lessons';
|
||||
import {
|
||||
course,
|
||||
setCourse,
|
||||
group,
|
||||
} from '../../../../components/Course/store';
|
||||
} from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { course, setCourse, group } from '$lib/components/Course/store';
|
||||
|
||||
export let courseId;
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let lessonEditing;
|
||||
let ref;
|
||||
let isStudent = true;
|
||||
|
||||
const { page } = stores();
|
||||
const flipDurationMs = 300;
|
||||
|
||||
function formatDate(date) {
|
||||
@@ -106,8 +93,8 @@
|
||||
|
||||
onMount(async () => {
|
||||
if ($course.id) return;
|
||||
const { data } = await fetchCourse(courseId);
|
||||
setCourse(data);
|
||||
const { data: _data } = await fetchCourse(courseId);
|
||||
setCourse(_data);
|
||||
});
|
||||
|
||||
$: {
|
||||
@@ -124,7 +111,7 @@
|
||||
<CourseContainer bind:isStudent>
|
||||
<PageNav title="Lessons">
|
||||
<div slot="widget">
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<PrimaryButton
|
||||
label="Add"
|
||||
onClick={addLesson}
|
||||
@@ -177,7 +164,7 @@
|
||||
</IconButton>
|
||||
</div>
|
||||
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<!-- Edit/Save -->
|
||||
<div class="absolute -top-2 -right-2">
|
||||
{#if lessonEditing === lesson.id}
|
||||
@@ -187,11 +174,11 @@
|
||||
handleSaveLesson(lesson, $course.id);
|
||||
}}
|
||||
>
|
||||
<Save24 class="carbon-icon" />
|
||||
<SaveIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
{:else}
|
||||
<IconButton onClick={() => (lessonEditing = lesson.id)}>
|
||||
<Edit24 class="carbon-icon" />
|
||||
<EditIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -209,7 +196,7 @@
|
||||
<h3 class="dark:text-white text-2xl m-0 flex items-center">
|
||||
<a
|
||||
href={isStudent && !lesson.is_complete
|
||||
? $page.path
|
||||
? $page.url.pathname
|
||||
: '/courses/' + $course.id + '/lessons/' + lesson.id}
|
||||
class="dark:text-white hover:underline text-black {isStudent &&
|
||||
!lesson.is_complete
|
||||
@@ -264,7 +251,7 @@
|
||||
on:input={(e) => (lesson.lesson_at = e.target.value)}
|
||||
/>
|
||||
{:else}
|
||||
<Time24 class="carbon-icon" />
|
||||
<TimeIcon size={24} class="carbon-icon" />
|
||||
<p class="dark:text-white text-md ml-2">
|
||||
{new Date(lesson.lesson_at).toDateString()}
|
||||
</p>
|
||||
@@ -280,7 +267,7 @@
|
||||
placeholder="https://meet.google.com/mga-dsjs-fmb"
|
||||
/>
|
||||
{:else}
|
||||
<Phone24 class="carbon-icon" />
|
||||
<PhoneIcon size={24} class="carbon-icon" />
|
||||
<a
|
||||
class="text-md ml-2"
|
||||
href={lesson.call_url || '#'}
|
||||
@@ -293,10 +280,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<div class="absolute bottom-2 right-0">
|
||||
<IconButton onClick={handleDelete(lesson.id)}>
|
||||
<Delete24 class="carbon-icon" />
|
||||
<TrashCanIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</RoleBasedSecurity>
|
||||
@@ -0,0 +1,21 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
const { id: courseId, lessonParams = [] } = params;
|
||||
console.log(lessonParams, lessonParams);
|
||||
// let lessonId = '';
|
||||
// let exerciseRouteName = '';
|
||||
// let exerciseId = '';
|
||||
// if (typeof lessonParams === 'string') {
|
||||
// lessonId
|
||||
// }
|
||||
const splitparams = lessonParams.split('/');
|
||||
console.log('splitparams', splitparams);
|
||||
const [lessonId, exerciseRouteName, exerciseId] = splitparams;
|
||||
|
||||
return {
|
||||
courseId,
|
||||
lessonId,
|
||||
exerciseRouteName,
|
||||
exerciseId,
|
||||
isMaterialsTabActive: !exerciseRouteName,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
<script>
|
||||
import { page } from '$app/stores';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { fetchCourse, fetchLesson } from '$lib/utils/services/courses';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import Materials from '$lib/components/Course/components/Lesson/Materials/index.svelte';
|
||||
import Exercises from '$lib/components/Course/components/Lesson/Exercises/index.svelte';
|
||||
import MODES from '$lib/utils/constants/mode.js';
|
||||
import { setCourse, course } from '$lib/components/Course/store';
|
||||
import { lesson } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
|
||||
export let data;
|
||||
|
||||
let path = '';
|
||||
let mode = MODES.view;
|
||||
let prevMode = '';
|
||||
let prevLessonId = '';
|
||||
let isFetching = false;
|
||||
|
||||
async function fetchReqData(lessonId = '') {
|
||||
isFetching = true;
|
||||
|
||||
let lessonData;
|
||||
if (!$course.id) {
|
||||
const { data: _data } = await fetchCourse(data.courseId);
|
||||
|
||||
lessonData = _data.lessons.find(
|
||||
(lesson = { id: '' }) => lesson.id === lessonId
|
||||
);
|
||||
setCourse(_data);
|
||||
} else if (prevLessonId !== lessonId) {
|
||||
const lesson = await fetchLesson(lessonId);
|
||||
lessonData = lesson.data;
|
||||
}
|
||||
|
||||
prevLessonId = lessonId;
|
||||
|
||||
const totalExercises =
|
||||
lessonData?.totalExercises?.[0] && lessonData.totalExercises[0].count;
|
||||
setLesson(lessonData, totalExercises || 0);
|
||||
isFetching = false;
|
||||
}
|
||||
|
||||
function setLesson(lessonData, totalExercises) {
|
||||
if (!lessonData) return;
|
||||
|
||||
lesson.update((l) => ({
|
||||
...l,
|
||||
id: data.lessonId,
|
||||
totalExercises,
|
||||
materials: lessonData,
|
||||
}));
|
||||
}
|
||||
|
||||
$: path = $page.url.pathname.replace(/\/exercises[\/ 0-9 a-z -]*/, '');
|
||||
|
||||
$: if (data.courseId) {
|
||||
mode = MODES.view;
|
||||
fetchReqData(data.lessonId);
|
||||
}
|
||||
|
||||
$: console.log('data changed', data);
|
||||
</script>
|
||||
|
||||
<CourseContainer
|
||||
{isFetching}
|
||||
{path}
|
||||
isExercisePage={!data.isMaterialsTabActive && data.exerciseId}
|
||||
>
|
||||
<PageNav
|
||||
navItems={[
|
||||
{
|
||||
label: 'Materials',
|
||||
isActive: data.isMaterialsTabActive,
|
||||
href: path,
|
||||
},
|
||||
{
|
||||
label: 'Exercises',
|
||||
badgeValue: $lesson.totalExercises,
|
||||
isActive: !data.isMaterialsTabActive,
|
||||
href: `${path}/exercises`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="widget">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
{#if data.isMaterialsTabActive}
|
||||
<div class="flex items-center">
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||
onClick={() => {
|
||||
prevMode = mode;
|
||||
mode = mode === MODES.edit ? MODES.view : MODES.edit;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</RoleBasedSecurity>
|
||||
</svelte:fragment>
|
||||
</PageNav>
|
||||
|
||||
{#if !data.isMaterialsTabActive}
|
||||
<Exercises
|
||||
lessonId={data.lessonId}
|
||||
exerciseId={data.exerciseId}
|
||||
path={`${path}/exercises`}
|
||||
/>
|
||||
{:else if !!data.lessonId}
|
||||
<PageBody>
|
||||
<Materials lessonId={data.lessonId} {mode} {prevMode} />
|
||||
</PageBody>
|
||||
{/if}
|
||||
</CourseContainer>
|
||||
@@ -1,136 +0,0 @@
|
||||
<script context="module">
|
||||
import {
|
||||
fetchCourse,
|
||||
fetchLesson,
|
||||
} from '../../../../../utils/services/courses';
|
||||
|
||||
export async function preload({ params }) {
|
||||
const { id: courseId, lessonParams = [] } = params;
|
||||
const [lessonId, exerciseRouteName, exerciseId] = lessonParams;
|
||||
|
||||
return {
|
||||
courseId,
|
||||
lessonId,
|
||||
exerciseRouteName,
|
||||
exerciseId,
|
||||
isMaterialsTabActive: !exerciseRouteName,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
import CourseContainer from '../../../../../components/CourseContainer/index.svelte';
|
||||
|
||||
import PrimaryButton from '../../../../../components/PrimaryButton/index.svelte';
|
||||
import RoleBasedSecurity from '../../../../../components/RoleBasedSecurity/index.svelte';
|
||||
import PageNav from '../../../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../../../components/PageBody/index.svelte';
|
||||
import Materials from '../../../../../components/Course/components/Lesson/Materials/index.svelte';
|
||||
import Exercises from '../../../../../components/Course/components/Lesson/Exercises/index.svelte';
|
||||
import MODES from '../../../../../utils/constants/mode.js';
|
||||
import { setCourse, course } from '../../../../../components/Course/store';
|
||||
import { lesson } from '../../../../../components/Course/components/Lesson/store/lessons';
|
||||
|
||||
export let courseId;
|
||||
export let lessonId;
|
||||
export let exerciseId;
|
||||
export let isMaterialsTabActive;
|
||||
|
||||
let path;
|
||||
let mode = MODES.view;
|
||||
let prevMode;
|
||||
let prevLessonId;
|
||||
let isFetching = false;
|
||||
|
||||
const { page } = stores();
|
||||
|
||||
async function fetchReqData(lessonId) {
|
||||
isFetching = true;
|
||||
|
||||
let lessonData;
|
||||
if (!$course.id) {
|
||||
const { data } = await fetchCourse(courseId);
|
||||
|
||||
lessonData = data.lessons.find((lesson) => lesson.id === lessonId);
|
||||
setCourse(data);
|
||||
} else if (prevLessonId !== lessonId) {
|
||||
const lesson = await fetchLesson(lessonId);
|
||||
lessonData = lesson.data;
|
||||
}
|
||||
|
||||
prevLessonId = lessonId;
|
||||
|
||||
const totalExercises =
|
||||
lessonData.totalExercises[0] && lessonData.totalExercises[0].count;
|
||||
setLesson(lessonData, totalExercises);
|
||||
isFetching = false;
|
||||
}
|
||||
|
||||
function setLesson(lessonData, totalExercises) {
|
||||
if (!lessonData) return;
|
||||
|
||||
lesson.update((l) => ({
|
||||
...l,
|
||||
id: lessonId,
|
||||
totalExercises,
|
||||
materials: lessonData,
|
||||
}));
|
||||
}
|
||||
|
||||
$: path = $page.path.replace(/\/exercises[\/ 0-9 a-z -]*/, '');
|
||||
|
||||
$: {
|
||||
if (courseId) {
|
||||
mode = MODES.view;
|
||||
fetchReqData(lessonId);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<CourseContainer
|
||||
{isFetching}
|
||||
{path}
|
||||
isExercisePage={!isMaterialsTabActive && exerciseId}
|
||||
>
|
||||
<PageNav
|
||||
navItems={[
|
||||
{
|
||||
label: 'Materials',
|
||||
isActive: isMaterialsTabActive,
|
||||
href: path,
|
||||
},
|
||||
{
|
||||
label: 'Exercises',
|
||||
badgeValue: $lesson.totalExercises,
|
||||
isActive: !isMaterialsTabActive,
|
||||
href: `${path}/exercises`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="widget">
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
{#if isMaterialsTabActive}
|
||||
<div class="flex items-center">
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||
onClick={() => {
|
||||
prevMode = mode;
|
||||
mode = mode === MODES.edit ? MODES.view : MODES.edit;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</RoleBasedSecurity>
|
||||
</svelte:fragment>
|
||||
</PageNav>
|
||||
|
||||
{#if !isMaterialsTabActive}
|
||||
<Exercises {lessonId} {exerciseId} path={`${path}/exercises`} />
|
||||
{:else if !!lessonId}
|
||||
<PageBody>
|
||||
<Materials {lessonId} {mode} {prevMode} />
|
||||
</PageBody>
|
||||
{/if}
|
||||
</CourseContainer>
|
||||
Reference in New Issue
Block a user