feat: multi language support (#254)
* feat: multitranslational support * - completion of settings page - completion of sidebar * sidebar rerendering bug fix * completion of the lesson navigation & materials page * completion of the course navigation * completion of requested languages * - Implementation of Language Picker - Rename Bug Fixes * checkpoint save * - addition of the language picker to the onboarding. - addition of the language switcher for the lesson notes. * merge completion * initialization of the new branch * add transition.svelte file * lesson note bug fix * feat: add translation migration * completion of translation * fix height issue of dropdown * refactoring * fix: improve code with LOCALE from db * finally get it fully functional * connect with AI * backward compatibility for lesson note * preserve old content, when generating AI content * undo translations in upgrade modal * fix duplicate key issue from codacy trigger --------- Co-authored-by: Rotimi Best <best@classroomio.com>
This commit is contained in:
co-authored by
Rotimi Best
parent
ff7d2cee35
commit
d75e2f258e
@@ -16,7 +16,9 @@
|
||||
</script>
|
||||
|
||||
<AddOrgModal />
|
||||
|
||||
<VerifyEmailModal />
|
||||
|
||||
<div class="org-root w-full flex items-center justify-between">
|
||||
{#if !isQuizPage($page.url?.pathname)}
|
||||
<OrgSideBar />
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
// import { supabase } from '$lib/utils/functions/supabase';
|
||||
import { onMount } from 'svelte';
|
||||
import { Add } from 'carbon-icons-svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import UnlockedIcon from 'carbon-icons-svelte/lib/Unlocked.svelte';
|
||||
import LockedIcon from 'carbon-icons-svelte/lib/Locked.svelte';
|
||||
// import Avatar from '$lib/components/Avatar/index.svelte';
|
||||
import { InlineCalendar, Datepicker } from 'svelte-calendar';
|
||||
// import { supabase } from '$lib/utils/functions/supabase';
|
||||
// import Avatar from '$lib/components/Avatar/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { formatUserUpcomingData, formatDate } from '$lib/utils/functions/routes/dashboard';
|
||||
import { user } from '$lib/utils/store/user';
|
||||
import { fetchUserUpcomingData } from '$lib/utils/services/dashboard';
|
||||
import { isMobile } from '$lib/utils/store/useMobile';
|
||||
import type { UserLessonDataType, LessonsByMonthIndexType } from '$lib/utils/types';
|
||||
import WelcomeModal from '$lib/components/WelcomeModal/WelcomeModal.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { Add } from 'carbon-icons-svelte';
|
||||
import { isOrgAdmin, currentOrgPath, currentOrg, userUpcomingData } from '$lib/utils/store/org';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import VisitOrgSiteButton from '$lib/components/Buttons/VisitOrgSite.svelte';
|
||||
import { getGreeting } from '$lib/utils/functions/date';
|
||||
import { globalStore } from '$lib/utils/store/app';
|
||||
import { t } from '$lib/utils/functions/translations.js';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -187,7 +188,7 @@
|
||||
<div class="py-10 px-5 w-full max-w-5xl md:mx-auto">
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold mb-3">
|
||||
{getGreeting()}
|
||||
{$t(getGreeting())}
|
||||
{$profile.fullname}!
|
||||
</h1>
|
||||
<div class="flex items-center">
|
||||
@@ -200,7 +201,7 @@
|
||||
{#if $isMobile}
|
||||
<Add size={24} />
|
||||
{:else}
|
||||
Create Course
|
||||
{$t('dashboard.create_course')}
|
||||
{/if}
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -213,11 +214,10 @@
|
||||
>
|
||||
<span>
|
||||
<p class="w-full md:w-[75%] lg:w-[80%] text-white text-xs lg:text-xl font-normal mb-5">
|
||||
Thank you for what you do ❤️. You are changing lives one classroom at a time and thanks to
|
||||
you, the world is a better place. 😊
|
||||
{$t('dashboard.hero_content')}
|
||||
</p>
|
||||
<PrimaryButton
|
||||
label="Keep Building 🚀"
|
||||
label={$t('dashboard.hero_button')}
|
||||
variant={VARIANTS.CONTAINED_WHITE}
|
||||
onClick={() => goto(`${$currentOrgPath}/courses`)}
|
||||
/>
|
||||
@@ -243,7 +243,7 @@
|
||||
<div class="w-full">
|
||||
<!-- Your Schedule -->
|
||||
<div class="w-full xl:w-auto container">
|
||||
<p class="dark:text-white font-bold mt-7 mb-4">Your Schedule</p>
|
||||
<p class="dark:text-white font-bold mt-7 mb-4">{$t('dashboard.your_schedule')}</p>
|
||||
<div
|
||||
class="rounded border border-gray-200 dark:border-neutral-600 gap-3 flex flex-col md:flex-row items-start px-2 md:px-5 py-5 w-full"
|
||||
>
|
||||
@@ -305,16 +305,16 @@
|
||||
href={!!lessonData.call_url ? lessonData.call_url : undefined}
|
||||
target="_blank"
|
||||
title={!!lessonData.call_url
|
||||
? 'Click to join the call'
|
||||
: 'No call link was added for this lesson. Ask your trainer'}
|
||||
? $t('dashboard.click_to_join')
|
||||
: $t('dashboard.no_call_link')}
|
||||
>
|
||||
Join call
|
||||
{$t('dashboard.join_call')}
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<p class="dark:text-white flex items-center justify-center w-full no-data">
|
||||
No lesson on this day
|
||||
{$t('dashboard.no_schedule')}
|
||||
</p>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import Audience from '$lib/components/Org/Audience/index.svelte';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
import { orgAudience, currentOrgPlan, currentOrgMaxAudience } from '$lib/utils/store/org';
|
||||
import { PLAN } from 'shared-constants/src/plans/constants';
|
||||
import UpgradeBanner from '$lib/components/Upgrade/Banner.svelte';
|
||||
@@ -22,14 +23,19 @@
|
||||
<div class="py-10 px-5">
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<div class="flex items-end">
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold m-0">Audience</h1>
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold m-0">{$t('audience.title')}</h1>
|
||||
{#if $currentOrgPlan?.plan_name !== PLAN.ENTERPRISE}
|
||||
<span class="ml-2">
|
||||
({$orgAudience.length} / {$currentOrgMaxAudience})
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<PrimaryButton label="Export" onClick={exportAudience} isDisabled={isLoading} {isLoading} />
|
||||
<PrimaryButton
|
||||
label={$t('audience.export')}
|
||||
onClick={exportAudience}
|
||||
isDisabled={isLoading}
|
||||
{isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if $orgAudience.length >= $currentOrgMaxAudience}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { currentOrgPath } from '$lib/utils/store/org';
|
||||
import { isMobile } from '$lib/utils/store/useMobile';
|
||||
import Add from 'carbon-icons-svelte/lib/Add.svelte';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
function askCommunity() {
|
||||
goto(`${$currentOrgPath}/community/ask`);
|
||||
@@ -19,14 +20,14 @@
|
||||
<section class="w-full md:max-w-4xl md:mx-auto">
|
||||
<div class="w-full py-10 px-5">
|
||||
<div class="flex items-center justify-between mb-10 w-full">
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">Community</h1>
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">{$t('community.title')}</h1>
|
||||
{#if $isMobile}
|
||||
<PrimaryButton onClick={askCommunity}>
|
||||
<Add size={24} />
|
||||
</PrimaryButton>
|
||||
{:else}
|
||||
<PrimaryButton
|
||||
label="Ask Community"
|
||||
label={$t('community.ask_button')}
|
||||
variant={VARIANTS.CONTAINED_DARK}
|
||||
onClick={askCommunity}
|
||||
/>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
import { calDateDiff } from '$lib/utils/functions/date';
|
||||
import { browser } from '$app/environment';
|
||||
import { fetchCourses } from '$lib/components/Courses/api.js';
|
||||
import { t } from '$lib/utils/functions/translations.js';
|
||||
|
||||
export let data;
|
||||
const { slug } = data;
|
||||
@@ -177,11 +178,11 @@
|
||||
|
||||
if (error) {
|
||||
console.error('Error: commenting', error);
|
||||
snackbar.error('Error - Please try again later');
|
||||
snackbar.error('snackbar.community.error.try_again');
|
||||
} else {
|
||||
console.log('Success: commenting', data);
|
||||
|
||||
snackbar.success('Comment Submitted!');
|
||||
snackbar.success('snackbar.community.success.comment_submitted');
|
||||
|
||||
// Add to comment
|
||||
const _c = data?.[0];
|
||||
@@ -229,7 +230,7 @@
|
||||
const { error } = await supabase.from(table).update({ votes }).match({ id: matchId });
|
||||
if (error) {
|
||||
console.error('Error: upvoteQuestion', error);
|
||||
snackbar.error('Error - Please try again later');
|
||||
snackbar.error('snackbar.community.error.try_again');
|
||||
} else {
|
||||
if (isQuestion) {
|
||||
voted.question = true;
|
||||
@@ -262,13 +263,14 @@
|
||||
const { error } = await supabase
|
||||
.from('community_question')
|
||||
.update({
|
||||
...editContent,
|
||||
title: editContent.title,
|
||||
body: editContent.body,
|
||||
course_id: editContent.courseId
|
||||
})
|
||||
.match({ id: question.id });
|
||||
if (error) {
|
||||
console.error('Error: handleQuestionEdit', error);
|
||||
snackbar.error('Error - Please try again later');
|
||||
snackbar.error('snackbar.community.error.try_again');
|
||||
} else {
|
||||
question.title = editContent.title;
|
||||
question.body = editContent.body;
|
||||
@@ -297,11 +299,11 @@
|
||||
deleteComment.isDeleting = false;
|
||||
|
||||
if (error) {
|
||||
snackbar.error('Error deleting comments');
|
||||
snackbar.error('snackbar.community.error.deleting_comments');
|
||||
console.log('Error deleting comments', error);
|
||||
return;
|
||||
}
|
||||
snackbar.success('Deleted successfully');
|
||||
snackbar.success('snackbar.community.success.success_delete');
|
||||
|
||||
question.comments = question.comments.filter((c) => c.id !== deleteComment.commentId);
|
||||
deleteComment.shouldDelete = false;
|
||||
@@ -318,7 +320,7 @@
|
||||
.match({ question_id: deleteQuestion.questionId });
|
||||
|
||||
if (commentDeleteError) {
|
||||
snackbar.error('Error deleting comments');
|
||||
snackbar.error('snackbar.community.error.deleting_comments');
|
||||
console.log('Error deleting comments', commentDeleteError);
|
||||
|
||||
deleteQuestion.isDeleting = false;
|
||||
@@ -331,12 +333,12 @@
|
||||
.match({ id: deleteQuestion.questionId });
|
||||
|
||||
if (questionDeleteError) {
|
||||
snackbar.error('Error deleting question');
|
||||
snackbar.error('snackbar.community.error.deleting_question');
|
||||
console.log('Error deleting question', questionDeleteError);
|
||||
return;
|
||||
}
|
||||
|
||||
snackbar.success('Deleted successfully');
|
||||
snackbar.success('snackbar.community.success.success_delete');
|
||||
goto(`${$currentOrgPath}/community`);
|
||||
deleteQuestion.isDeleting = false;
|
||||
}
|
||||
@@ -350,7 +352,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{question?.title || 'Question'}</title>
|
||||
<title>{question?.title || $t('community.ask.question')}</title>
|
||||
</svelte:head>
|
||||
|
||||
<DeleteModal
|
||||
@@ -398,7 +400,7 @@
|
||||
<Dropdown
|
||||
class="w-[25%] h-full"
|
||||
size="xl"
|
||||
label="Select Course"
|
||||
label={$t('community.ask.select_course')}
|
||||
items={fetchedCourses.map((course) => ({ id: course.id, text: course.title }))}
|
||||
bind:selectedId={editContent.courseId}
|
||||
/>
|
||||
@@ -415,14 +417,14 @@
|
||||
|
||||
{#if question.author.id === $profile.id}
|
||||
<PrimaryButton
|
||||
label={isEditMode ? 'Save' : 'Edit'}
|
||||
label={isEditMode ? $t('community.ask.save') : $t('community.ask.edit')}
|
||||
variant={VARIANTS.OUTLINED}
|
||||
onClick={handleQuestionEdit}
|
||||
className="h-fit"
|
||||
/>
|
||||
{#if isEditMode}
|
||||
<PrimaryButton
|
||||
label="Cancel"
|
||||
label={$t('community.ask.cancel')}
|
||||
variant={VARIANTS.TEXT}
|
||||
onClick={() => (isEditMode = !isEditMode)}
|
||||
className="py-3 px-6 rounded-sm h-fit"
|
||||
@@ -461,7 +463,7 @@
|
||||
<div class="my-2">
|
||||
<TextEditor
|
||||
bind:value={editContent.body}
|
||||
placeholder="Give an answer"
|
||||
placeholder={$t('community.ask.give')}
|
||||
onChange={(html) => (editContent.body = html)}
|
||||
/>
|
||||
</div>
|
||||
@@ -522,13 +524,13 @@
|
||||
{#if !editorInstance}
|
||||
<TextEditor
|
||||
bind:value={comment}
|
||||
placeholder="Give an answer"
|
||||
placeholder={$t('community.ask.give')}
|
||||
onChange={(html) => (comment = html)}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<div class="flex justify-end mr-2">
|
||||
<PrimaryButton label="Comment" onClick={submitComment} />
|
||||
<PrimaryButton label={$t('community.ask.comment')} onClick={submitComment} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { fetchCourses } from '$lib/components/Courses/api';
|
||||
import { t } from '$lib/utils/functions/translations.js';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -26,10 +27,12 @@
|
||||
courseId: ''
|
||||
};
|
||||
|
||||
let fetchedCourses = [];
|
||||
let fetchedCourses: any[] = [];
|
||||
|
||||
async function getCourses(userId: string | null, orgId: string) {
|
||||
const coursesResults = await fetchCourses(userId, orgId);
|
||||
if (!coursesResults) return;
|
||||
|
||||
fetchedCourses = coursesResults.allCourses;
|
||||
}
|
||||
|
||||
@@ -56,12 +59,12 @@
|
||||
|
||||
if (error) {
|
||||
console.error('Error: asking question', error);
|
||||
snackbar.error('Error - Please try again later');
|
||||
snackbar.error('snackbar.community.error.try_again');
|
||||
} else {
|
||||
const slug = question[0]?.slug;
|
||||
|
||||
console.log('Success: asking question', question, slug);
|
||||
snackbar.success('Question Submitted!');
|
||||
snackbar.success('snackbar.community.success.question_submitted');
|
||||
goto(`${$currentOrgPath}/community/${slug}`);
|
||||
}
|
||||
}
|
||||
@@ -83,25 +86,30 @@
|
||||
class="text-gray-500 dark:text-white text-md flex items-center"
|
||||
href={`${$currentOrgPath}/community`}
|
||||
>
|
||||
<ArrowLeftIcon size={24} class="carbon-icon dark:text-white" /> Go Back
|
||||
<ArrowLeftIcon size={24} class="carbon-icon dark:text-white" />
|
||||
{$t('community.ask.go_back')}
|
||||
</a>
|
||||
<div class="flex items-center gap-12 justify-between">
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">Ask the community</h1>
|
||||
<PrimaryButton label="Publish" variant={VARIANTS.CONTAINED_DARK} onClick={handleSave} />
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">{$t('community.ask.ask_the')}</h1>
|
||||
<PrimaryButton
|
||||
label={$t('community.ask.publish')}
|
||||
variant={VARIANTS.CONTAINED_DARK}
|
||||
onClick={handleSave}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 p-2 flex gap-x-5 justify-between">
|
||||
<TextField
|
||||
bind:value={fields.title}
|
||||
placeholder="Title"
|
||||
placeholder={$t('community.ask.title')}
|
||||
errorMessage={errors.title}
|
||||
className="w-[75%]"
|
||||
/>
|
||||
<Dropdown
|
||||
class="w-[25%]"
|
||||
class="w-[25%] h-full"
|
||||
size="xl"
|
||||
label="Select Course"
|
||||
label={$t('community.ask.select_course')}
|
||||
invalid={!!errors.courseId}
|
||||
invalidText={errors.courseId}
|
||||
items={fetchedCourses.map((course) => ({ id: course.id, text: course.title }))}
|
||||
@@ -111,7 +119,7 @@
|
||||
<div class="px-2">
|
||||
<TextEditor
|
||||
bind:value={fields.body}
|
||||
placeholder="Ask the community any question you might have"
|
||||
placeholder={$t('community.ask.ask_community')}
|
||||
onChange={(html) => (fields.body = html)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import { isOrgAdmin } from '$lib/utils/store/org';
|
||||
import type { Course } from '$lib/utils/types';
|
||||
import { browser } from '$app/environment';
|
||||
import { t } from '$lib/utils/functions/translations.js';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
|
||||
export let data;
|
||||
@@ -86,14 +87,14 @@
|
||||
<section class="w-full md:max-w-6xl md:mx-auto">
|
||||
<div class="py-2 md:py-10 px-2 md:px-5">
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">Courses</h1>
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">{$t('courses.heading')}</h1>
|
||||
{#if $isMobile}
|
||||
<PrimaryButton isDisabled={!$isOrgAdmin} onClick={() => ($createCourseModal.open = true)}>
|
||||
<Add size={24} />
|
||||
</PrimaryButton>
|
||||
{:else}
|
||||
<PrimaryButton
|
||||
label="Create Course"
|
||||
label={$t('courses.heading_button')}
|
||||
variant={VARIANTS.CONTAINED_DARK}
|
||||
isDisabled={!$isOrgAdmin}
|
||||
onClick={() => ($createCourseModal.open = true)}
|
||||
@@ -101,9 +102,9 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-row-reverse mb-5">
|
||||
<div class="flex items-end justify-start">
|
||||
<div class="filter-containter flex items-end justify-start">
|
||||
<Search
|
||||
placeholder="Find course"
|
||||
placeholder={$t('courses.search_placeholder')}
|
||||
bind:value={searchValue}
|
||||
searchClass="mr-2"
|
||||
class=" bg-gray-100 dark:bg-neutral-800"
|
||||
@@ -112,9 +113,9 @@
|
||||
class="h-full"
|
||||
bind:selectedId
|
||||
items={[
|
||||
{ id: '0', text: 'Date Created' },
|
||||
{ id: '1', text: 'Published' },
|
||||
{ id: '2', text: 'Lessons' }
|
||||
{ id: '0', text: $t('courses.course_filter.date_created') },
|
||||
{ id: '1', text: $t('courses.course_filter.published') },
|
||||
{ id: '2', text: $t('courses.course_filter.lessons') }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -127,7 +128,7 @@
|
||||
</section>
|
||||
|
||||
<style>
|
||||
:global(.bx--dropdown) {
|
||||
.filter-containter :global(.bx--dropdown) {
|
||||
max-height: unset;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -146,10 +146,10 @@
|
||||
console.log('data', data);
|
||||
console.log('error', error);
|
||||
if (error) {
|
||||
snackbar.error("Something's not right - Please try later");
|
||||
snackbar.error('snackbar.course_settings.error.not_right');
|
||||
return;
|
||||
} else {
|
||||
snackbar.success('Saved Successfully');
|
||||
snackbar.success('snackbar.course_settings.success.saved');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import OrgSettings from '$lib/components/Org/Settings/index.svelte';
|
||||
import ViewSiteBtn from '$lib/components/Buttons/VisitOrgSite.svelte';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -10,7 +11,7 @@
|
||||
<section class="w-full md:max-w-4xl mx-auto">
|
||||
<div class="py-10 px-5">
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<h1 class="dark:text-white text-3xl font-bold">Settings</h1>
|
||||
<h1 class="dark:text-white text-3xl font-bold">{$t('settings.heading')}</h1>
|
||||
|
||||
<ViewSiteBtn />
|
||||
</div>
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
import Chip from '$lib/components/Chip/Text.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import StepDoneIcon from '$lib/components/Icons/StepDoneIcon.svelte';
|
||||
import CheckmarkOutline from 'carbon-icons-svelte/lib/CheckmarkOutline.svelte';
|
||||
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { goto } from '$app/navigation';
|
||||
import { snackbar } from '$lib/components/Snackbar/store.js';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
export let data;
|
||||
let setupList = data.setup || [];
|
||||
@@ -24,7 +24,7 @@
|
||||
};
|
||||
|
||||
const isCompleted = (id) => {
|
||||
return setupList?.find((c) => c.id === id).is_completed == true;
|
||||
return setupList?.find((c) => c.id === id)?.is_completed == true;
|
||||
};
|
||||
|
||||
const handleClick = (title) => {
|
||||
@@ -38,7 +38,7 @@
|
||||
const courseId = data?.courses[0].id;
|
||||
goto(`/courses/${courseId}/lessons`);
|
||||
} else {
|
||||
snackbar.info('You need to create a course');
|
||||
snackbar.info('setup.info_course');
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
const lessonId = data?.lessons[0].id;
|
||||
goto(`/courses/${courseId}/lessons/${lessonId}`);
|
||||
} else {
|
||||
snackbar.info('You Need to Create a lesson');
|
||||
snackbar.info('setup.info_lesson');
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
const courseId = data?.courses[0].id;
|
||||
goto(`/courses/${courseId}/settings`);
|
||||
} else {
|
||||
snackbar.info('You need to create a course');
|
||||
snackbar.info('setup.info_course');
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<section class="w-full md:max-w-4xl mx-auto">
|
||||
<div class="py-2 md:py-10 px-2 md:px-5">
|
||||
<div class="flex items-center gap-2">
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">Get Started</h1>
|
||||
<h1 class="dark:text-white text-2xl md:text-3xl font-bold">{$t('setup.get_started')}</h1>
|
||||
<Chip
|
||||
value={`${completed}/${setupList.length}`}
|
||||
className="text-[10px] font-semibold px-3 !py-1"
|
||||
@@ -104,9 +104,11 @@
|
||||
className={`text-[10px] font-semibold !py-1 `}
|
||||
shape="rounded-full"
|
||||
/>
|
||||
<p class="font-medium text-lg">{list.title}</p>
|
||||
<p class="font-medium text-lg">{$t(list.title)}</p>
|
||||
</div>
|
||||
<p class={`text-sm`}>{list.desc}</p>
|
||||
<p class={`text-sm`}>
|
||||
{$t(list.desc)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-full lg:w-[30%]">
|
||||
<PrimaryButton
|
||||
@@ -118,7 +120,7 @@
|
||||
{#if list.is_completed}
|
||||
<CheckmarkOutline />
|
||||
{/if}
|
||||
{list.button_label}
|
||||
{$t(list.button_label)}
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -95,45 +95,45 @@ export const load = async ({ params = { slug: '' } }) => {
|
||||
const data = [
|
||||
{
|
||||
id: 'profile',
|
||||
title: 'Upload a profile picture and update username',
|
||||
desc: 'Personalize and a human touch making interactions more personal and memorable',
|
||||
title: 'setup.1.title',
|
||||
desc: 'setup.1.desc',
|
||||
is_completed: false,
|
||||
button_label: 'Update Profile'
|
||||
button_label: 'setup.1.button_label'
|
||||
},
|
||||
{
|
||||
id: 'organization',
|
||||
title: 'Update organisation profile picture',
|
||||
desc: 'Establish a professional and recognizable identity for your organization',
|
||||
title: 'setup.2.title',
|
||||
desc: 'setup.2.desc',
|
||||
is_completed: orgHasAvatarUrl,
|
||||
button_label: 'Update Org Profile'
|
||||
button_label: 'setup.2.button_label'
|
||||
},
|
||||
{
|
||||
id: 'course',
|
||||
title: 'Create Course',
|
||||
desc: 'Create a course that you will share with your students',
|
||||
title: 'setup.3.title',
|
||||
desc: 'setup.4.desc',
|
||||
is_completed: isCourseCreated,
|
||||
button_label: 'Create Course'
|
||||
button_label: 'setup.3.button_label'
|
||||
},
|
||||
{
|
||||
id: 'lesson',
|
||||
title: 'Create a lesson',
|
||||
desc: 'Break your course into lesson that your students can easily understand',
|
||||
title: 'setup.4.title',
|
||||
desc: 'setup.4.desc',
|
||||
is_completed: isLessonCreated,
|
||||
button_label: 'Create Lesson'
|
||||
button_label: 'setup.4.button_label'
|
||||
},
|
||||
{
|
||||
id: 'exercise',
|
||||
title: 'Create an exercise',
|
||||
desc: 'Test your students allow them to demonstarte their understanding of the subject matter',
|
||||
title: 'setup.5.title',
|
||||
desc: 'setup.5.desc',
|
||||
is_completed: isExerciseCreated,
|
||||
button_label: 'Create Assignment'
|
||||
button_label: 'setup.5.button_label'
|
||||
},
|
||||
{
|
||||
id: 'publish',
|
||||
title: 'Publish a course',
|
||||
desc: 'Make your course public and purchaseable ',
|
||||
title: 'setup.6.title',
|
||||
desc: 'setup.6.desc',
|
||||
is_completed: isCoursePublished,
|
||||
button_label: 'Publish Course'
|
||||
button_label: 'setup.6.button_label'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user