--
All checks were successful
Deploy / CreateImage (push) Successful in 4m48s
Deploy / DeployService (push) Successful in 26s

This commit is contained in:
Nastya 2025-07-01 15:39:54 +03:00
parent b09e587220
commit 2465aab529
3 changed files with 434 additions and 1 deletions

@ -18,11 +18,197 @@ const getLanguageFromURL = (): string => {
return "ru"; // Жёсткий фолбэк return "ru"; // Жёсткий фолбэк
}; };
const r = {
ru: {
"quiz is inactive": "Квиз не активирован",
"no questions found": "Нет созданных вопросов",
"quiz is empty": "Квиз пуст",
"quiz already completed": "Вы уже прошли этот опрос",
"no quiz id": "Отсутствует id квиза",
"quiz data is null": "Не были переданы параметры квиза",
"invalid request data": "Такого квиза не существует",
"default message": "Что-то пошло не так",
"The request could not be sent": "Заявка не может быть отправлена",
"The number of points could not be sent": "Количество баллов не может быть отправлено",
"Your result": "Ваш результат",
"Your points": "Ваши баллы",
of: "из",
"View answers": "Посмотреть ответы",
"Find out more": "Узнать подробнее",
"Go to website": "Перейти на сайт",
"Question title": "Заголовок вопроса",
"Question without a title": "Вопрос без названия",
"Your answer": "Ваш ответ",
"Add image": "Добавить изображение",
"Accepts images": "Принимает изображения",
"Add video": "Добавить видео",
"Accepts .mp4 and .mov format - maximum 50mb": "Принимает .mp4 и .mov формат — максимум 50мб",
"Add audio file": "Добавить аудиофайл",
"Accepts audio files": "Принимает аудиофайлы",
"Add document": "Добавить документ",
"Accepts documents": "Принимает документы",
Next: "Далее",
Prev: "Назад",
From: "От",
До: "До",
"Enter your answer": "Введите свой ответ",
"Incorrect file type selected": "Выбран некорректный тип файла",
"File is too big. Maximum size is 50 MB": "Файл слишком большой. Максимальный размер 50 МБ",
"Acceptable file extensions": "Допустимые расширения файлов",
"You have uploaded": "Вы загрузили",
"The answer was not counted": "Ответ не был засчитан",
"Select an answer option below": "Выберите вариант ответа ниже",
"Select an answer option on the left": "Выберите вариант ответа слева",
"Fill out the form to receive your test results": "Заполните форму, чтобы получить результаты теста",
Enter: "Введите",
Name: "Имя",
"Phone number": "Номер телефона",
"Last name": "Фамилия",
Address: "Адрес",
"Incorrect email entered": "Введена некорректная почта",
"Please fill in the fields": "Пожалуйста, заполните поля",
"Please try again later": "повторите попытку позже",
"Regulation on the processing of personal data": "Положением об обработке персональных данных",
"Privacy Policy": "Политикой конфиденциальности",
familiarized: "ознакомлен",
and: "и",
"Get results": "Получить результаты",
"Data sent successfully": "Данные успешно отправлены",
Step: "Шаг",
"questions are not ready yet": "Вопросы для аудитории ещё не созданы. Пожалуйста, подождите",
"Add your image": "Добавьте своё изображение",
"select emoji": "выберите смайлик",
"file is too big": "Файл слишком большой",
"file type is not supported": "Тип файла не поддерживается",
},
en: {
"quiz is inactive": "Quiz is inactive",
"no questions found": "No questions found",
"quiz is empty": "Quiz is empty",
"quiz already completed": "You've already completed this quiz",
"no quiz id": "Missing quiz ID",
"quiz data is null": "No quiz parameters were provided",
"invalid request data": "This quiz doesn't exist",
"default message": "Something went wrong",
"The request could not be sent": "Request could not be sent",
"The number of points could not be sent": "Points could not be submitted",
"Your result": "Your result",
"Your points": "Your points",
of: "of",
"View answers": "View answers",
"Find out more": "Learn more",
"Go to website": "Go to website",
"Question title": "Question title",
"Question without a title": "Untitled question",
"Your answer": "Your answer",
"Add image": "Add image",
"Accepts images": "Accepts images",
"Add video": "Add video",
"Accepts .mp4 and .mov format - maximum 50mb": "Accepts .mp4 and .mov format - maximum 50MB",
"Add audio file": "Add audio file",
"Accepts audio files": "Accepts audio files",
"Add document": "Add document",
"Accepts documents": "Accepts documents",
Next: "Next",
Prev: "Previous",
From: "From",
До: "To",
"Enter your answer": "Enter your answer",
"Incorrect file type selected": "Invalid file type selected",
"File is too big. Maximum size is 50 MB": "File is too large. Maximum size is 50 MB",
"Acceptable file extensions": "Allowed file extensions",
"You have uploaded": "You've uploaded",
"The answer was not counted": "Answer wasn't counted",
"Select an answer option below": "Select an answer option below",
"Select an answer option on the left": "Select an answer option on the left",
"Fill out the form to receive your test results": "Fill out the form to receive your test results",
Enter: "Enter",
Name: "Name",
"Phone number": "Phone number",
"Last name": "Last name",
Address: "Address",
"Incorrect email entered": "Invalid email entered",
"Please fill in the fields": "Please fill in the fields",
"Please try again later": "Please try again later",
"Regulation on the processing of personal data": "Personal Data Processing Regulation",
"Privacy Policy": "Privacy Policy",
familiarized: "acknowledged",
and: "and",
"Get results": "Get results",
"Data sent successfully": "Data sent successfully",
Step: "Step",
"questions are not ready yet": "There are no questions for the audience yet. Please wait",
"Add your image": "Add your image",
"select emoji": "select emoji",
},
uz: {
"quiz is inactive": "Test faol emas",
"no questions found": "Savollar topilmadi",
"quiz is empty": "Test boʻsh",
"quiz already completed": "Siz bu testni allaqachon topshirgansiz",
"no quiz id": "Test IDsi yoʻq",
"quiz data is null": "Test parametrlari yuborilmagan",
"invalid request data": "Bunday test mavjud emas",
"default message": "Xatolik yuz berdi",
"The request could not be sent": "Soʻrov yuborib boʻlmadi",
"The number of points could not be sent": "Ballar yuborib boʻlmadi",
"Your result": "Sizning natijangiz",
"Your points": "Sizning ballaringiz",
of: "/",
"View answers": "Javoblarni koʻrish",
"Find out more": "Batafsil maʼlumot",
"Go to website": "Veb-saytga oʻtish",
"Question title": "Savol sarlavhasi",
"Question without a title": "Sarlavhasiz savol",
"Your answer": "Sizning javobingiz",
"Add image": "Rasm qoʻshish",
"Accepts images": "Rasmlarni qabul qiladi",
"Add video": "Video qoʻshish",
"Accepts .mp4 and .mov format - maximum 50mb": ".mp4 va .mov formatlarini qabul qiladi - maksimal 50MB",
"Add audio file": "Audio fayl qoʻshish",
"Accepts audio files": "Audio fayllarni qabul qiladi",
"Add document": "Hujjat qoʻshish",
"Accepts documents": "Hujjatlarni qabul qiladi",
Next: "Keyingi",
Prev: "Oldingi",
From: "Dan",
До: "Gacha",
"Enter your answer": "Javobingizni kiriting",
"Incorrect file type selected": "Notoʻgʻri fayl turi tanlandi",
"File is too big. Maximum size is 50 MB": "Fayl juda katta. Maksimal hajmi 50 MB",
"Acceptable file extensions": "Qabul qilinadigan fayl kengaytmalari",
"You have uploaded": "Siz yuklagansiz",
"The answer was not counted": "Javob hisobga olinmadi",
"Select an answer option below": "Quyidagi javob variantlaridan birini tanlang",
"Select an answer option on the left": "Chapdagi javob variantlaridan birini tanlang",
"Fill out the form to receive your test results": "Test natijalaringizni olish uchun shaklni toʻldiring",
Enter: "Kiriting",
Name: "Ism",
"Phone number": "Telefon raqami",
"Last name": "Familiya",
Address: "Manzil",
"Incorrect email entered": "Notoʻgʻri elektron pochta kiritildi",
"Please fill in the fields": "Iltimos, maydonlarni toʻldiring",
"Please try again later": "Iltimos, keyinroq urinib koʻring",
"Regulation on the processing of personal data": "Shaxsiy maʼlumotlarni qayta ishlash qoidalari",
"Privacy Policy": "Maxfiylik siyosati",
familiarized: "tanishdim",
and: "va",
"Get results": "Natijalarni olish",
"Data sent successfully": "Ma'lumotlar muvaffaqiyatli yuborildi",
Step: "Qadam",
"questions are not ready yet": "Tomoshabinlar uchun hozircha savollar yo'q. Iltimos kuting",
"Add your image": "Rasmingizni qo'shing",
"select emoji": "emoji tanlang",
},
};
// 2. Конфиг с полной отладкой // 2. Конфиг с полной отладкой
i18n i18n
.use(Backend) .use(Backend)
.use(initReactI18next) .use(initReactI18next)
.init({ .init({
resources: r,
lng: getLanguageFromURL(), // Принудительно из URL lng: getLanguageFromURL(), // Принудительно из URL
fallbackLng: "ru", fallbackLng: "ru",
supportedLngs: ["en", "ru", "uz"], supportedLngs: ["en", "ru", "uz"],

240
src/i18n/i18nWidget.ts Normal file

@ -0,0 +1,240 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
// 1. Функция для определения языка из URL
const getLanguageFromURL = (): string => {
const path = window.location.pathname;
const langMatch = path.match(/^\/(en|ru|uz)(\/|$)/i);
return langMatch ? langMatch[1].toLowerCase() : "ru"; // Фолбэк на 'ru'
};
// 2. Локали, встроенные прямо в конфиг
const r = {
ru: {
"quiz is inactive": "Квиз не активирован",
"no questions found": "Нет созданных вопросов",
"quiz is empty": "Квиз пуст",
"quiz already completed": "Вы уже прошли этот опрос",
"no quiz id": "Отсутствует id квиза",
"quiz data is null": "Не были переданы параметры квиза",
"invalid request data": "Такого квиза не существует",
"default message": "Что-то пошло не так",
"The request could not be sent": "Заявка не может быть отправлена",
"The number of points could not be sent": "Количество баллов не может быть отправлено",
"Your result": "Ваш результат",
"Your points": "Ваши баллы",
of: "из",
"View answers": "Посмотреть ответы",
"Find out more": "Узнать подробнее",
"Go to website": "Перейти на сайт",
"Question title": "Заголовок вопроса",
"Question without a title": "Вопрос без названия",
"Your answer": "Ваш ответ",
"Add image": "Добавить изображение",
"Accepts images": "Принимает изображения",
"Add video": "Добавить видео",
"Accepts .mp4 and .mov format - maximum 50mb": "Принимает .mp4 и .mov формат — максимум 50мб",
"Add audio file": "Добавить аудиофайл",
"Accepts audio files": "Принимает аудиофайлы",
"Add document": "Добавить документ",
"Accepts documents": "Принимает документы",
Next: "Далее",
Prev: "Назад",
From: "От",
До: "До",
"Enter your answer": "Введите свой ответ",
"Incorrect file type selected": "Выбран некорректный тип файла",
"File is too big. Maximum size is 50 MB": "Файл слишком большой. Максимальный размер 50 МБ",
"Acceptable file extensions": "Допустимые расширения файлов",
"You have uploaded": "Вы загрузили",
"The answer was not counted": "Ответ не был засчитан",
"Select an answer option below": "Выберите вариант ответа ниже",
"Select an answer option on the left": "Выберите вариант ответа слева",
"Fill out the form to receive your test results": "Заполните форму, чтобы получить результаты теста",
Enter: "Введите",
Name: "Имя",
"Phone number": "Номер телефона",
"Last name": "Фамилия",
Address: "Адрес",
"Incorrect email entered": "Введена некорректная почта",
"Please fill in the fields": "Пожалуйста, заполните поля",
"Please try again later": "повторите попытку позже",
"Regulation on the processing of personal data": "Положением об обработке персональных данных",
"Privacy Policy": "Политикой конфиденциальности",
familiarized: "ознакомлен",
and: "и",
"Get results": "Получить результаты",
"Data sent successfully": "Данные успешно отправлены",
Step: "Шаг",
"questions are not ready yet": "Вопросы для аудитории ещё не созданы. Пожалуйста, подождите",
"Add your image": "Добавьте своё изображение",
"select emoji": "выберите смайлик",
"file is too big": "Файл слишком большой",
"file type is not supported": "Тип файла не поддерживается",
},
en: {
"quiz is inactive": "Quiz is inactive",
"no questions found": "No questions found",
"quiz is empty": "Quiz is empty",
"quiz already completed": "You've already completed this quiz",
"no quiz id": "Missing quiz ID",
"quiz data is null": "No quiz parameters were provided",
"invalid request data": "This quiz doesn't exist",
"default message": "Something went wrong",
"The request could not be sent": "Request could not be sent",
"The number of points could not be sent": "Points could not be submitted",
"Your result": "Your result",
"Your points": "Your points",
of: "of",
"View answers": "View answers",
"Find out more": "Learn more",
"Go to website": "Go to website",
"Question title": "Question title",
"Question without a title": "Untitled question",
"Your answer": "Your answer",
"Add image": "Add image",
"Accepts images": "Accepts images",
"Add video": "Add video",
"Accepts .mp4 and .mov format - maximum 50mb": "Accepts .mp4 and .mov format - maximum 50MB",
"Add audio file": "Add audio file",
"Accepts audio files": "Accepts audio files",
"Add document": "Add document",
"Accepts documents": "Accepts documents",
Next: "Next",
Prev: "Previous",
From: "From",
До: "To",
"Enter your answer": "Enter your answer",
"Incorrect file type selected": "Invalid file type selected",
"File is too big. Maximum size is 50 MB": "File is too large. Maximum size is 50 MB",
"Acceptable file extensions": "Allowed file extensions",
"You have uploaded": "You've uploaded",
"The answer was not counted": "Answer wasn't counted",
"Select an answer option below": "Select an answer option below",
"Select an answer option on the left": "Select an answer option on the left",
"Fill out the form to receive your test results": "Fill out the form to receive your test results",
Enter: "Enter",
Name: "Name",
"Phone number": "Phone number",
"Last name": "Last name",
Address: "Address",
"Incorrect email entered": "Invalid email entered",
"Please fill in the fields": "Please fill in the fields",
"Please try again later": "Please try again later",
"Regulation on the processing of personal data": "Personal Data Processing Regulation",
"Privacy Policy": "Privacy Policy",
familiarized: "acknowledged",
and: "and",
"Get results": "Get results",
"Data sent successfully": "Data sent successfully",
Step: "Step",
"questions are not ready yet": "There are no questions for the audience yet. Please wait",
"Add your image": "Add your image",
"select emoji": "select emoji",
},
uz: {
"quiz is inactive": "Test faol emas",
"no questions found": "Savollar topilmadi",
"quiz is empty": "Test boʻsh",
"quiz already completed": "Siz bu testni allaqachon topshirgansiz",
"no quiz id": "Test IDsi yoʻq",
"quiz data is null": "Test parametrlari yuborilmagan",
"invalid request data": "Bunday test mavjud emas",
"default message": "Xatolik yuz berdi",
"The request could not be sent": "Soʻrov yuborib boʻlmadi",
"The number of points could not be sent": "Ballar yuborib boʻlmadi",
"Your result": "Sizning natijangiz",
"Your points": "Sizning ballaringiz",
of: "/",
"View answers": "Javoblarni koʻrish",
"Find out more": "Batafsil maʼlumot",
"Go to website": "Veb-saytga oʻtish",
"Question title": "Savol sarlavhasi",
"Question without a title": "Sarlavhasiz savol",
"Your answer": "Sizning javobingiz",
"Add image": "Rasm qoʻshish",
"Accepts images": "Rasmlarni qabul qiladi",
"Add video": "Video qoʻshish",
"Accepts .mp4 and .mov format - maximum 50mb": ".mp4 va .mov formatlarini qabul qiladi - maksimal 50MB",
"Add audio file": "Audio fayl qoʻshish",
"Accepts audio files": "Audio fayllarni qabul qiladi",
"Add document": "Hujjat qoʻshish",
"Accepts documents": "Hujjatlarni qabul qiladi",
Next: "Keyingi",
Prev: "Oldingi",
From: "Dan",
До: "Gacha",
"Enter your answer": "Javobingizni kiriting",
"Incorrect file type selected": "Notoʻgʻri fayl turi tanlandi",
"File is too big. Maximum size is 50 MB": "Fayl juda katta. Maksimal hajmi 50 MB",
"Acceptable file extensions": "Qabul qilinadigan fayl kengaytmalari",
"You have uploaded": "Siz yuklagansiz",
"The answer was not counted": "Javob hisobga olinmadi",
"Select an answer option below": "Quyidagi javob variantlaridan birini tanlang",
"Select an answer option on the left": "Chapdagi javob variantlaridan birini tanlang",
"Fill out the form to receive your test results": "Test natijalaringizni olish uchun shaklni toʻldiring",
Enter: "Kiriting",
Name: "Ism",
"Phone number": "Telefon raqami",
"Last name": "Familiya",
Address: "Manzil",
"Incorrect email entered": "Notoʻgʻri elektron pochta kiritildi",
"Please fill in the fields": "Iltimos, maydonlarni toʻldiring",
"Please try again later": "Iltimos, keyinroq urinib koʻring",
"Regulation on the processing of personal data": "Shaxsiy maʼlumotlarni qayta ishlash qoidalari",
"Privacy Policy": "Maxfiylik siyosati",
familiarized: "tanishdim",
and: "va",
"Get results": "Natijalarni olish",
"Data sent successfully": "Ma'lumotlar muvaffaqiyatli yuborildi",
Step: "Qadam",
"questions are not ready yet": "Tomoshabinlar uchun hozircha savollar yo'q. Iltimos kuting",
"Add your image": "Rasmingizni qo'shing",
"select emoji": "emoji tanlang",
},
};
// 3. Конфигурация i18n без Backend
i18n
.use(initReactI18next)
.init({
resources: r, // Используем встроенные переводы
lng: getLanguageFromURL(),
fallbackLng: "ru",
supportedLngs: ["en", "ru", "uz"],
debug: true,
interpolation: {
escapeValue: false,
},
react: {
useSuspense: false,
},
detection: {
order: ["path"],
lookupFromPathIndex: 0,
caches: [],
},
parseMissingKeyHandler: (key) => {
console.warn("Missing translation:", key);
return key;
},
missingKeyHandler: (lngs, ns, key) => {
console.error("🚨 Missing i18n key:", {
key,
languages: lngs,
namespace: ns,
stack: new Error().stack,
});
},
})
.then(() => {
console.log("i18n initialized. Current language:", i18n.language);
});
// 4. Логирование событий
i18n.on("languageChanged", (lng) => {
console.log("Language changed to:", lng);
});
export default i18n;

@ -2,6 +2,7 @@ import QuizAnswerer from "@/components/QuizAnswerer";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
// eslint-disable-next-line react-refresh/only-export-components // eslint-disable-next-line react-refresh/only-export-components
export * from "./widgets"; export * from "./widgets";
import "./i18n/i18nWidget";
// old widget // old widget
const widget = { const widget = {
@ -19,7 +20,13 @@ const widget = {
const root = createRoot(element); const root = createRoot(element);
root.render(<QuizAnswerer quizId={quizId} changeFaviconAndTitle={changeFaviconAndTitle} disableGlobalCss />); root.render(
<QuizAnswerer
quizId={quizId}
changeFaviconAndTitle={changeFaviconAndTitle}
disableGlobalCss
/>
);
}, },
}; };