feat: automatically detect language on server and translate UI (#530)

* feat: detect language on the server and translate page

* translate auth pages

* PR reviews
This commit is contained in:
Rotimi Best
2024-12-28 23:11:55 +01:00
committed by GitHub
parent 1f1ee8afd3
commit 381776f388
24 changed files with 431 additions and 232 deletions
@@ -76,7 +76,10 @@ export async function getProfile({
}
// Skip refetching profile, if already in store
if (profileStore.id) return;
if (profileStore.id) {
handleLocaleChange(profileStore.locale);
return;
}
// Check if user has profile
let {
@@ -124,7 +127,7 @@ export async function getProfile({
setAnalyticsUser();
// Fetch language
handleLocaleChange(profileStore.locale);
handleLocaleChange(newProfileData[0].locale);
if (isOrgSite) {
const { data, error } = await supabase
@@ -179,8 +182,7 @@ export async function getProfile({
// Set user in sentry
setAnalyticsUser();
// Fetch language
handleLocaleChange(profileStore.locale);
handleLocaleChange(profileData.locale);
const orgRes = await getOrganizations(profileData.id, isOrgSite, orgSiteName);
@@ -1,6 +1,6 @@
import { LOCALE } from '$lib/utils/types';
import { writable } from 'svelte/store';
import i18n, { type Config } from 'sveltekit-i18n';
import { LOCALE } from '$lib/utils/types';
interface Params {
dateValue: number;
@@ -10,8 +10,7 @@ interface Params {
val: Date;
}
const config: Config<Partial<Params>> = {
initLocale: 'en',
export const config: Config<Partial<Params>> = {
// parser: parser(),
loaders: [
{
@@ -1,7 +1,7 @@
import { t } from '$lib/utils/functions/translations';
import isNumber from 'lodash/isNumber';
import z from 'zod';
import { validateEmail } from './validateEmail';
import { t } from '$lib/utils/functions/translations';
const getOrgNameValidation = () =>
z
@@ -85,12 +85,12 @@ const forgotValidationSchema = z.object({
const authValidationSchema = z.object({
email: z.string().email({
message: `${t.get('validations.auth.email.invalid_email')}`,
invalid_type_error: `${t.get('validations.invalid_type_error')}`
message: 'validations.auth.email.invalid_email',
invalid_type_error: 'validations.invalid_type_error'
}),
password: z.string().min(6, {
message: `${t.get('validations.auth.password.min_char')}`,
invalid_type_error: `${t.get('validations.invalid_type_error')}`
message: 'validations.auth.password.min_char',
invalid_type_error: 'validations.invalid_type_error'
})
});
@@ -1,21 +1,21 @@
import { get } from 'svelte/store';
import { supabase } from '$lib/utils/functions/supabase';
import { isUUID } from '$lib/utils/functions/isUUID';
import { QUESTION_TYPE } from '$lib/components/Question/constants';
import { STATUS } from '$lib/utils/constants/course';
import { isUUID } from '$lib/utils/functions/isUUID';
import { supabase } from '$lib/utils/functions/supabase';
import { isOrgAdmin } from '$lib/utils/store/org';
import type {
Lesson,
Course,
Exercise,
ExerciseTemplate,
Group,
Groupmember,
Exercise,
Lesson,
LessonCompletion,
ExerciseTemplate,
LessonSection
LessonSection,
ProfileCourseProgress
} from '$lib/utils/types';
import { STATUS } from '$lib/utils/constants/course';
import type { PostgrestSingleResponse, PostgrestError } from '@supabase/supabase-js';
import type { ProfileCourseProgress } from '$lib/utils/types';
import { isOrgAdmin } from '$lib/utils/store/org';
import type { PostgrestError, PostgrestSingleResponse } from '@supabase/supabase-js';
import { get } from 'svelte/store';
export async function fetchCourses(profileId, orgId) {
if (!orgId || !profileId) return;
@@ -144,10 +144,7 @@ export async function fetchCourse(courseId?: Course['id'], slug?: Course['slug']
const { data, error } = response;
console.log(`error`, error);
console.log(`data`, data);
if (!data || error) {
console.log(`data`, data);
console.log(`fetchCourse => error`, error);
// return this.redirect(307, '/courses');
return { data, error };
@@ -1,11 +1,11 @@
import { get } from 'svelte/store';
import type { PostgrestError } from '@supabase/supabase-js';
import { goto } from '$app/navigation';
import { supabase } from '$lib/utils/functions/supabase';
import { orgs, currentOrg, orgAudience, orgTeam } from '$lib/utils/store/org';
import { ROLE, ROLE_LABEL } from '$lib/utils/constants/roles';
import type { CurrentOrg, OrgTeamMember } from '$lib/utils/types/org';
import { supabase } from '$lib/utils/functions/supabase';
import { currentOrg, orgAudience, orgs, orgTeam } from '$lib/utils/store/org';
import type { OrganizationPlan } from '$lib/utils/types';
import type { CurrentOrg, OrgTeamMember } from '$lib/utils/types/org';
import type { PostgrestError } from '@supabase/supabase-js';
import { get } from 'svelte/store';
export async function getOrgTeam(orgId: string) {
const { data, error } = await supabase
@@ -164,8 +164,6 @@ export async function getOrgAudience(orgId: string) {
.eq('groupmember.group.organization_id', orgId)
.eq('groupmember.role_id', ROLE.STUDENT);
console.log('data', data);
const audience = (data || []).map((profile) => ({
id: profile.id,
name: profile.fullname,
@@ -1293,7 +1293,29 @@
"email": "Deine E-Mail",
"password": "Ihr Passwort",
"forgot": "Passwort vergessen?",
"login": "Anmeldung"
"login": "Anmeldung",
"login_with": "oder loggen Sie sich mit ein",
"signup_with": "oder melden Sie sich an",
"already_have_account": "Sie haben bereits ein Konto?",
"not_registered_yet": "Noch nicht registriert?",
"signup": "Melden Sie sich an",
"signup_with_google": "Melden Sie sich bei Google an",
"login_with_google": "Melden Sie sich mit Google an",
"create_to_join": "Erstellen Sie ein kostenloses Konto, um Mitglied zu werden",
"login_to_join": "Melden Sie sich an, um beizutreten",
"validation": {
"unable_to_create_profile": "Profil kann nicht erstellt werden",
"user_cannot_be_created": "Benutzer kann nicht erstellt werden"
},
"fields": {
"email": "Ihre E-Mail",
"full_name": "Vollständiger Name",
"password": "Ihr Passwort",
"confirm_password": "Passwort bestätigen",
"password_helper_message": "Das Passwort muss mehr als 6 Zeichen lang sein",
"create_account": "Benutzerkonto erstellen"
},
"create_account": "Benutzerkonto erstellen"
},
"welcome_modal": {
"we_at": "Wir bei",
@@ -49,7 +49,29 @@
"email": "Your email",
"password": "Your password",
"forgot": "Forgot password?",
"login": "Log In"
"login": "Log In",
"login_with": "or login with",
"signup_with": "or sign up with",
"already_have_account": "Already have an account?",
"not_registered_yet": "Not registered yet?",
"signup": "Sign up",
"signup_with_google": "Sign up with Google",
"login_with_google": "Login with Google",
"create_to_join": "Create a free account to join",
"create_account": "Create Account",
"login_to_join": "Log in to join",
"fields": {
"email": "Your Email",
"full_name": "Full Name",
"password": "Your Password",
"confirm_password": "Confirm Password",
"password_helper_message": "Password must be more than 6 characters",
"create_account": "Create Account"
},
"validation": {
"unable_to_create_profile": "Unable to create profile",
"user_cannot_be_created": "User cannot be created"
}
},
"profileMenu": {
"profile": "PROFILE",
@@ -1293,7 +1293,29 @@
"email": "Tu correo electrónico",
"password": "Tu contraseña",
"forgot": "¿Has olvidado tu contraseña?",
"login": "Acceso"
"login": "Acceso",
"login_with": "o inicia sesión con",
"signup_with": "o regístrate con",
"already_have_account": "¿Ya tienes una cuenta?",
"not_registered_yet": "¿Aún no estás registrado?",
"signup": "Inscribirse",
"signup_with_google": "Regístrate con Google",
"login_with_google": "Iniciar sesión con Google",
"create_to_join": "Crea una cuenta gratuita para unirte",
"login_to_join": "Inicia sesión para unirte",
"validation": {
"unable_to_create_profile": "No se puede crear el perfil",
"user_cannot_be_created": "No se puede crear usuario"
},
"fields": {
"email": "Tu correo electrónico",
"full_name": "Nombre completo",
"password": "Tu contraseña",
"confirm_password": "confirmar Contraseña",
"password_helper_message": "La contraseña debe tener más de 6 caracteres.",
"create_account": "Crear una cuenta"
},
"create_account": "Crear una cuenta"
},
"welcome_modal": {
"we_at": "nosotros en",
@@ -1293,7 +1293,29 @@
"email": "Votre email",
"password": "Votre mot de passe",
"forgot": "Mot de passe oublié?",
"login": "Se connecter"
"login": "Se connecter",
"login_with": "ou connectez-vous avec",
"signup_with": "ou inscrivez-vous avec",
"already_have_account": "Vous avez déjà un compte ?",
"not_registered_yet": "Pas encore inscrit ?",
"signup": "S'inscrire",
"signup_with_google": "Inscrivez-vous avec Google",
"login_with_google": "Connectez-vous avec Google",
"create_to_join": "Créez un compte gratuit pour vous inscrire",
"login_to_join": "Connectez-vous pour rejoindre",
"validation": {
"unable_to_create_profile": "Impossible de créer un profil",
"user_cannot_be_created": "L'utilisateur ne peut pas être créé"
},
"fields": {
"email": "Votre e-mail",
"full_name": "Nom et prénom",
"password": "Votre mot de passe",
"confirm_password": "Confirmez le mot de passe",
"password_helper_message": "Le mot de passe doit comporter plus de 6 caractères",
"create_account": "Créer un compte"
},
"create_account": "Créer un compte"
},
"welcome_modal": {
"we_at": "Nous à",
@@ -1293,7 +1293,29 @@
"email": "आपका ईमेल",
"password": "आपका पासवर्ड",
"forgot": "पासवर्ड भूल गए?",
"login": "लॉग इन करें"
"login": "लॉग इन करें",
"login_with": "या के साथ लॉगिन करें",
"signup_with": "या इसके साथ साइन अप करें",
"already_have_account": "क्या आपके पास पहले से एक खाता मौजूद है?",
"not_registered_yet": "अभी तक पंजीकृत नहीं हैं?",
"signup": "साइन अप करें",
"signup_with_google": "Google के साथ साइन अप करें",
"login_with_google": "गूगल से लॉगिन करें",
"create_to_join": "शामिल होने के लिए एक निःशुल्क खाता बनाएँ",
"login_to_join": "शामिल होने के लिए लॉग इन करें",
"validation": {
"unable_to_create_profile": "प्रोफ़ाइल बनाने में असमर्थ",
"user_cannot_be_created": "उपयोगकर्ता नहीं बनाया जा सकता"
},
"fields": {
"email": "आपका ईमेल",
"full_name": "पूरा नाम",
"password": "आपका पासवर्ड",
"confirm_password": "पासवर्ड की पुष्टि कीजिये",
"password_helper_message": "पासवर्ड 6 अक्षर से अधिक होना चाहिए",
"create_account": "खाता बनाएं"
},
"create_account": "खाता बनाएं"
},
"welcome_modal": {
"we_at": "हम पर",
@@ -1293,7 +1293,29 @@
"email": "Seu email",
"password": "Sua senha",
"forgot": "Esqueceu sua senha?",
"login": "Conecte-se"
"login": "Conecte-se",
"login_with": "ou faça login com",
"signup_with": "ou cadastre-se com",
"already_have_account": "Já tem uma conta?",
"not_registered_yet": "Ainda não está cadastrado?",
"signup": "Inscrever-se",
"signup_with_google": "Inscreva-se no Google",
"login_with_google": "Faça login com o Google",
"create_to_join": "Crie uma conta gratuita para participar",
"login_to_join": "Faça login para participar",
"validation": {
"unable_to_create_profile": "Não foi possível criar o perfil",
"user_cannot_be_created": "O usuário não pode ser criado"
},
"fields": {
"email": "Seu e-mail",
"full_name": "Nome completo",
"password": "Sua senha",
"confirm_password": "Confirme sua senha",
"password_helper_message": "A senha deve ter mais de 6 caracteres",
"create_account": "Criar uma conta"
},
"create_account": "Criar uma conta"
},
"welcome_modal": {
"we_at": "Nós em",
@@ -1293,7 +1293,29 @@
"email": "Ваш адрес электронной почты",
"password": "Ваш пароль",
"forgot": "Забыли пароль?",
"login": "Авторизоваться"
"login": "Авторизоваться",
"login_with": "или войдите с помощью",
"signup_with": "или зарегистрируйтесь через",
"already_have_account": "У вас уже есть аккаунт?",
"not_registered_yet": "Еще не зарегистрированы?",
"signup": "Зарегистрироваться",
"signup_with_google": "Зарегистрируйтесь через Google",
"login_with_google": "Войти через Google",
"create_to_join": "Создайте бесплатную учетную запись, чтобы присоединиться",
"login_to_join": "Войдите, чтобы присоединиться",
"validation": {
"unable_to_create_profile": "Невозможно создать профиль",
"user_cannot_be_created": "Пользователь не может быть создан"
},
"fields": {
"email": "Ваш адрес электронной почты",
"full_name": "Полное имя",
"password": "Ваш пароль",
"confirm_password": "Подтвердите пароль",
"password_helper_message": "Пароль должен быть более 6 символов",
"create_account": "Зарегистрироваться"
},
"create_account": "Зарегистрироваться"
},
"welcome_modal": {
"we_at": "Мы в",
@@ -1293,7 +1293,29 @@
"email": "Email của bạn",
"password": "Mật khẩu của bạn",
"forgot": "Quên mật khẩu?",
"login": "Đăng nhập"
"login": "Đăng nhập",
"login_with": "hoặc đăng nhập với",
"signup_with": "hoặc đăng ký với",
"already_have_account": "Đã có tài khoản?",
"not_registered_yet": "Chưa đăng ký?",
"signup": "Đăng ký",
"signup_with_google": "Đăng ký với Google",
"login_with_google": "Đăng nhập bằng Google",
"create_to_join": "Tạo một tài khoản miễn phí để tham gia",
"login_to_join": "Đăng nhập để tham gia",
"validation": {
"unable_to_create_profile": "Không thể tạo hồ sơ",
"user_cannot_be_created": "Không thể tạo người dùng"
},
"fields": {
"email": "Email của bạn",
"full_name": "Tên đầy đủ",
"password": "Mật khẩu của bạn",
"confirm_password": "Xác nhận mật khẩu",
"password_helper_message": "Mật khẩu phải nhiều hơn 6 ký tự",
"create_account": "Tạo tài khoản"
},
"create_account": "Tạo tài khoản"
},
"welcome_modal": {
"we_at": "Chúng tôi ở",