CLASSROOMIO-T-79: Implement empty state pages
Co-authored-by: Rotimi Best <[email protected]> Merge-request: CLASSROOMIO-MR-32 Merged-by: Best Admin <[email protected]>
This commit is contained in:
committed by
Space Cloud
co-authored by
Rotimi Best
parent
8ae0bffc34
commit
60d0c6d837
@@ -3,7 +3,7 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="{className} w-full h-80 flex items-center justify-center flex-col border rounded border-gray-200"
|
||||
class="{className} w-full h-[517px] flex items-center justify-center flex-col border rounded border-gray-200"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -9,16 +9,14 @@
|
||||
import CheckboxQuestion from '$lib/components/Question/CheckboxQuestion/index.svelte';
|
||||
import TextareaQuestion from '$lib/components/Question/TextareaQuestion/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import Progress from '$lib/components/Progress/index.svelte';
|
||||
import { removeDuplicate } from '$lib/utils/functions/removeDuplicate';
|
||||
import { QUESTION_TYPE } from '$lib/components/Question/constants';
|
||||
import { STATUS } from './constants';
|
||||
import { getPropsForQuestion, filterOutDeleted } from './functions';
|
||||
import {
|
||||
formatAnswers,
|
||||
getGroupMemberId,
|
||||
} from '$lib/components/Course/function';
|
||||
import { formatAnswers, getGroupMemberId } from '$lib/components/Course/function';
|
||||
import { submitExercise } from '$lib/utils/services/courses';
|
||||
import { fetchSubmission } from '$lib/utils/services/submissions';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
@@ -42,21 +40,18 @@
|
||||
|
||||
const prevAnswer = answers[id] || [];
|
||||
const formattedAnswer =
|
||||
typeof value === 'string'
|
||||
? value
|
||||
: removeDuplicate([...prevAnswer, ...(value || [])]);
|
||||
typeof value === 'string' ? value : removeDuplicate([...prevAnswer, ...(value || [])]);
|
||||
|
||||
$questionnaireMetaData.answers = {
|
||||
...answers,
|
||||
[id]: formattedAnswer,
|
||||
[id]: formattedAnswer
|
||||
};
|
||||
|
||||
if (moveToNextQuestion) {
|
||||
$questionnaireMetaData.currentQuestionIndex += 1;
|
||||
}
|
||||
|
||||
const isFinished =
|
||||
!questions[$questionnaireMetaData.currentQuestionIndex - 1];
|
||||
const isFinished = !questions[$questionnaireMetaData.currentQuestionIndex - 1];
|
||||
console.log(`isFinished`, isFinished);
|
||||
console.log(
|
||||
`$questionnaireMetaData.currentQuestionIndex`,
|
||||
@@ -87,11 +82,7 @@
|
||||
return 100;
|
||||
}
|
||||
|
||||
return (
|
||||
Math.round(
|
||||
((currentQuestionIndex - 1) / $questionnaire.questions.length) * 100
|
||||
) || 0
|
||||
);
|
||||
return Math.round(((currentQuestionIndex - 1) / $questionnaire.questions.length) * 100) || 0;
|
||||
}
|
||||
|
||||
function getTotalPossibleGrade() {
|
||||
@@ -113,7 +104,7 @@
|
||||
const args = {
|
||||
exerciseId,
|
||||
courseId,
|
||||
submittedBy: getGroupMemberId(people, profileId),
|
||||
submittedBy: getGroupMemberId(people, profileId)
|
||||
};
|
||||
const { data } = await fetchSubmission(args);
|
||||
hasSubmission = true;
|
||||
@@ -123,31 +114,26 @@
|
||||
|
||||
$questionnaireMetaData.answers = formatAnswers({
|
||||
questions: $questionnaire.questions,
|
||||
answers: submission.answers,
|
||||
answers: submission.answers
|
||||
});
|
||||
|
||||
$questionnaireMetaData.totalPossibleGrade = getTotalPossibleGrade();
|
||||
|
||||
$questionnaireMetaData.currentQuestionIndex =
|
||||
$questionnaire.questions.length;
|
||||
$questionnaireMetaData.currentQuestionIndex = $questionnaire.questions.length;
|
||||
$questionnaireMetaData.isFinished = true;
|
||||
$questionnaireMetaData.status = submission.status_id;
|
||||
$questionnaireMetaData.finalTotalGrade = 0;
|
||||
$questionnaireMetaData.grades = submission.answers.reduce(
|
||||
(acc, answer) => {
|
||||
acc[answer.question_id] = answer.point;
|
||||
$questionnaireMetaData.finalTotalGrade += answer.point;
|
||||
$questionnaireMetaData.grades = submission.answers.reduce((acc, answer) => {
|
||||
acc[answer.question_id] = answer.point;
|
||||
$questionnaireMetaData.finalTotalGrade += answer.point;
|
||||
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
currentQuestion =
|
||||
$questionnaire.questions[$questionnaireMetaData.currentQuestionIndex - 1];
|
||||
currentQuestion = $questionnaire.questions[$questionnaireMetaData.currentQuestionIndex - 1];
|
||||
if ($questionnaireMetaData.currentQuestionIndex > 0 && !currentQuestion) {
|
||||
$questionnaireMetaData.isFinished = true;
|
||||
}
|
||||
@@ -182,16 +168,15 @@
|
||||
questionnaireMetaData={$questionnaireMetaData}
|
||||
/>
|
||||
{:else if !$questionnaire.questions.length}
|
||||
<div
|
||||
class="w-4/5 h-40 m-auto flex items-center justify-center text-center border-2 border-gray-200 rounded-md"
|
||||
>
|
||||
<h3 class="dark:text-white text-2xl">
|
||||
No questions added. <br />
|
||||
<Box>
|
||||
<img src="/images/empty-exercise-icon.svg" alt="Exercise svg" class="my-2.5" />
|
||||
<h2 class="text-xl my-1.5">No question added for this exercise</h2>
|
||||
<p class="text-sm text-center px-44">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
Click the <span class="text-blue-700">Edit</span> button to add.
|
||||
</RoleBasedSecurity>
|
||||
</h3>
|
||||
</div>
|
||||
</p>
|
||||
</Box>
|
||||
{:else if $questionnaireMetaData.currentQuestionIndex === 0}
|
||||
<div>
|
||||
<h2 class="my-1">{$questionnaire.title}</h2>
|
||||
@@ -219,12 +204,7 @@
|
||||
{@html marked($questionnaire.description || 'No desription')}
|
||||
</article>
|
||||
|
||||
<PrimaryButton
|
||||
onClick={handleStart}
|
||||
label="Start"
|
||||
className="my-5 float-right"
|
||||
type="button"
|
||||
/>
|
||||
<PrimaryButton onClick={handleStart} label="Start" className="my-5 float-right" type="button" />
|
||||
</div>
|
||||
{:else if $questionnaireMetaData.isFinished}
|
||||
<div class="flex items-center justify-between">
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script>
|
||||
import { goto } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
import AudioConsoleIcon from 'carbon-icons-svelte/lib/AudioConsole.svelte';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import { Moon } from 'svelte-loading-spinners';
|
||||
import Backdrop from '$lib/components/Backdrop/index.svelte';
|
||||
@@ -26,19 +25,19 @@
|
||||
let newExercise = {
|
||||
id: 1,
|
||||
title: '',
|
||||
description: '',
|
||||
description: ''
|
||||
};
|
||||
|
||||
async function handleAddExercise() {
|
||||
const { data, error } = await createExercise({
|
||||
title: newExercise.title,
|
||||
lesson_id: lessonId,
|
||||
lesson_id: lessonId
|
||||
});
|
||||
|
||||
console.log(`data, error `, data, error);
|
||||
lesson.update((_lesson) => ({
|
||||
..._lesson,
|
||||
exercises: [..._lesson.exercises, data[0]],
|
||||
exercises: [..._lesson.exercises, data[0]]
|
||||
}));
|
||||
|
||||
handleCancelAddExercise();
|
||||
@@ -49,7 +48,7 @@
|
||||
newExercise = {
|
||||
id: $lesson.exercises.length + 1,
|
||||
title: '',
|
||||
description: '',
|
||||
description: ''
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,41 +132,20 @@
|
||||
{/if}
|
||||
|
||||
{#if exerciseId}
|
||||
<Exercise
|
||||
{exerciseId}
|
||||
{goBack}
|
||||
refetchExercise={() => getExercise(exerciseId)}
|
||||
/>
|
||||
<Exercise {exerciseId} {goBack} refetchExercise={() => getExercise(exerciseId)} />
|
||||
{:else}
|
||||
<Modal
|
||||
onClose={handleCancelAddExercise}
|
||||
bind:open
|
||||
modalHeading="Create an Exercise"
|
||||
width="w-80"
|
||||
>
|
||||
<TextField
|
||||
bind:value={newExercise.title}
|
||||
autofocus={true}
|
||||
placeholder="Exercise name"
|
||||
/>
|
||||
<Modal onClose={handleCancelAddExercise} bind:open modalHeading="Create an Exercise" width="w-80">
|
||||
<TextField bind:value={newExercise.title} autofocus={true} placeholder="Exercise name" />
|
||||
|
||||
<div class="mt-5 flex items-center">
|
||||
<PrimaryButton
|
||||
className="px-6 py-3"
|
||||
label="Submit"
|
||||
onClick={handleAddExercise}
|
||||
/>
|
||||
<PrimaryButton className="px-6 py-3" label="Submit" onClick={handleAddExercise} />
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<PageBody>
|
||||
<slot:fragment slot="header">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label="Add"
|
||||
onClick={() => (open = !open)}
|
||||
/>
|
||||
<PrimaryButton className="mr-2" label="Add" onClick={() => (open = !open)} />
|
||||
</RoleBasedSecurity>
|
||||
</slot:fragment>
|
||||
|
||||
@@ -181,11 +159,15 @@
|
||||
<p class="dark:text-white mt-4 text-sm">Created Jul 3, 2021</p>
|
||||
</a>
|
||||
{:else}
|
||||
<Box>
|
||||
<AudioConsoleIcon size={32} class="carbon-icon w-80" />
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">
|
||||
No Exercise Added
|
||||
</h3>
|
||||
<Box className="mt-3">
|
||||
<div class="flex justify-between flex-col items-center w-96">
|
||||
<img src="/images/empty-exercise-icon.svg" alt="Exercise" class="my-2.5 mx-auto" />
|
||||
<h2 class="text-xl my-1.5 font-normal">No exercises added for this lesson</h2>
|
||||
<p class="text-sm text-center text-slate-500">
|
||||
Share your knowledge with the world by creating engaging exercises. Add an exercise
|
||||
now.
|
||||
</p>
|
||||
</div>
|
||||
</Box>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import EditContent from '$lib/components/EditContent/index.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import {
|
||||
lesson,
|
||||
handleUpdateLessonMaterials,
|
||||
isLessonDirty,
|
||||
} from '../store/lessons';
|
||||
import { lesson, handleUpdateLessonMaterials, isLessonDirty } from '../store/lessons';
|
||||
import * as CONSTANTS from './constants';
|
||||
|
||||
export let mode = MODES.view;
|
||||
@@ -42,10 +38,7 @@
|
||||
} else if (tab.value === 2) {
|
||||
badgeValue = !!note ? 1 : 0;
|
||||
} else {
|
||||
badgeValue =
|
||||
typeof video_url === 'string' && !!video_url
|
||||
? video_url.split(',').length
|
||||
: 0;
|
||||
badgeValue = typeof video_url === 'string' && !!video_url ? video_url.split(',').length : 0;
|
||||
}
|
||||
|
||||
tab.badgeValue = badgeValue;
|
||||
@@ -81,8 +74,14 @@
|
||||
/>
|
||||
{:else}
|
||||
<Box>
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">No slide added</h3>
|
||||
<img alt="Slide not found" src="/notfound.webp" class="w-80" />
|
||||
<div class="flex justify-between flex-col items-center w-96">
|
||||
<img src="/images/empty-slide-icon.svg" alt="No Slide" class="my-2.5 mx-auto" />
|
||||
<h2 class="text-xl my-1.5 font-normal">No slides yet</h2>
|
||||
<p class="text-sm text-center text-slate-500">
|
||||
Share your knowledge with the world by creating engaging slides. Add your slide's link
|
||||
now.
|
||||
</p>
|
||||
</div>
|
||||
</Box>
|
||||
{/if}
|
||||
</TabContent>
|
||||
@@ -99,8 +98,13 @@
|
||||
<MarkdownRender content={$lesson.materials.note} />
|
||||
{:else}
|
||||
<Box>
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">No note added</h3>
|
||||
<img alt="Lesson note not found" src="/notfound.webp" class="w-80" />
|
||||
<div class="flex justify-between flex-col items-center w-96">
|
||||
<img src="/images/empty-note-icon.svg" alt="No Note" class="my-2.5 mx-auto" />
|
||||
<h2 class="text-xl my-1.5 font-normal">No Notes yet</h2>
|
||||
<p class="text-sm text-center text-slate-500">
|
||||
Share your knowledge with the world by creating engaging notes. Add your notes now.
|
||||
</p>
|
||||
</div>
|
||||
</Box>
|
||||
{/if}
|
||||
</TabContent>
|
||||
@@ -129,10 +133,14 @@
|
||||
{/each}
|
||||
{:else}
|
||||
<Box>
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">
|
||||
No youtube video added
|
||||
</h3>
|
||||
<img alt="Video not found" src="/notfound.webp" class="w-80" />
|
||||
<div class="flex justify-between flex-col items-center w-96">
|
||||
<img src="/images/empty-video-icon.svg" alt="No Video" class="my-2.5 mx-auto" />
|
||||
<h2 class="text-xl my-1.5 font-normal">No videos yet</h2>
|
||||
<p class="text-sm text-center text-slate-500">
|
||||
Share your knowledge with the world by creating engaging videos. Add your video link
|
||||
now.
|
||||
</p>
|
||||
</div>
|
||||
</Box>
|
||||
{/if}
|
||||
</TabContent>
|
||||
|
||||
+35
-49
@@ -22,12 +22,7 @@
|
||||
// import Footer from '$lib/components/Footer/index.svelte';
|
||||
import Apps from '$lib/components/Apps/index.svelte';
|
||||
import PlayQuiz from '$lib/components/Org/Quiz/Play/index.svelte';
|
||||
import {
|
||||
isCoursesPage,
|
||||
isOrgPage,
|
||||
isLMSPage,
|
||||
isQuizPage,
|
||||
} from '$lib/utils/functions/app';
|
||||
import { isCoursesPage, isOrgPage, isLMSPage, isQuizPage } from '$lib/utils/functions/app';
|
||||
import showAppsSideBar from '$lib/utils/functions/showAppsSideBar';
|
||||
import isPublicRoute from '$lib/utils/functions/routes/isPublicRoute';
|
||||
import { user, profile } from '$lib/utils/store/user';
|
||||
@@ -58,14 +53,14 @@
|
||||
integrations: [
|
||||
new Integrations.BrowserTracing(),
|
||||
new CaptureConsole({
|
||||
levels: ['error'],
|
||||
}),
|
||||
levels: ['error']
|
||||
})
|
||||
],
|
||||
environment: !dev ? 'production' : 'development',
|
||||
// Set tracesSampleRate to 1.0 to capture 100%
|
||||
// of transactions for performance monitoring.
|
||||
// We recommend adjusting this value in production
|
||||
tracesSampleRate: 1.0,
|
||||
tracesSampleRate: 1.0
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -74,7 +69,7 @@
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
// Get user profile
|
||||
const {
|
||||
data: { session },
|
||||
data: { session }
|
||||
} = await supabase.auth.getSession();
|
||||
const { user: authUser } = session;
|
||||
console.log('Get user profile', authUser);
|
||||
@@ -83,20 +78,14 @@
|
||||
let {
|
||||
data: profileData,
|
||||
error,
|
||||
status,
|
||||
} = await supabase
|
||||
.from('profile')
|
||||
.select(`*`)
|
||||
.eq('id', authUser?.id)
|
||||
.single();
|
||||
status
|
||||
} = await supabase.from('profile').select(`*`).eq('id', authUser?.id).single();
|
||||
|
||||
if (error && !profileData && status === 406 && authUser) {
|
||||
// User wasn't found, create profile
|
||||
console.log(`User wasn't found, create profile`);
|
||||
|
||||
const [regexUsernameMatch] = [
|
||||
...(authUser.email?.matchAll(/(.*)@/g) || []),
|
||||
];
|
||||
const [regexUsernameMatch] = [...(authUser.email?.matchAll(/(.*)@/g) || [])];
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('profile')
|
||||
@@ -104,7 +93,7 @@
|
||||
id: authUser.id,
|
||||
username: regexUsernameMatch[1] + '1669991321770',
|
||||
fullname: regexUsernameMatch[1],
|
||||
email: authUser.email,
|
||||
email: authUser.email
|
||||
})
|
||||
.select();
|
||||
|
||||
@@ -125,7 +114,7 @@
|
||||
.insert({
|
||||
organization_id: $currentOrg.id,
|
||||
profile_id: $profile.id,
|
||||
role_id: 3,
|
||||
role_id: 3
|
||||
})
|
||||
.select();
|
||||
if (error) {
|
||||
@@ -188,9 +177,7 @@
|
||||
const subdomain = matches?.[1] ?? '';
|
||||
|
||||
if (!blockedSubdomain.includes(subdomain)) {
|
||||
const answer = Array.isArray(matches)
|
||||
? !!subdomain && subdomain !== 'www'
|
||||
: false;
|
||||
const answer = Array.isArray(matches) ? !!subdomain && subdomain !== 'www' : false;
|
||||
|
||||
$appStore.isStudentDomain = debug || answer;
|
||||
$appStore.siteNameFromDomain = debug ? 'codingdojo' : subdomain;
|
||||
@@ -230,32 +217,30 @@
|
||||
// return goto('/login');
|
||||
// }
|
||||
|
||||
const { data: authListener } = supabase.auth.onAuthStateChange(
|
||||
(event, session) => {
|
||||
// Log key events
|
||||
console.log(`event`, event);
|
||||
if (event == 'PASSWORD_RECOVERY') {
|
||||
console.log('PASSWORD RESET');
|
||||
}
|
||||
|
||||
if (path.includes('reset')) {
|
||||
console.log('Dont change auth when on reset page');
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip Authentication
|
||||
if (skipAuth) return;
|
||||
|
||||
// Authentication Steps
|
||||
if (event === 'SIGNED_IN') {
|
||||
$user.fetchingUser = true;
|
||||
getProfile();
|
||||
} else {
|
||||
console.log('not logged in, go to login');
|
||||
return goto('/login');
|
||||
}
|
||||
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
|
||||
// Log key events
|
||||
console.log(`event`, event);
|
||||
if (event == 'PASSWORD_RECOVERY') {
|
||||
console.log('PASSWORD RESET');
|
||||
}
|
||||
);
|
||||
|
||||
if (path.includes('reset')) {
|
||||
console.log('Dont change auth when on reset page');
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip Authentication
|
||||
if (skipAuth) return;
|
||||
|
||||
// Authentication Steps
|
||||
if (event === 'SIGNED_IN') {
|
||||
$user.fetchingUser = true;
|
||||
getProfile();
|
||||
} else {
|
||||
console.log('not logged in, go to login');
|
||||
return goto('/login');
|
||||
}
|
||||
});
|
||||
|
||||
// Update theme - dark or light mode
|
||||
$appStore.isDark = localStorage.getItem('theme') === 'dark';
|
||||
@@ -266,6 +251,7 @@
|
||||
}
|
||||
|
||||
return () => {
|
||||
console.log('unsubscribed');
|
||||
authListener?.unsubscribe();
|
||||
};
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
lessons,
|
||||
handleAddLesson,
|
||||
handleSaveLesson,
|
||||
handleDelete,
|
||||
handleDelete
|
||||
} from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { course, setCourse, group } from '$lib/components/Course/store';
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
ref.scrollIntoView({
|
||||
block: 'start',
|
||||
behavior: 'smooth',
|
||||
inline: 'nearest',
|
||||
inline: 'nearest'
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
@@ -66,10 +66,7 @@
|
||||
}
|
||||
|
||||
function handleDndFinalize(e) {
|
||||
const prevLessonsByOrder = $lessons.reduce(
|
||||
(acc, l) => ({ ...acc, [l.id]: l.order }),
|
||||
{}
|
||||
);
|
||||
const prevLessonsByOrder = $lessons.reduce((acc, l) => ({ ...acc, [l.id]: l.order }), {});
|
||||
$lessons = e.detail.items;
|
||||
|
||||
// Only update the lesson order that changed
|
||||
@@ -98,9 +95,7 @@
|
||||
});
|
||||
|
||||
$: {
|
||||
const user = $group.people.find(
|
||||
(person) => person.profile_id === $profile.id
|
||||
);
|
||||
const user = $group.people.find((person) => person.profile_id === $profile.id);
|
||||
|
||||
if (user) {
|
||||
isStudent = user.role_id === 3;
|
||||
@@ -112,11 +107,7 @@
|
||||
<PageNav title="Lessons">
|
||||
<div slot="widget">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<PrimaryButton
|
||||
label="Add"
|
||||
onClick={addLesson}
|
||||
isDisabled={!!lessonEditing}
|
||||
/>
|
||||
<PrimaryButton label="Add" onClick={addLesson} isDisabled={!!lessonEditing} />
|
||||
</RoleBasedSecurity>
|
||||
</div>
|
||||
</PageNav>
|
||||
@@ -130,8 +121,8 @@
|
||||
dragDisabled: isStudent,
|
||||
dropTargetStyle: {
|
||||
border: '2px #1d4ed8 solid',
|
||||
'border-style': 'dashed',
|
||||
},
|
||||
'border-style': 'dashed'
|
||||
}
|
||||
}}
|
||||
on:consider={handleDndConsider}
|
||||
on:finalize={handleDndFinalize}
|
||||
@@ -153,7 +144,7 @@
|
||||
? {}
|
||||
: {
|
||||
title: `Click to ${lesson.is_complete ? 'lock' : 'unlock'}`,
|
||||
direction: 'right',
|
||||
direction: 'right'
|
||||
}}
|
||||
>
|
||||
{#if lesson.is_complete}
|
||||
@@ -218,11 +209,7 @@
|
||||
>
|
||||
<div class="mb-3 lg:mb-0">
|
||||
{#if lessonEditing === lesson.id}
|
||||
<Select
|
||||
bind:value={lesson.profile}
|
||||
options={$group.tutors}
|
||||
labelKey="fullname"
|
||||
/>
|
||||
<Select bind:value={lesson.profile} options={$group.tutors} labelKey="fullname" />
|
||||
{:else if !lesson.profile}
|
||||
<p class="dark:text-white ml-2 text-sm">No tutor added</p>
|
||||
{:else}
|
||||
@@ -268,11 +255,7 @@
|
||||
/>
|
||||
{:else}
|
||||
<PhoneIcon size={24} class="carbon-icon" />
|
||||
<a
|
||||
class="text-md ml-2"
|
||||
href={lesson.call_url || '#'}
|
||||
target="_blank"
|
||||
>
|
||||
<a class="text-md ml-2" href={lesson.call_url || '#'} target="_blank">
|
||||
{lesson.call_url ? 'Join lesson' : 'No link'}
|
||||
</a>
|
||||
{/if}
|
||||
@@ -290,10 +273,14 @@
|
||||
</div>
|
||||
{:else}
|
||||
<Box>
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">
|
||||
No lesson added
|
||||
</h3>
|
||||
<img alt="No lesson added" src="/notfound2.gif" class="w-80" />
|
||||
<div class="flex justify-between flex-col items-center w-96">
|
||||
<img src="/images/empty-lesson-icon.svg" alt="Lesson" class="my-2.5 mx-auto" />
|
||||
<h2 class="text-xl my-1.5 font-normal">No lessons yet</h2>
|
||||
<p class="text-sm text-center text-slate-500">
|
||||
Share your knowledge with the world by creating engaging lessons. Start by clicking on
|
||||
the New Lesson button.
|
||||
</p>
|
||||
</div>
|
||||
</Box>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
@@ -8,7 +8,6 @@ export const load = ({ params = { id: '' } }) => {
|
||||
// lessonId
|
||||
// }
|
||||
const splitparams = lessonParams.split('/');
|
||||
console.log('splitparams', splitparams);
|
||||
const [lessonId, exerciseRouteName, exerciseId] = splitparams;
|
||||
|
||||
return {
|
||||
@@ -16,6 +15,6 @@ export const load = ({ params = { id: '' } }) => {
|
||||
lessonId,
|
||||
exerciseRouteName,
|
||||
exerciseId,
|
||||
isMaterialsTabActive: !exerciseRouteName,
|
||||
isMaterialsTabActive: !exerciseRouteName
|
||||
};
|
||||
};
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
if (!$course.id) {
|
||||
const { data: _data } = await fetchCourse(data.courseId);
|
||||
|
||||
lessonData = _data.lessons.find(
|
||||
(lesson = { id: '' }) => lesson.id === lessonId
|
||||
);
|
||||
lessonData = _data.lessons.find((lesson = { id: '' }) => lesson.id === lessonId);
|
||||
setCourse(_data);
|
||||
} else if (prevLessonId !== lessonId) {
|
||||
const lesson = await fetchLesson(lessonId);
|
||||
@@ -38,8 +36,7 @@
|
||||
|
||||
prevLessonId = lessonId;
|
||||
|
||||
const totalExercises =
|
||||
lessonData?.totalExercises?.[0] && lessonData.totalExercises[0].count;
|
||||
const totalExercises = lessonData?.totalExercises?.[0] && lessonData.totalExercises[0].count;
|
||||
setLesson(lessonData, totalExercises || 0);
|
||||
isFetching = false;
|
||||
}
|
||||
@@ -51,7 +48,7 @@
|
||||
...l,
|
||||
id: data.lessonId,
|
||||
totalExercises,
|
||||
materials: lessonData,
|
||||
materials: lessonData
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -61,28 +58,22 @@
|
||||
mode = MODES.view;
|
||||
fetchReqData(data.lessonId);
|
||||
}
|
||||
|
||||
$: console.log('data changed', data);
|
||||
</script>
|
||||
|
||||
<CourseContainer
|
||||
{isFetching}
|
||||
{path}
|
||||
isExercisePage={!data.isMaterialsTabActive && data.exerciseId}
|
||||
>
|
||||
<CourseContainer {isFetching} {path} isExercisePage={!data.isMaterialsTabActive && data.exerciseId}>
|
||||
<PageNav
|
||||
navItems={[
|
||||
{
|
||||
label: 'Materials',
|
||||
isActive: data.isMaterialsTabActive,
|
||||
href: path,
|
||||
href: path
|
||||
},
|
||||
{
|
||||
label: 'Exercises',
|
||||
badgeValue: $lesson.totalExercises,
|
||||
isActive: !data.isMaterialsTabActive,
|
||||
href: `${path}/exercises`,
|
||||
},
|
||||
href: `${path}/exercises`
|
||||
}
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="widget">
|
||||
@@ -104,11 +95,7 @@
|
||||
</PageNav>
|
||||
|
||||
{#if !data.isMaterialsTabActive}
|
||||
<Exercises
|
||||
lessonId={data.lessonId}
|
||||
exerciseId={data.exerciseId}
|
||||
path={`${path}/exercises`}
|
||||
/>
|
||||
<Exercises lessonId={data.lessonId} exerciseId={data.exerciseId} path={`${path}/exercises`} />
|
||||
{:else if !!data.lessonId}
|
||||
<PageBody>
|
||||
<Materials lessonId={data.lessonId} {mode} {prevMode} />
|
||||
|
||||
Reference in New Issue
Block a user