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
@@ -13,6 +13,7 @@
|
||||
import CopyFile from 'carbon-icons-svelte/lib/CopyFile.svelte';
|
||||
import Share from 'carbon-icons-svelte/lib/Share.svelte';
|
||||
import UserFollow from 'carbon-icons-svelte/lib/UserFollow.svelte';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
export let bannerImage: string | undefined;
|
||||
export let id = '';
|
||||
@@ -55,11 +56,30 @@
|
||||
|
||||
{#if showContextMenu}
|
||||
<ContextMenu {target}>
|
||||
<ContextMenuOption indented labelText="Clone" icon={CopyFile} on:click={handleCloneCourse} />
|
||||
<ContextMenuOption indented labelText="Share" icon={Share} on:click={handleShareCourse} />
|
||||
<ContextMenuOption indented labelText="Invite" icon={UserFollow} on:click={handleInvite} />
|
||||
<ContextMenuOption
|
||||
indented
|
||||
labelText={$t('courses.lesson_card.context_menu.clone')}
|
||||
icon={CopyFile}
|
||||
on:click={handleCloneCourse}
|
||||
/>
|
||||
<ContextMenuOption
|
||||
indented
|
||||
labelText={$t('courses.lesson_card.context_menu.share')}
|
||||
icon={Share}
|
||||
on:click={handleShareCourse}
|
||||
/>
|
||||
<ContextMenuOption
|
||||
indented
|
||||
labelText={$t('courses.lesson_card.context_menu.invite')}
|
||||
icon={UserFollow}
|
||||
on:click={handleInvite}
|
||||
/>
|
||||
<ContextMenuDivider />
|
||||
<ContextMenuOption kind="danger" labelText="Delete" on:click={handleDeleteCourse} />
|
||||
<ContextMenuOption
|
||||
kind="danger"
|
||||
labelText={$t('courses.lesson_card.context_menu.delete')}
|
||||
on:click={handleDeleteCourse}
|
||||
/>
|
||||
</ContextMenu>
|
||||
{/if}
|
||||
|
||||
@@ -79,7 +99,7 @@
|
||||
<svelte:fragment slot="loading">
|
||||
<SkeletonPlaceholder style="width: 100%; height: 200px;" />
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="error">An error occurred.</svelte:fragment>
|
||||
<svelte:fragment slot="error">{$t('courses.lesson_card.error_message')}</svelte:fragment>
|
||||
</ImageLoader>
|
||||
</div>
|
||||
|
||||
@@ -94,7 +114,10 @@
|
||||
'items-center'}"
|
||||
>
|
||||
<div>
|
||||
<p class="text-xs pt-2 {!isLMS && 'pl-2'} dark:text-white">{totalLessons} lessons</p>
|
||||
<p class="text-xs pt-2 {!isLMS && 'pl-2'} dark:text-white">
|
||||
{totalLessons}
|
||||
{$t('courses.lesson_card.lessons_number')}
|
||||
</p>
|
||||
<p class="text-xs py-2">
|
||||
{#if isOnLandingPage}
|
||||
<span class="px-2">{!cost ? 'Free' : formatter.format(cost)}</span>
|
||||
@@ -111,9 +134,9 @@
|
||||
{:else}
|
||||
<Tag type={isPublished ? 'green' : 'cool-gray'}>
|
||||
{#if isPublished}
|
||||
Published
|
||||
{$t('courses.lesson_card.published')}
|
||||
{:else}
|
||||
Unpublished
|
||||
{$t('courses.lesson_card.unpublished')}
|
||||
{/if}
|
||||
</Tag>
|
||||
{/if}
|
||||
@@ -122,13 +145,16 @@
|
||||
|
||||
{#if isLMS}
|
||||
<PrimaryButton
|
||||
label="Continue Course"
|
||||
label={$t('courses.lesson_card.continue_course')}
|
||||
variant={VARIANTS.OUTLINED}
|
||||
className="rounded-none text-primary-600"
|
||||
/>
|
||||
{:else if !isOnLandingPage}
|
||||
<div class="flex flex-col justify-between">
|
||||
<p class="text-xs pt-2 pl-2 dark:text-white">{totalStudents} students</p>
|
||||
<p class="text-xs pt-2 pl-2 dark:text-white">
|
||||
{totalStudents}
|
||||
{$t('courses.lesson_card.students')}
|
||||
</p>
|
||||
<div></div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { goto } from '$app/navigation';
|
||||
import { capturePosthogEvent } from '$lib/utils/services/posthog';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
let isLoading = false;
|
||||
let errors = {
|
||||
@@ -118,13 +119,13 @@
|
||||
{onClose}
|
||||
bind:open={$createCourseModal.open}
|
||||
width="w-4/5 md:w-2/5"
|
||||
modalHeading="Create a Course"
|
||||
modalHeading={$t('courses.new_course_modal.heading')}
|
||||
>
|
||||
<form on:submit|preventDefault={createCourse}>
|
||||
<TextField
|
||||
label="Course name"
|
||||
label={$t('courses.new_course_modal.course_name')}
|
||||
bind:value={$createCourseModal.title}
|
||||
placeholder="Your course name"
|
||||
placeholder={$t('courses.new_course_modal.course_name_placeholder')}
|
||||
className="mb-4"
|
||||
isRequired={true}
|
||||
errorMessage={errors.title}
|
||||
@@ -132,10 +133,10 @@
|
||||
/>
|
||||
|
||||
<TextArea
|
||||
label="Short description"
|
||||
label={$t('courses.new_course_modal.short_description')}
|
||||
bind:value={$createCourseModal.description}
|
||||
rows={4}
|
||||
placeholder="A little description about this course"
|
||||
placeholder={$t('courses.new_course_modal.short_description_placeholder')}
|
||||
className="mb-4"
|
||||
isRequired={true}
|
||||
errorMessage={errors.description}
|
||||
@@ -146,7 +147,7 @@
|
||||
<div class="mt-5 flex items-center">
|
||||
<PrimaryButton
|
||||
className="px-6 py-3"
|
||||
label="Finish"
|
||||
label={$t('courses.new_course_modal.button')}
|
||||
type="submit"
|
||||
isDisabled={isLoading}
|
||||
{isLoading}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
import { courseMetaDeta } from './store';
|
||||
import type { Course } from '$lib/utils/types';
|
||||
import { globalStore } from '$lib/utils/store/app';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
export let courses: Course[] = [];
|
||||
export let emptyTitle = 'No Courses Created';
|
||||
export let emptyDescription =
|
||||
'Share your knowledge with the world by creating engaging courses for your students.';
|
||||
export let emptyTitle = $t('courses.lesson_card.empty_title');
|
||||
export let emptyDescription = $t('courses.lesson_card.empty_description');
|
||||
|
||||
function calcProgressRate(progressRate?: number, totalLessons?: number): number {
|
||||
if (!progressRate || !totalLessons) {
|
||||
|
||||
Reference in New Issue
Block a user