diff --git a/lib/next-auth.d.ts b/lib/next-auth.d.ts
index eb66a0c..e27115c 100644
--- a/lib/next-auth.d.ts
+++ b/lib/next-auth.d.ts
@@ -4,7 +4,13 @@ declare module "next-auth" {
interface Session {
refresh_token: string;
access_token: string;
- expires_in: string;
+ expires_in?: string;
+ }
+
+ interface User {
+ refresh_token: string;
+ access_token: string;
+ expires_in?: string;
}
}
@@ -14,6 +20,6 @@ declare module "next-auth/jwt" {
interface JWT {
refresh_token: string;
access_token: string;
- expires_in: string;
+ expires_in?: string;
}
}
diff --git a/messages/en.json b/messages/en.json
new file mode 100644
index 0000000..2dcb808
--- /dev/null
+++ b/messages/en.json
@@ -0,0 +1,186 @@
+{
+ "general": {
+ "date": "Date",
+ "address": "Address",
+ "status": "Status",
+ "description": "Description",
+ "reviews": "Reviews",
+ "rating": "Rating",
+ "review": "Review",
+ "write_comment": "Write Comment",
+ "search": "Search",
+ "search_for": "Search For",
+ "city": "City",
+ "added_roads": "Added Roads",
+ "broken_roads": "Broken Roads",
+ "accident_hotspots": "Accident Hotspots",
+ "local_defects": "Local Defects",
+ "repair_plans": "Repair Plans",
+ "repaired": "Repaired",
+ "fixed_local_defects": "Fixed Local Defects",
+ "news": "News",
+ "details": "Details",
+ "navigation": "Navigation",
+ "contacts": "Contacts",
+ "download_our_app": "Download our app",
+ "back": "Back",
+ "save": "Save",
+ "saving": "Saving",
+ "cancel": "Cancel",
+ "cancellation": "Cancellation",
+ "save_changes": "Save Changes",
+ "send": "Send",
+ "receive": "Receive",
+ "delete": "Delete",
+ "show_on_map": "Show on Map",
+ "author_of_appeal": "Author of Appeal",
+ "enter_city": "Enter City",
+ "page_not_found": "Page Not Found (404)",
+ "incorrect_address_or_nonexistent_page": "Incorrect Address or Nonexistent Page.",
+ "home": "Home",
+ "first_name": "First Name",
+ "last_name": "Last Name",
+ "email": "Email"
+ },
+ "navigation": {
+ "home": "Home",
+ "about_us": "About Us",
+ "statistics": "Statistics",
+ "news": "News",
+ "volunteers": "Volunteers",
+ "profile": "Profile",
+ "login": "Login"
+ },
+ "home": {
+ "title": "Roads of Kyrgyzstan",
+ "subtitle": "Let's Make Roads Safe!",
+ "info": "Current information about the state of roads",
+ "report_broken_road": "Report Broken Road",
+ "road_map": "Road Map",
+ "latest_news": "Stay informed about the latest news on traffic, construction, and events!",
+ "enter_location": "Enter city, village, or region",
+ "broken_roads": "Broken road",
+ "accident_hotspots": "Accident hotspot",
+ "local_defects": "Local defect",
+ "repair_plans": "In repair plan",
+ "repaired": "Repaired",
+ "fixed_local_defects": "Fixed local defect",
+ "rating": "Rating",
+ "road_discussions": "Discussing roads: rating, experience, comfort on the way!",
+ "enter_address": "Enter address",
+ "read_more": "Read More"
+ },
+ "about_us": {
+ "name": "Transparency International-Kyrgyzstan",
+ "description": "Branch of the international organization Transparency International in the Kyrgyz Republic.",
+ "mission": "Promoting effective public policy and good governance to prevent corruption and strengthen democracy in the country.",
+ "goals_and_priorities": {
+ "anti-corruption_education": "Anti-corruption education of the population, raising public awareness of the importance and significance of the fight against corruption in Kyrgyzstan;",
+ "study_of_corruption_practices": "Organization of the study of the practice and theory of combating corruption and the participation of civil society structures in Kyrgyzstan and other countries;",
+ "supporting_citizens_and_organizations": "Assistance to citizens and organizations in the implementation of their constitutional rights and freedoms;",
+ "international_experience": "Preferential orientation to international experience in reducing corruption, mastering its technologies and resources, as well as involving civil society structures in the international dialogue on combating corruption."
+ }
+ },
+ "volunteers": {
+ "activists": "Activists",
+ "received_votes": "Received Votes",
+ "left_votes": "Left Votes",
+ "rating": "Rating"
+ },
+ "profile": {
+ "personal_cabinet": "Personal Cabinet",
+ "personal_data": "Personal Data",
+ "my_appeals": "My Appeals",
+ "logout": "Logout",
+ "write_appeal": "Write Appeal",
+ "profile_photo": "Profile Photo",
+ "others_identification": "With a profile photo, other people will recognize you, and it will be easier for you to determine which account you logged into.",
+ "add_profile_photo": "Add Profile Photo",
+ "profile_photo_updated": "Profile Photo Updated",
+ "delete": "Delete",
+ "change": "Change"
+ },
+ "authorization": {
+ "change_password": "Change Password",
+ "old_password": "Old Password",
+ "enter_old_password": "Enter Old Password",
+ "new_password": "New Password",
+ "enter_new_password": "Enter New Password",
+ "confirm_new_password": "Confirm New Password",
+ "confirm_new_password_prompt": "Please confirm the new password",
+ "password": "Password",
+ "forgot_password": "Forgot Password?",
+ "login": "Login",
+ "register": "Register",
+ "sign_in_account": "Sign in to Account",
+ "enter_credentials": "Please enter your credentials",
+ "login_via_google": "Login via Google",
+ "enter_password": "Enter Password",
+ "password_requirements": "Minimum 8 characters, 1 uppercase letter, and 1 digit",
+ "no_account_yet": "Don't have an account yet? Register",
+ "registration": "Registration",
+ "register_now": "Register Now",
+ "already_have_account": "Already have an account? Sign in",
+ "enter_email": "Enter Email",
+ "enter_email_for_code": "Enter email, and we will send a code to reset the password",
+ "send_code": "Send Code",
+ "confirm_code": "Confirm Code",
+ "enter_code": "Enter Code",
+ "enter_reset_code": "Enter code to reset and recover the password",
+ "reset_code": "Reset Code",
+ "reset_password": "Reset Password",
+ "check_email": "Check Your Email",
+ "code_sent_to": "We sent a code to the email name@gmail.com",
+ "confirmation_code": "Confirmation Code",
+ "confirm": "Confirm",
+ "resend_code_in": "Resend Code in",
+ "resend_code": "Resend Code"
+ },
+ "send_report": {
+ "how_to_mark_road_section": "How to mark a road section?",
+ "mark_road_instructions": "Place a pin and start drawing a road section (it can consist of any number of broken lines).",
+ "remove_segment_instruction": "To remove a segment, click on the points again.",
+ "add_problem_description": "Add a problem description",
+ "enter_description": "Enter description",
+ "add_photos": "Add Photos",
+ "upload_photos_instructions": "Upload up to 5 photos related to the road you want to mark. Photos will help better understand the problem.",
+ "attach_file": "Attach File (up to 5 MB)",
+ "submit_for_moderation": "Submit for Moderation",
+ "appeal_submitted": "Your appeal has been submitted",
+ "thanks_for_appeal": "Thank you for your appeal. It is currently under moderation.",
+ "view_my_appeals": "View My Appeals"
+ },
+ "months": {
+ "january": "January",
+ "february": "February",
+ "march": "March",
+ "april": "April",
+ "may": "May",
+ "june": "June",
+ "july": "July",
+ "august": "August",
+ "september": "September",
+ "october": "October",
+ "november": "November",
+ "december": "December"
+ },
+ "validation_errors": {
+ "invalid_email_format": "Invalid email format.",
+ "passwords_do_not_match": "Passwords do not match.",
+ "required_field_not_filled": "Required field not filled.",
+ "exceeded_maximum_length": "Exceeded maximum length of the field.",
+ "login_required_before_commenting": "Please log in or register before leaving a comment.",
+ "login_required_before_like": "Please log in or register before liking."
+ },
+ "server_errors": {
+ "invalid_email_or_password": "Invalid email or password.",
+ "server_error_auth_attempt": "Server error during authentication attempt.",
+ "login_failed": "Failed to log in. Something went wrong, please try again later.",
+ "account_already_exists": "An account with this email already exists.",
+ "account_not_found": "Account not found.",
+ "invalid_activation_code": "Invalid activation code.",
+ "invalid_activation_code_reset": "Invalid activation code for reset.",
+ "invalid_password_reset_code": "Invalid password reset code.",
+ "invalid_code": "Invalid code."
+ }
+}
diff --git a/messages/kg.json b/messages/kg.json
new file mode 100644
index 0000000..2f3fe5e
--- /dev/null
+++ b/messages/kg.json
@@ -0,0 +1,186 @@
+{
+ "general": {
+ "date": "Күн",
+ "address": "Дарек",
+ "status": "Статус",
+ "description": "Сүрөт",
+ "reviews": "Комментарийлер",
+ "rating": "Рейтинг",
+ "review": "Комментарий",
+ "write_comment": "Комментарий жазуу",
+ "search": "Издөө",
+ "search_for": "Издөө",
+ "city": "Шаар",
+ "added_roads": "Кошулган жолдор",
+ "broken_roads": "Тас тастаган жолдор",
+ "accident_hotspots": "Авариялуу жерлер",
+ "local_defects": "Жерги дефекттер",
+ "repair_plans": "Түзөө планттары",
+ "repaired": "Түзөлгөн",
+ "fixed_local_defects": "Жерги дефекттерди түзөлгөн",
+ "news": "Жаңылыктар",
+ "details": "Эчти маалымат",
+ "navigation": "Навигация",
+ "contacts": "Контакттар",
+ "download_our_app": "Биздин приложениямызды жүктөп алыңыз",
+ "back": "Кайтуу",
+ "save": "Сактоо",
+ "saving": "Сакталат",
+ "cancel": "Жокко чыгаруу",
+ "cancellation": "Жокко чыгаруу",
+ "save_changes": "Өзгөртүүлөрдү сактоо",
+ "send": "Жиберүү",
+ "receive": "Алуу",
+ "delete": "Жок кылуу",
+ "show_on_map": "Картада көрсөтүү",
+ "author_of_appeal": "Өтүнчүнүн автору",
+ "enter_city": "Шаарды киргизиңиз",
+ "page_not_found": "Бет табылган эмес (404)",
+ "incorrect_address_or_nonexistent_page": "Туура эмес дарек же бет жок",
+ "home": "Башкы бет",
+ "first_name": "Аты",
+ "last_name": "Фамилия",
+ "email": "Электрондук почта"
+ },
+ "navigation": {
+ "home": "Башкы бет",
+ "about_us": "Биз тууралуу",
+ "statistics": "Статистика",
+ "news": "Жаңылыктар",
+ "volunteers": "Волонтёрлер",
+ "profile": "Профиль",
+ "login": "Кириш"
+ },
+ "home": {
+ "title": "Кыргызстандын жолдору",
+ "subtitle": "Жолдорду бекемделүү жасаңыз!",
+ "info": "Жолдордун жаңы күйү",
+ "report_broken_road": "Тас тастаган жолду турганды таратуу",
+ "road_map": "Жол картасы",
+ "latest_news": "Трафик, өндүрүү жана тапшыруудагы соңгосу турган жаңылыктардан кабардар болуңуз!",
+ "enter_location": "Шаар, айыл жана регионду киргизиңиз",
+ "broken_roads": "Жол кирпич",
+ "accident_hotspots": "Авариянын жатактоо жерлери",
+ "local_defects": "Жерги дефект",
+ "repair_plans": "Тозгоондоо жатактоо планында",
+ "repaired": "Тозотулду",
+ "fixed_local_defects": "Тозотулган жерги дефект",
+ "rating": "Рейтинг",
+ "road_discussions": "Жолдорду талкуулоо: рейтинг, тажрыйба, жолдоо боюнча комфорт!",
+ "enter_address": "Даректи киргизиңиз",
+ "read_more": "Көбүрөөк окуу"
+ },
+ "transparency_international_kyrgyzstan": {
+ "name": "Транспаренттыктык Интернационал-Кыргызстан",
+ "description": "Транспаренттыктык Интернационалдын Кыргызстан Республикасы бөлүмү.",
+ "mission": "Коррупциянын ыкмасы менен демократияны күтүтүп, эффективдүү жамааттык саясат жана жакшы мамлекеттүү башкаруунун бириктирилүү үчүн.",
+ "goals_and_priorities": {
+ "anti-corruption_education": "Коррупция менен борбордук бийикти ашуу, Кыргызстанда коррупцияга каршы болгондоо маанилүүдүн жана азаттыктардын маанилүүлүгү үчүн жалпы айткынуу;",
+ "study_of_corruption_practices": "Коррупцияга каршы борбордукты тартуу жана учуруу теориясы менен, Кыргызстан менен башка өлкөлердеги кызмат көрсөтүүсү үчүн азаттыктыктын долбоорлорун жана каттоого жаткантыруу;",
+ "supporting_citizens_and_organizations": "Граждандар менен биздин же компаниялардын конституциялык башкаруу менен жандуулаткануу;",
+ "international_experience": "Коррупциянын аздоого чейинки жыйынтыкты башкаруу үчүн көздөр тартуу, улуттуктары менен биргелеп, коррупцияга каршы көрсөткүчтөрдү мамлекеттик диалогга киргизүү."
+ }
+ },
+ "volunteers": {
+ "activists": "Активисттер",
+ "received_votes": "Алынган баллдар",
+ "left_votes": "Калган баллдар",
+ "rating": "Рейтинг"
+ },
+ "profile": {
+ "personal_cabinet": "Жеке кабинет",
+ "personal_data": "Жеке дайындар",
+ "my_appeals": "Менин жардам кылган жалпылыгым",
+ "logout": "Чыгуу",
+ "write_appeal": "Жардам кылуу",
+ "profile_photo": "Профиль сүрөтү",
+ "others_identification": "Профиль сүрөтү аркылуу башка адамдар сизди танышат, жана сизге кирген аккаунтту тандашуу өттүрүлгөн болот.",
+ "add_profile_photo": "Профиль сүрөтү кошуу",
+ "profile_photo_updated": "Профиль сүрөтү жаңыртылды",
+ "delete": "Жок кылуу",
+ "change": "Өзгөртүү"
+ },
+ "authorization": {
+ "change_password": "Сыр сөздү өзгөртүү",
+ "old_password": "Эски сыр сөз",
+ "enter_old_password": "Эски сыр сөздү киргизиңиз",
+ "new_password": "Жаңы сыр сөз",
+ "enter_new_password": "Жаңы сыр сөздү киргизиңиз",
+ "confirm_new_password": "Жаңы сыр сөздү растоо",
+ "confirm_new_password_prompt": "Жаңы сыр сөздү растоо, аны кайра чалыңыз",
+ "password": "Сыр сөз",
+ "forgot_password": "Сыр сөздү унуттуңузбу?",
+ "login": "Кириш",
+ "register": "Тизмеге кирүү",
+ "sign_in_account": "Аккаунтка кириңиз",
+ "enter_credentials": "Киргизген дайындарыңызды киргизиңиз",
+ "login_via_google": "Google аркылуу кириңиз",
+ "enter_password": "Сыр сөздү киргизиңиз",
+ "password_requirements": "Минимум 8 белги, 1 башкы буюк тамга жана 1 сандар",
+ "no_account_yet": "Өйткені, аккаунт жоок? Тизмеге кирүү",
+ "registration": "Тизмеге кирүү",
+ "register_now": "Азыр тизмеге кирүү",
+ "already_have_account": "Аккаунт бар болсо, кириңиз",
+ "enter_email": "Электрондук почтаны киргизиңиз",
+ "enter_email_for_code": "Электрондук почта киргизиңиз, биз сизге сыр сөздү калыпта тапшыруу үчүн код жөнөтөт",
+ "send_code": "Код жөнөтүү",
+ "confirm_code": "Кодду растоо",
+ "enter_code": "Кодду киргизиңиз",
+ "enter_reset_code": "Сыр сөздү өзгөртүп жаңыртуу үчүн кодду киргизиңиз",
+ "reset_code": "Сыр сөздү өзгөртүү коду",
+ "reset_password": "Сыр сөздү өзгөртүү",
+ "check_email": "Почтаны текшериңиз",
+ "code_sent_to": "Биз кодду name@gmail.com почтасына жөнөттүк",
+ "confirmation_code": "Тастыгы код",
+ "confirm": "Растоо",
+ "resend_code_in": "Кодду кайталап жөнөтүү",
+ "resend_code": "Кодду кайталап жөнөтүү"
+ },
+ "send_report": {
+ "how_to_mark_road_section": "Жол бөлүмүн белгилөө үчүн",
+ "mark_road_instructions": "Чек салып, жол бөлүмүн белгилөөгө ээсиңиз (ал булактардан турат).",
+ "remove_segment_instruction": "Жол бөлүмүн каттоо үчүн бир маандын жакшысына басыңыз.",
+ "add_problem_description": "Проблеманын сүрөтүн кошуңуз",
+ "enter_description": "Сүрөттөмөнү киргизиңиз",
+ "add_photos": "Фотографияларды кошуңуз",
+ "upload_photos_instructions": "Жолдун байланышты 5 фотосун жүктөп алыңыз, анткени жататат жана туура түшүнүүдү макул болот.",
+ "attach_file": "Файлды тиштөө (5 МБга чейин)",
+ "submit_for_moderation": "Модерацияга жиберүү",
+ "appeal_submitted": "Сиздин жалпылыгыңыз жиберилди",
+ "thanks_for_appeal": "Сиздин жалпылыгыңуз үчүн рахмат. Азырынча аны модерацияда.",
+ "view_my_appeals": "Менин жалпылыгымдарымды көрүү"
+ },
+ "months": {
+ "january": "Жанварь",
+ "february": "Февраль",
+ "march": "Март",
+ "april": "Апрель",
+ "may": "Май",
+ "june": "Июнь",
+ "july": "Июль",
+ "august": "Август",
+ "september": "Сентябрь",
+ "october": "Октябрь",
+ "november": "Ноябрь",
+ "december": "Декабрь"
+ },
+ "validation_errors": {
+ "invalid_email_format": "Туура эмес электрондук почта форматы.",
+ "passwords_do_not_match": "Сыр сөздөрдүн туура келмейт.",
+ "required_field_not_filled": "Милдеттүү талаа толтурулган жок.",
+ "exceeded_maximum_length": "Талаанын эң ылдам узундугу өткөнчү болду.",
+ "login_required_before_commenting": "Комментарий бир ар каайыпты таштоо алганда, ал кайталап киргизиңиз же тизмеге киргизиңиз.",
+ "login_required_before_like": "Лайк койгондо, кайталап киргизиңиз же тизмеге киргизиңиз керек."
+ },
+ "server_errors": {
+ "invalid_email_or_password": "Туура эмес почта же сыр сөз.",
+ "server_error_auth_attempt": "Авторизация учуруу учурастыктан кайталап сервердеги ката.",
+ "login_failed": "Кирүүгө мүмкүн болгон эмес. Негизги нече кайталап уруксат бериңиз.",
+ "account_already_exists": "Бул почтага ар бир аккаунт бар.",
+ "account_not_found": "Аккаунт табылган жок.",
+ "invalid_activation_code": "Четке калган иштеш коду.",
+ "invalid_activation_code_reset": "Сыр сөздү калыпта тапшыруу үчүн четке калган иштеш коду.",
+ "invalid_password_reset_code": "Сыр сөздү өзгөртүү коду четке калган эмес.",
+ "invalid_code": "Четке калган иштеш коду."
+ }
+}
diff --git a/messages/ru.json b/messages/ru.json
new file mode 100644
index 0000000..d7f005a
--- /dev/null
+++ b/messages/ru.json
@@ -0,0 +1,186 @@
+{
+ "general": {
+ "date": "Дата",
+ "address": "Адрес",
+ "status": "Статус",
+ "description": "Описание",
+ "reviews": "Комментарии",
+ "rating": "Рейтинг",
+ "review": "Комментарий",
+ "write_comment": "Написать комментарий",
+ "search": "Поиск",
+ "search_for": "Искать",
+ "city": "Город",
+ "added_roads": "Добавлено дорог",
+ "broken_roads": "Разбитых дорог",
+ "accident_hotspots": "Очагов аварийности",
+ "local_defects": "Локальных дефектов",
+ "repair_plans": "В планах ремонта",
+ "repaired": "Отремонтировано",
+ "fixed_local_defects": "Локальных дефектов исправлено",
+ "news": "Новости",
+ "details": "Подробнее",
+ "navigation": "Навигация",
+ "contacts": "Контакты",
+ "download_our_app": "Скачивай наше приложение",
+ "back": "Назад",
+ "save": "Сохранить",
+ "saving": "Сохранение",
+ "cancel": "Отменить",
+ "cancellation": "Отмена",
+ "save_changes": "Сохранить изменения",
+ "send": "Отправить",
+ "receive": "Получить",
+ "delete": "Удалить",
+ "show_on_map": "Показать на карте",
+ "author_of_appeal": "Автор обращения",
+ "enter_city": "Введите населенный пункт",
+ "page_not_found": "Страница не найдена (404)",
+ "incorrect_address_or_nonexistent_page": "Неправильно набран адрес или такой страницы не существует.",
+ "home": "На главную",
+ "first_name": "Имя",
+ "last_name": "Фамилия",
+ "email": "Электронная почта"
+ },
+ "navigation": {
+ "home": "Главная",
+ "about_us": "О нас",
+ "statistics": "Статистика",
+ "news": "Новости",
+ "volunteers": "Волонтеры",
+ "profile": "Профиль",
+ "login": "Войти"
+ },
+ "home": {
+ "title": "Дороги Кыргызстана",
+ "subtitle": "Сделаем дороги безопасными!",
+ "info": "Актуальная информация о состоянии дорог",
+ "report_broken_road": "Отметить разбитую дорогу",
+ "road_map": "Карта дорог",
+ "latest_news": "Будьте в курсе последних новостей о дорожном движении, строительствах и мероприятиях!",
+ "enter_location": "Введите город, село или регион",
+ "broken_roads": "Разбитая дорога",
+ "accident_hotspots": "Очаг аварийности",
+ "local_defects": "Локальный дефект",
+ "repair_plans": "В плане ремонта",
+ "repaired": "Отремонтировано",
+ "fixed_local_defects": "Локальный дефект исправлен",
+ "rating": "Рейтинг",
+ "road_discussions": "Обсуждаем дороги: рейтинг, опыт, комфорт в пути!",
+ "enter_address": "Введите адрес",
+ "read_more": "Читать"
+ },
+ "about_us": {
+ "name": "Transparency International-Кыргызстан",
+ "description": "Филиал международной организации Transparency International в Кыргызской Республике.",
+ "mission": "Продвижение эффективной общественной политики и надлежащего управления в целях предотвращения коррупции и усиления демократии в стране.",
+ "goals_and_priorities": {
+ "anti-corruption_education": "Антикоррупционное просвещение населения, повышение общественного осознания значимости и важности борьбы с коррупцией в Кыргызстане;",
+ "study_of_corruption_practices": "Организация изучения практики и теории борьбы с коррупцией и участия в ней структур гражданского общества в Кыргызстане и других странах;",
+ "supporting_citizens_and_organizations": "Содействие гражданам и организациям в реализации их конституционных прав и свобод;",
+ "international_experience": "Преимущественная ориентация на международный опыт уменьшения коррупции, освоение его технологий, ресурсов, а также включение структур гражданского общества в международный диалог борьбы с коррупцией."
+ }
+ },
+ "volunteers": {
+ "activists": "Активисты",
+ "received_votes": "Получено голосов",
+ "left_votes": "Оставлено голосов",
+ "rating": "Рейтинг"
+ },
+ "profile": {
+ "personal_cabinet": "Личный кабинет",
+ "personal_data": "Личные данные",
+ "my_appeals": "Мои обращения",
+ "logout": "Выйти из аккаунта",
+ "write_appeal": "Написать обращение",
+ "profile_photo": "Фото профиля",
+ "others_identification": "По фото профиля другие люди смогут вас узнавать, а вам будет проще определять, в какой аккаунт вы вошли.",
+ "add_profile_photo": "Добавить фото профиля",
+ "profile_photo_updated": "Фото профиля обновлено",
+ "delete": "Удалить",
+ "change": "Сменить"
+ },
+ "authorization": {
+ "change_password": "Изменить пароль",
+ "old_password": "Старый пароль",
+ "enter_old_password": "Введите старый пароль",
+ "new_password": "Новый пароль",
+ "enter_new_password": "Введите новый пароль",
+ "confirm_new_password": "Подтвердить новый пароль",
+ "confirm_new_password_prompt": "Пожалуйста, подтвердите новый пароль",
+ "password": "Пароль",
+ "forgot_password": "Забыли пароль?",
+ "login": "Войти",
+ "register": "Зарегистрироваться",
+ "sign_in_account": "Войдите в аккаунт",
+ "enter_credentials": "Пожалуйста, введите свои данные",
+ "login_via_google": "Войти через Google",
+ "enter_password": "Введите пароль",
+ "password_requirements": "Минимум 8 символов, 1 заглавная буква и цифра",
+ "no_account_yet": "Еще нет аккаунта? Зарегистрируйтесь",
+ "registration": "Регистрация",
+ "register_now": "Зарегистрировать",
+ "already_have_account": "Уже есть аккаунт? Войти в аккаунт",
+ "enter_email": "Введите электронную почту",
+ "enter_email_for_code": "Введите электронную почту и мы отправим код для восстановления пароля",
+ "send_code": "Отправить код",
+ "confirm_code": "Потвердить код",
+ "enter_code": "Введите код",
+ "enter_reset_code": "Введите код для сброса и восстановления пароля",
+ "reset_code": "Код сброса пароля",
+ "reset_password": "Сбросить пароль",
+ "check_email": "Проверьте свою почту",
+ "code_sent_to": "Мы отправили код на почту name@gmail.com",
+ "confirmation_code": "Код подтверждения",
+ "confirm": "Подтвердить",
+ "resend_code_in": "Отправить код повторно через",
+ "resend_code": "Отправить код повторно"
+ },
+ "send_report": {
+ "how_to_mark_road_section": "Как отметить участок дороги?",
+ "mark_road_instructions": "Поставьте булавку и начните рисовать участок дороги (он может состоять из любого количества ломаных линий).",
+ "remove_segment_instruction": "Чтобы удалить отрезок, нажмите на точки повторно.",
+ "add_problem_description": "Добавьте описание проблемы",
+ "enter_description": "Введите описание",
+ "add_photos": "Добавьте фотографии",
+ "upload_photos_instructions": "Загрузите до 5 фотографий, связанных с дорогой, которую вы хотите отметить. Фотографии помогут лучше понять проблему.",
+ "attach_file": "Прикрепить файл (до 5 МБ)",
+ "submit_for_moderation": "Отправить на модерацию",
+ "appeal_submitted": "Ваше обращение отправлено",
+ "thanks_for_appeal": "Спасибо за ваше обращение. На данный момент оно в модерации.",
+ "view_my_appeals": "Смотреть мои обращения"
+ },
+ "months": {
+ "january": "Январь",
+ "february": "Февраль",
+ "march": "Март",
+ "april": "Апрель",
+ "may": "Май",
+ "june": "Июнь",
+ "july": "Июль",
+ "august": "Август",
+ "september": "Сентябрь",
+ "october": "Октябрь",
+ "november": "Ноябрь",
+ "december": "Декабрь"
+ },
+ "validation_errors": {
+ "invalid_email_format": "Неверный формат электронной почты.",
+ "passwords_do_not_match": "Пароли не совпадают.",
+ "required_field_not_filled": "Обязательное поле не заполнено.",
+ "exceeded_maximum_length": "Превышена максимальная длина поля.",
+ "login_required_before_commenting": "Перед тем как оставить комментарий, пожалуйста, войдите или зарегистрируйтесь.",
+ "login_required_before_like": "Перед тем как поставить лайк, пожалуйста, войдите или зарегистрируйтесь."
+ },
+ "server_errors": {
+ "invalid_email_or_password": "Неверная почта или пароль.",
+ "server_error_auth_attempt": "Серверная ошибка при попытке авторизации.",
+ "login_failed": "Не удалось войти в систему. Что-то пошло не так, попробуйте еще раз немного позже.",
+ "account_already_exists": "Такая учетная запись уже существует.",
+ "account_not_found": "Такой учетной записи не существует.",
+ "invalid_activation_code": "Код не действителен.",
+ "invalid_activation_code_reset": "Код активации не действителен.",
+ "invalid_password_reset_code": "Код сброса пароля не действителен.",
+ "invalid_code": "Неверный код."
+ }
+}
diff --git a/next.config.mjs b/next.config.mjs
index 22adadb..b7e04b8 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,3 +1,6 @@
+import createNextIntlPlugin from "next-intl/plugin";
+const withNextIntl = createNextIntlPlugin();
+
/** @type {import('next').NextConfig} */
const nextConfig = {
distDir: "build",
@@ -9,6 +12,10 @@ const nextConfig = {
},
],
},
+ env: {
+ CLIENT_ID: process.env.CLIENT_ID,
+ CLIENT_SECRET: process.env.CLIENT_SECRET,
+ },
};
-export default nextConfig;
+export default withNextIntl(nextConfig);
diff --git a/package.json b/package.json
index f2aae33..68649ef 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"leaflet": "^1.9.4",
"next": "14.1.0",
"next-auth": "^4.24.5",
+ "next-intl": "^3.9.0",
"react": "^18",
"react-dom": "^18",
"react-leaflet": "^4.2.1",
diff --git a/src/app/App.scss b/src/app/[locale]/App.scss
similarity index 100%
rename from src/app/App.scss
rename to src/app/[locale]/App.scss
diff --git a/src/app/Providers.tsx b/src/app/[locale]/Providers.tsx
similarity index 100%
rename from src/app/Providers.tsx
rename to src/app/[locale]/Providers.tsx
diff --git a/src/app/about-us/AboutUs.scss b/src/app/[locale]/about-us/AboutUs.scss
similarity index 100%
rename from src/app/about-us/AboutUs.scss
rename to src/app/[locale]/about-us/AboutUs.scss
diff --git a/src/app/about-us/assets/header.svg b/src/app/[locale]/about-us/assets/header.svg
similarity index 100%
rename from src/app/about-us/assets/header.svg
rename to src/app/[locale]/about-us/assets/header.svg
diff --git a/src/app/about-us/page.tsx b/src/app/[locale]/about-us/page.tsx
similarity index 100%
rename from src/app/about-us/page.tsx
rename to src/app/[locale]/about-us/page.tsx
diff --git a/src/app/create-report/CreateReport.scss b/src/app/[locale]/create-report/CreateReport.scss
similarity index 100%
rename from src/app/create-report/CreateReport.scss
rename to src/app/[locale]/create-report/CreateReport.scss
diff --git a/src/app/create-report/page.tsx b/src/app/[locale]/create-report/page.tsx
similarity index 92%
rename from src/app/create-report/page.tsx
rename to src/app/[locale]/create-report/page.tsx
index 6dfba99..3bb680f 100644
--- a/src/app/create-report/page.tsx
+++ b/src/app/[locale]/create-report/page.tsx
@@ -10,7 +10,7 @@ export const metadata: Metadata = {
};
const DynamicForm = dynamic(
- () => import("@/widgets/ReportForm/ReportForm"),
+ () => import("@/widgets/forms/ReportForm/ReportForm"),
{
ssr: false,
}
diff --git a/src/app/globals.scss b/src/app/[locale]/globals.scss
similarity index 100%
rename from src/app/globals.scss
rename to src/app/[locale]/globals.scss
diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx
new file mode 100644
index 0000000..95ab16d
--- /dev/null
+++ b/src/app/[locale]/layout.tsx
@@ -0,0 +1,34 @@
+import type { Metadata } from "next";
+import "./globals.scss";
+import "./App.scss";
+// import "@/shared/fonts/fonts.scss";
+import Navbar from "@/widgets/Navbar/Navbar";
+import Footer from "@/widgets/Footer/Footer";
+import { NextIntlClientProvider, useMessages } from "next-intl";
+import { Providers } from "./Providers";
+
+export default function LocaleLayout({
+ children,
+ params,
+}: Readonly<{
+ children: React.ReactNode;
+ params: { locale: string };
+}>) {
+ const messages = useMessages();
+ return (
+
+
+
+
+
+ {children}
+
+
+
+
+
+ );
+}
diff --git a/src/app/news/News.scss b/src/app/[locale]/news/News.scss
similarity index 100%
rename from src/app/news/News.scss
rename to src/app/[locale]/news/News.scss
diff --git a/src/app/news/[id]/NewsDetails.scss b/src/app/[locale]/news/[id]/NewsDetails.scss
similarity index 100%
rename from src/app/news/[id]/NewsDetails.scss
rename to src/app/[locale]/news/[id]/NewsDetails.scss
diff --git a/src/app/news/[id]/icons/calendar.svg b/src/app/[locale]/news/[id]/icons/calendar.svg
similarity index 100%
rename from src/app/news/[id]/icons/calendar.svg
rename to src/app/[locale]/news/[id]/icons/calendar.svg
diff --git a/src/app/news/[id]/icons/message.svg b/src/app/[locale]/news/[id]/icons/message.svg
similarity index 100%
rename from src/app/news/[id]/icons/message.svg
rename to src/app/[locale]/news/[id]/icons/message.svg
diff --git a/src/app/news/[id]/page.tsx b/src/app/[locale]/news/[id]/page.tsx
similarity index 100%
rename from src/app/news/[id]/page.tsx
rename to src/app/[locale]/news/[id]/page.tsx
diff --git a/src/app/news/page.tsx b/src/app/[locale]/news/page.tsx
similarity index 85%
rename from src/app/news/page.tsx
rename to src/app/[locale]/news/page.tsx
index 7bda94b..5220527 100644
--- a/src/app/news/page.tsx
+++ b/src/app/[locale]/news/page.tsx
@@ -1,7 +1,5 @@
import "./News.scss";
import Typography from "@/shared/ui/components/Typography/Typography";
-import { apiInstance } from "@/shared/config/apiConfig";
-import { INewsList } from "@/shared/types/news-type";
import NewsList from "@/widgets/NewsList/NewsList";
import { Metadata } from "next";
diff --git a/src/app/page.tsx b/src/app/[locale]/page.tsx
similarity index 67%
rename from src/app/page.tsx
rename to src/app/[locale]/page.tsx
index 19fa2ef..146b631 100644
--- a/src/app/page.tsx
+++ b/src/app/[locale]/page.tsx
@@ -1,8 +1,8 @@
-import Header from "@/widgets/Header/Header";
-import StatisticsSection from "@/widgets/StatisticsSection/StatisticsSection";
-import RatingSection from "@/widgets/RatingSection/RatingSection";
-import NewsSection from "@/widgets/NewsSection/NewsSection";
-import MapSection from "@/widgets/MapSection/MapSection";
+import Header from "@/widgets/home/Header/Header";
+import StatisticsSection from "@/widgets/home/StatisticsSection/StatisticsSection";
+import RatingSection from "@/widgets/home/RatingSection/RatingSection";
+import NewsSection from "@/widgets/home/NewsSection/NewsSection";
+import MapSection from "@/widgets/home/MapSection/MapSection";
import { Metadata } from "next";
export const metadata: Metadata = {
diff --git a/src/app/profile/AuthGuard.tsx b/src/app/[locale]/profile/AuthGuard.tsx
similarity index 78%
rename from src/app/profile/AuthGuard.tsx
rename to src/app/[locale]/profile/AuthGuard.tsx
index 9cafb69..9a5a307 100644
--- a/src/app/profile/AuthGuard.tsx
+++ b/src/app/[locale]/profile/AuthGuard.tsx
@@ -14,13 +14,9 @@ const AuthGuard = ({ children }: { children: React.ReactNode }) => {
};
await apiInstance.post("/token/verify/", data);
} catch (error: unknown) {
- if (error instanceof AxiosError) {
- if (error.response?.data.code === "token_not_valid") {
- signOut({
- callbackUrl: "/",
- });
- }
- }
+ signOut({
+ callbackUrl: "/",
+ });
}
};
diff --git a/src/app/profile/Profile.scss b/src/app/[locale]/profile/Profile.scss
similarity index 100%
rename from src/app/profile/Profile.scss
rename to src/app/[locale]/profile/Profile.scss
diff --git a/src/app/profile/layout.tsx b/src/app/[locale]/profile/layout.tsx
similarity index 96%
rename from src/app/profile/layout.tsx
rename to src/app/[locale]/profile/layout.tsx
index 0ff7938..1a54820 100644
--- a/src/app/profile/layout.tsx
+++ b/src/app/[locale]/profile/layout.tsx
@@ -6,7 +6,6 @@ import { AxiosError } from "axios";
import { apiInstance } from "@/shared/config/apiConfig";
import { getServerSession } from "next-auth";
import { authConfig } from "@/shared/config/authConfig";
-import { IProfile } from "@/shared/types/profile-type";
import { Metadata } from "next";
export const metadata: Metadata = {
diff --git a/src/app/profile/my-reports/page.tsx b/src/app/[locale]/profile/my-reports/page.tsx
similarity index 79%
rename from src/app/profile/my-reports/page.tsx
rename to src/app/[locale]/profile/my-reports/page.tsx
index fa81167..7661268 100644
--- a/src/app/profile/my-reports/page.tsx
+++ b/src/app/[locale]/profile/my-reports/page.tsx
@@ -1,4 +1,4 @@
-import ProfileTable from "@/widgets/ProfileTable/ProfileTable";
+import ProfileTable from "@/widgets/tables/ProfileTable/ProfileTable";
import React from "react";
const MyReports = async ({
diff --git a/src/app/profile/page.tsx b/src/app/[locale]/profile/page.tsx
similarity index 72%
rename from src/app/profile/page.tsx
rename to src/app/[locale]/profile/page.tsx
index a54c709..db4d387 100644
--- a/src/app/profile/page.tsx
+++ b/src/app/[locale]/profile/page.tsx
@@ -1,5 +1,3 @@
-import React from "react";
-
const page = () => {
return page
;
};
diff --git a/src/app/profile/personal/page.tsx b/src/app/[locale]/profile/personal/page.tsx
similarity index 94%
rename from src/app/profile/personal/page.tsx
rename to src/app/[locale]/profile/personal/page.tsx
index 28e4526..65922c8 100644
--- a/src/app/profile/personal/page.tsx
+++ b/src/app/[locale]/profile/personal/page.tsx
@@ -4,7 +4,7 @@ import ProfileAvatar from "@/features/ProfileAvatar/ProfileAvatar";
import { apiInstance } from "@/shared/config/apiConfig";
import { authConfig } from "@/shared/config/authConfig";
import { IProfile } from "@/shared/types/profile-type";
-import ProfileForm from "@/widgets/ProfileForm/ProfileForm";
+import ProfileForm from "@/widgets/forms/ProfileForm/ProfileForm";
import { AxiosError } from "axios";
import { getServerSession } from "next-auth";
import React from "react";
diff --git a/src/app/[locale]/report/[id]/ReportDetails.scss b/src/app/[locale]/report/[id]/ReportDetails.scss
new file mode 100644
index 0000000..f59921f
--- /dev/null
+++ b/src/app/[locale]/report/[id]/ReportDetails.scss
@@ -0,0 +1,37 @@
+.report-details {
+ display: flex;
+ flex-direction: column;
+ gap: 75px;
+ &__container {
+ display: grid;
+ grid-template-columns: 1.05fr 1fr;
+ gap: 76px;
+ }
+
+ &__map {
+ grid-row: 2 / 3;
+ grid-column: 1 / 3;
+ }
+}
+
+@media screen and (max-width: 1024px) {
+ .report-details {
+ &__container {
+ grid-template-columns: 1fr;
+ gap: 45px;
+ }
+
+ &__map {
+ grid-row: 2 / 3;
+ grid-column: 1 / 2;
+ }
+ }
+}
+
+@media screen and (max-width: 550px) {
+ .report-details {
+ &__container {
+ gap: 40px;
+ }
+ }
+}
diff --git a/src/app/report/[id]/icons/def_image.svg b/src/app/[locale]/report/[id]/icons/def_image.svg
similarity index 100%
rename from src/app/report/[id]/icons/def_image.svg
rename to src/app/[locale]/report/[id]/icons/def_image.svg
diff --git a/src/app/[locale]/report/[id]/page.tsx b/src/app/[locale]/report/[id]/page.tsx
new file mode 100644
index 0000000..59ccc55
--- /dev/null
+++ b/src/app/[locale]/report/[id]/page.tsx
@@ -0,0 +1,66 @@
+import "./ReportDetails.scss";
+import { IReport } from "@/shared/types/report-type";
+
+import ReviewSection from "@/widgets/ReviewSection/ReviewSection";
+import { Metadata } from "next";
+import ReportInformation from "@/widgets/report-details/ReportInformation/ReportInformation";
+import ReportImages from "@/widgets/report-details/ReportImages/ReportImages";
+import dynamic from "next/dynamic";
+import BreadCrumbs from "@/features/BreadCrumbs/BreadCrumbs";
+
+const DynamicMap = dynamic(
+ () => import("@/widgets/report-details/ReportMap/ReportMap"),
+ {
+ ssr: false,
+ }
+);
+
+export const metadata: Metadata = {
+ title: "KG ROAD | Обращение",
+ description:
+ "Страница обращения Kyrgyzstan Transperency International",
+};
+
+const ReportDetails = async ({
+ params,
+}: {
+ params: { id: string };
+}) => {
+ const getReportDetails = async () => {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_BASE_API}/report/${params.id}/`,
+ { cache: "no-store" }
+ );
+
+ return res.json();
+ };
+ const report: IReport = await getReportDetails();
+
+ return (
+
+ );
+};
+
+export default ReportDetails;
diff --git a/src/app/sign-in/forgot-password/page.tsx b/src/app/[locale]/sign-in/forgot-password/page.tsx
similarity index 68%
rename from src/app/sign-in/forgot-password/page.tsx
rename to src/app/[locale]/sign-in/forgot-password/page.tsx
index bcd9397..8c5e8c5 100644
--- a/src/app/sign-in/forgot-password/page.tsx
+++ b/src/app/[locale]/sign-in/forgot-password/page.tsx
@@ -1,5 +1,5 @@
import "@/shared/ui/auth-classes.scss";
-import ForgotPasswordForm from "@/widgets/ForgotPasswordForm/ForgotPasswordForm";
+import ForgotPasswordForm from "@/widgets/forms/ForgotPasswordForm/ForgotPasswordForm";
const ForgotPassword = () => {
return (
diff --git a/src/app/sign-in/icons/sign-in_icon.svg b/src/app/[locale]/sign-in/icons/sign-in_icon.svg
similarity index 100%
rename from src/app/sign-in/icons/sign-in_icon.svg
rename to src/app/[locale]/sign-in/icons/sign-in_icon.svg
diff --git a/src/app/sign-in/page.tsx b/src/app/[locale]/sign-in/page.tsx
similarity index 89%
rename from src/app/sign-in/page.tsx
rename to src/app/[locale]/sign-in/page.tsx
index f510e01..6c6111e 100644
--- a/src/app/sign-in/page.tsx
+++ b/src/app/[locale]/sign-in/page.tsx
@@ -1,9 +1,9 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import sign_in_icon from "./icons/sign-in_icon.svg";
-import SignInForm from "@/widgets/SignInForm/SignInForm";
-import Link from "next/link";
+import SignInForm from "@/widgets/forms/SignInForm/SignInForm";
import { Metadata } from "next";
+import { Link } from "@/shared/config/navigation";
export const metadata: Metadata = {
title: "KG ROAD | Вход",
diff --git a/src/app/sign-in/reset-code/icons/key.svg b/src/app/[locale]/sign-in/reset-code/icons/key.svg
similarity index 100%
rename from src/app/sign-in/reset-code/icons/key.svg
rename to src/app/[locale]/sign-in/reset-code/icons/key.svg
diff --git a/src/app/sign-in/reset-code/page.tsx b/src/app/[locale]/sign-in/reset-code/page.tsx
similarity index 90%
rename from src/app/sign-in/reset-code/page.tsx
rename to src/app/[locale]/sign-in/reset-code/page.tsx
index fa29c86..5d64234 100644
--- a/src/app/sign-in/reset-code/page.tsx
+++ b/src/app/[locale]/sign-in/reset-code/page.tsx
@@ -1,7 +1,7 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import key from "./icons/key.svg";
-import ResetCodeForm from "@/widgets/ResetCodeForm/ResetCodeForm";
+import ResetCodeForm from "@/widgets/forms/ResetCodeForm/ResetCodeForm";
const ResetCode = () => {
return (
diff --git a/src/app/sign-up/confirm-email/icons/mail.svg b/src/app/[locale]/sign-up/confirm-email/icons/mail.svg
similarity index 100%
rename from src/app/sign-up/confirm-email/icons/mail.svg
rename to src/app/[locale]/sign-up/confirm-email/icons/mail.svg
diff --git a/src/app/sign-up/confirm-email/page.tsx b/src/app/[locale]/sign-up/confirm-email/page.tsx
similarity index 89%
rename from src/app/sign-up/confirm-email/page.tsx
rename to src/app/[locale]/sign-up/confirm-email/page.tsx
index a287680..7338b7e 100644
--- a/src/app/sign-up/confirm-email/page.tsx
+++ b/src/app/[locale]/sign-up/confirm-email/page.tsx
@@ -1,7 +1,7 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import mail from "./icons/mail.svg";
-import ConfirmEmailForm from "@/widgets/ConfirmEmailForm/ConfirmEmailForm";
+import ConfirmEmailForm from "@/widgets/forms/ConfirmEmailForm/ConfirmEmailForm";
const ConfirmEmail = ({
searchParams,
diff --git a/src/app/sign-up/icons/flag.svg b/src/app/[locale]/sign-up/icons/flag.svg
similarity index 100%
rename from src/app/sign-up/icons/flag.svg
rename to src/app/[locale]/sign-up/icons/flag.svg
diff --git a/src/app/sign-up/page.tsx b/src/app/[locale]/sign-up/page.tsx
similarity index 89%
rename from src/app/sign-up/page.tsx
rename to src/app/[locale]/sign-up/page.tsx
index 121ad7c..27f27c9 100644
--- a/src/app/sign-up/page.tsx
+++ b/src/app/[locale]/sign-up/page.tsx
@@ -1,9 +1,9 @@
import "@/shared/ui/auth-classes.scss";
import Image from "next/image";
import flag from "./icons/flag.svg";
-import Link from "next/link";
-import SignUpForm from "@/widgets/SignUpForm/SignUpForm";
+import SignUpForm from "@/widgets/forms/SignUpForm/SignUpForm";
import { Metadata } from "next";
+import { Link } from "@/shared/config/navigation";
export const metadata: Metadata = {
title: "KG ROAD | Регистрация",
diff --git a/src/app/statistics/Statistics.scss b/src/app/[locale]/statistics/Statistics.scss
similarity index 100%
rename from src/app/statistics/Statistics.scss
rename to src/app/[locale]/statistics/Statistics.scss
diff --git a/src/app/statistics/page.tsx b/src/app/[locale]/statistics/page.tsx
similarity index 74%
rename from src/app/statistics/page.tsx
rename to src/app/[locale]/statistics/page.tsx
index fc86ca7..7c305a0 100644
--- a/src/app/statistics/page.tsx
+++ b/src/app/[locale]/statistics/page.tsx
@@ -1,9 +1,6 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./Statistics.scss";
-import { apiInstance } from "@/shared/config/apiConfig";
-import { IStatistics } from "@/shared/types/statistics-type";
-import { AxiosError } from "axios";
-import StatisticsTable from "@/widgets/StatisticsTable/StatisticsTable";
+import StatisticsTable from "@/widgets/tables/StatisticsTable/StatisticsTable";
import { Metadata } from "next";
export const metadata: Metadata = {
diff --git a/src/app/volunteers/Volunteers.scss b/src/app/[locale]/volunteers/Volunteers.scss
similarity index 100%
rename from src/app/volunteers/Volunteers.scss
rename to src/app/[locale]/volunteers/Volunteers.scss
diff --git a/src/app/volunteers/page.tsx b/src/app/[locale]/volunteers/page.tsx
similarity index 86%
rename from src/app/volunteers/page.tsx
rename to src/app/[locale]/volunteers/page.tsx
index 82fff0b..c25f29f 100644
--- a/src/app/volunteers/page.tsx
+++ b/src/app/[locale]/volunteers/page.tsx
@@ -1,6 +1,6 @@
import Typography from "@/shared/ui/components/Typography/Typography";
import "./Volunteers.scss";
-import VolunteersTable from "@/widgets/VolunteersTable/VolunteersTable";
+import VolunteersTable from "@/widgets/tables/VolunteersTable/VolunteersTable";
import { Metadata } from "next";
export const metadata: Metadata = {
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 9bec346..568d357 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,25 +1,9 @@
-import type { Metadata } from "next";
-import "./globals.scss";
-import "./App.scss";
-// import "@/shared/fonts/fonts.scss";
-import { Providers } from "./Providers";
-import Navbar from "@/widgets/Navbar/Navbar";
-import Footer from "@/widgets/Footer/Footer";
+import { ReactNode } from "react";
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
-
-
- {children}
-
-
-
-
- );
+type Props = {
+ children: ReactNode;
+};
+
+export default function RootLayout({ children }: Props) {
+ return children;
}
diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx
new file mode 100644
index 0000000..23405db
--- /dev/null
+++ b/src/app/not-found.tsx
@@ -0,0 +1,13 @@
+"use client";
+
+import Error from "next/error";
+
+export default function NotFound() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/src/app/report/[id]/page.tsx b/src/app/report/[id]/page.tsx
deleted file mode 100644
index 831d3da..0000000
--- a/src/app/report/[id]/page.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import "./ReportDetails.scss";
-import Image from "next/image";
-import RoadType from "@/entities/RoadType/RoadType";
-import ReportLike from "@/features/ReportLike/ReportLike";
-import { apiInstance } from "@/shared/config/apiConfig";
-import { IReport } from "@/shared/types/report-type";
-import {
- ROAD_TYPES,
- ROAD_TYPES_COLORS,
-} from "@/shared/variables/road-types";
-import calendar from "./icons/calendar.svg";
-import map_pin from "./icons/map-pin.svg";
-import def_image from "./icons/def_image.svg";
-import ReviewSection from "@/widgets/ReviewSection/ReviewSection";
-import { Metadata } from "next";
-
-export const metadata: Metadata = {
- title: "KG ROAD | Обращение",
- description:
- "Страница обращения Kyrgyzstan Transperency International",
-};
-
-const ReportDetails = async ({
- params,
-}: {
- params: { id: string };
-}) => {
- const getReportDetails = async () => {
- const res = await fetch(
- `${process.env.NEXT_PUBLIC_BASE_API}/report/${params.id}/`,
- { cache: "no-store" }
- );
-
- return res.json();
- };
- const report: IReport = await getReportDetails();
-
- const months: Record = {
- "01": "Январь",
- "02": "Февраль",
- "03": "Март",
- "04": "Апрель",
- "05": "Май",
- "06": "Июнь",
- "07": "Июль",
- "08": "Август",
- "09": "Сентябрь",
- "10": "Октябрь",
- "11": "Ноябрь",
- "12": "Декабрь",
- };
-
- const showImages = () => {
- const images = [];
-
- for (let i = 0; i < 5; i++) {
- if (report.image[i]) {
- const image = (
-
- );
- images.push(image);
- } else {
- const defImage = (
-
-
-
- );
- images.push(defImage);
- }
- }
-
- return images;
- };
-
- return (
-
-
-
-
- {ROAD_TYPES[report.category]}
-
-
{report.location[0].address}
-
-
-
-
- {months[report.created_at.slice(5, 7)]}{" "}
- {report.created_at.slice(5, 7).slice(0, 1) === "0"
- ? report.created_at.slice(6, 7)
- : report.created_at.slice(5, 7)}
- , {report.created_at.slice(0, 4)}
-
-
-
-
-
-
- {report.description}
-
-
-
- Автор обращения:{" "}
-
- {report.author.first_name}{" "}
- {report.author.last_name.slice(0, 1)}.
-
-
-
-
-
- {showImages().map((image) => image)}
-
-
-
-
-
- );
-};
-
-export default ReportDetails;
diff --git a/src/entities/NewsCard/NewsCard.tsx b/src/entities/NewsCard/NewsCard.tsx
index 7cb4f6f..45fc07d 100644
--- a/src/entities/NewsCard/NewsCard.tsx
+++ b/src/entities/NewsCard/NewsCard.tsx
@@ -3,6 +3,7 @@
import Image, { StaticImageData } from "next/image";
import "./NewsCard.scss";
import Link from "next/link";
+import { useTranslations } from "next-intl";
interface INewsCard {
id: number;
@@ -19,6 +20,7 @@ const NewsCard: React.FC = ({
description,
date,
}: INewsCard) => {
+ const t = useTranslations("general");
const sliceTitle = (title: string) => {
if (title.length > 35) {
return `${title.slice(0, 35)}...`;
@@ -57,7 +59,7 @@ const NewsCard: React.FC = ({
- Подробнее
+ {t("details")}
);
diff --git a/src/features/BreadCrumbs/BreadCrumbs.scss b/src/features/BreadCrumbs/BreadCrumbs.scss
new file mode 100644
index 0000000..a27803f
--- /dev/null
+++ b/src/features/BreadCrumbs/BreadCrumbs.scss
@@ -0,0 +1,5 @@
+.breadcrumbs {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
diff --git a/src/features/BreadCrumbs/BreadCrumbs.tsx b/src/features/BreadCrumbs/BreadCrumbs.tsx
new file mode 100644
index 0000000..68d7aae
--- /dev/null
+++ b/src/features/BreadCrumbs/BreadCrumbs.tsx
@@ -0,0 +1,9 @@
+"use client";
+
+import "./BreadCrumbs.scss";
+
+const BreadCrumbs = () => {
+ return ;
+};
+
+export default BreadCrumbs;
diff --git a/src/features/GoogleButton/GoogleButton.tsx b/src/features/GoogleButton/GoogleButton.tsx
index 4817ca7..af9d1dd 100644
--- a/src/features/GoogleButton/GoogleButton.tsx
+++ b/src/features/GoogleButton/GoogleButton.tsx
@@ -1,10 +1,27 @@
+"use client";
+
import Image from "next/image";
import "./GoogleButton.scss";
import google from "./icons/google.svg";
+import { useSearchParams } from "next/navigation";
+import { signIn, useSession } from "next-auth/react";
const GoogleButton = () => {
+ const session = useSession();
+ const searchParams = useSearchParams();
+ const callbackUrl =
+ searchParams.get("callbackUrl") || "/profile/personal";
+
+ const googleLogin = async () => {
+ await signIn("google", { callbackUrl });
+ };
+
return (
-