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:
Adeyemi Adetunji
2024-04-19 05:45:48 +01:00
committed by GitHub
co-authored by Rotimi Best
parent ff7d2cee35
commit d75e2f258e
153 changed files with 11264 additions and 1130 deletions
@@ -10,5 +10,5 @@ export const calDateDiff = (date: string | number | Date): string => {
export const getGreeting = () => {
const date = new Date();
const hours = date.getHours();
return hours < 12 ? 'Good Morning' : hours < 18 ? 'Good Afternoon' : 'Good Evening';
return hours < 12 ? 'dashboard.morning_heading' : hours < 18 ? 'dashboard.afternoon_heading' : 'dashboard.evening_heading';
};
@@ -0,0 +1,104 @@
import { writable } from 'svelte/store';
import i18n, { type Config } from 'sveltekit-i18n';
import { LOCALE } from '$lib/utils/types';
interface Params {
dateValue: number;
value: number;
download: number;
award: number;
val: Date;
}
const config: Config<Partial<Params>> = {
initLocale: 'en',
// parser: parser(),
loaders: [
{
locale: 'en',
key: '',
loader: async () => (await import('../translations/en.json')).default
},
{
locale: 'hi',
key: '',
loader: async () => (await import('../translations/hi.json')).default
},
{
locale: 'fr',
key: '',
loader: async () => (await import('../translations/fr.json')).default
},
{
locale: 'pt',
key: '',
loader: async () => (await import('../translations/pt.json')).default
},
{
locale: 'de',
key: '',
loader: async () => (await import('../translations/de.json')).default
},
{
locale: 'vi',
key: '',
loader: async () => (await import('../translations/vi.json')).default
},
{
locale: 'ru',
key: '',
loader: async () => (await import('../translations/ru.json')).default
},
{
locale: 'es',
key: '',
loader: async () => (await import('../translations/es.json')).default
}
]
};
export const { t, loading, locales, locale, initialized, translations, loadTranslations } =
new i18n(config);
export const selectedLocale = writable<string>('en');
// Translations logs
loading.subscribe(async ($loading) => {
if ($loading) {
console.log('Loading translations...');
await loading.toPromise();
}
});
export async function handleLocaleChange(newLocale) {
if (!newLocale) {
return;
}
locale.set(newLocale);
await fetch('/api/i18n', {
body: JSON.stringify({ locale: newLocale }),
method: 'POST'
});
}
export function lessonFallbackNote(
note: string,
translation: Record<LOCALE, string>,
locale: LOCALE
) {
if (!translation) {
return note;
}
const content = translation[locale];
// if locale is english and no translated content for english but note exists
if (locale === LOCALE.EN && !content && note?.length) {
return note;
}
return content;
}