diff --git a/messages/en.json b/messages/en.json
new file mode 100644
index 0000000..c13fd53
--- /dev/null
+++ b/messages/en.json
@@ -0,0 +1,62 @@
+{
+ "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"
+ },
+ "disclaimer": {
+ "text": "This website is funded by the European Union. Its contents are the sole responsibility of Transparency International Kyrgyzstan and do not necessarily reflect the views of the European Union."
+ },
+ "navigation": {
+ "home": "Home",
+ "about_us": "About Us",
+ "privacy": "Privacy Policy",
+ "support": "Support",
+ "statistics": "Statistics",
+ "news": "News",
+ "volunteers": "Volunteers",
+ "profile": "Profile",
+ "login": "Login"
+ },
+ "rights": {
+ "text": "All rights reserved"
+ }
+}
diff --git a/messages/kg.json b/messages/kg.json
new file mode 100644
index 0000000..b499500
--- /dev/null
+++ b/messages/kg.json
@@ -0,0 +1,62 @@
+{
+ "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": "Биз жөнүндө",
+ "privacy": "Купуялык саясаты",
+ "support": "Колдоо",
+ "statistics": "Статистика",
+ "news": "Жаңылыктар",
+ "volunteers": "Ыктыярчылар",
+ "profile": "Профиль",
+ "login": "Кирүү"
+ },
+ "disclaimer": {
+ "text": "Бул веб-сайт Европа Биримдиги тарабынан каржыланат. Анын мазмуну үчүн Трансперенси Интернешнл Кыргызстан гана жоопкерчиликтүү жана ал Европа Биримдигинин көз карашын сөзсүз түрдө чагылдырбайт."
+ },
+ "rights": {
+ "text": "Бардык укуктар корголгон"
+ }
+}
diff --git a/messages/ru.json b/messages/ru.json
new file mode 100644
index 0000000..ee97ef0
--- /dev/null
+++ b/messages/ru.json
@@ -0,0 +1,62 @@
+{
+ "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": "О нас",
+ "privacy": "Политика конфиденциальности",
+ "support": "Поддержка",
+ "statistics": "Статистика",
+ "news": "Новости",
+ "volunteers": "Волонтеры",
+ "profile": "Профиль",
+ "login": "Войти"
+ },
+ "disclaimer": {
+ "text": "Этот веб-сайт финансируется Европейским Союзом. Ответственность за его содержание лежит исключительно на Трансперенси Интернешнл Кыргызстан и не обязательно отражает точку зрения Европейского Союза."
+ },
+ "rights": {
+ "text": "Все права защищены"
+ }
+}
diff --git a/next.config.mjs b/next.config.mjs
index 4678774..9e682c8 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,4 +1,16 @@
-/** @type {import('next').NextConfig} */
-const nextConfig = {};
+import createNextIntlPlugin from "next-intl/plugin";
+const withNextIntl = createNextIntlPlugin();
-export default nextConfig;
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "**",
+ },
+ ],
+ },
+};
+
+export default withNextIntl(nextConfig);
diff --git a/package-lock.json b/package-lock.json
index b1b5890..4251bf6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"next": "14.2.5",
+ "next-intl": "^3.17.2",
"react": "^18",
"react-dom": "^18"
},
@@ -91,6 +92,58 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz",
+ "integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==",
+ "dependencies": {
+ "@formatjs/intl-localematcher": "0.5.4",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/ecma402-abstract/node_modules/@formatjs/intl-localematcher": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
+ "integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
+ "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "2.7.8",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz",
+ "integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.0.0",
+ "@formatjs/icu-skeleton-parser": "1.8.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz",
+ "integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.0.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/intl-localematcher": {
+ "version": "0.2.32",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.32.tgz",
+ "integrity": "sha512-k/MEBstff4sttohyEpXxCmC3MqbUn9VvHGlZ8fauLzkbwXmVrEeyzS+4uhrvAk9DWU9/7otYWxyDox4nT/KVLQ==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
@@ -2464,6 +2517,17 @@
"node": ">= 0.4"
}
},
+ "node_modules/intl-messageformat": {
+ "version": "10.5.14",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.14.tgz",
+ "integrity": "sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.0.0",
+ "@formatjs/fast-memoize": "2.2.0",
+ "@formatjs/icu-messageformat-parser": "2.7.8",
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -3149,6 +3213,14 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/next": {
"version": "14.2.5",
"resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz",
@@ -3198,6 +3270,26 @@
}
}
},
+ "node_modules/next-intl": {
+ "version": "3.17.2",
+ "resolved": "https://registry.npmjs.org/next-intl/-/next-intl-3.17.2.tgz",
+ "integrity": "sha512-X2ly23e1lC5vdWHaJFBDZi/0iornEdFQQtqJmmPOb7WD+LDssm9vAnx+hJshYGjddaP3rUmyWaPgePCQqaxm1g==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/amannn"
+ }
+ ],
+ "dependencies": {
+ "@formatjs/intl-localematcher": "^0.2.32",
+ "negotiator": "^0.6.3",
+ "use-intl": "^3.17.2"
+ },
+ "peerDependencies": {
+ "next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -4647,6 +4739,18 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/use-intl": {
+ "version": "3.17.2",
+ "resolved": "https://registry.npmjs.org/use-intl/-/use-intl-3.17.2.tgz",
+ "integrity": "sha512-9lPgt41nS8x4AYCLfIC9VKCmamnVxzPM2nze7lpp/I1uaSSQvIz5MQpYUFikv08cMUsCwAWahU0e+arHInpdcw==",
+ "dependencies": {
+ "@formatjs/fast-memoize": "^2.2.0",
+ "intl-messageformat": "^10.5.14"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/package.json b/package.json
index 552b534..2542221 100644
--- a/package.json
+++ b/package.json
@@ -9,18 +9,19 @@
"lint": "next lint"
},
"dependencies": {
+ "next": "14.2.5",
+ "next-intl": "^3.17.2",
"react": "^18",
- "react-dom": "^18",
- "next": "14.2.5"
+ "react-dom": "^18"
},
"devDependencies": {
- "typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
+ "eslint": "^8",
+ "eslint-config-next": "14.2.5",
"postcss": "^8",
"tailwindcss": "^3.4.1",
- "eslint": "^8",
- "eslint-config-next": "14.2.5"
+ "typescript": "^5"
}
}
diff --git a/src/app/[locale]/globals.css b/src/app/[locale]/globals.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/src/app/[locale]/globals.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx
new file mode 100644
index 0000000..e1848a9
--- /dev/null
+++ b/src/app/[locale]/layout.tsx
@@ -0,0 +1,31 @@
+import type { Metadata } from "next";
+import { Inter } from "next/font/google";
+import "./globals.css";
+import { NextIntlClientProvider, useMessages } from "next-intl";
+import Footer from "../widgets/Footer/Footer";
+
+const inter = Inter({ subsets: ["latin"] });
+
+export const metadata: Metadata = {
+ title: "Create Next App",
+ description: "Generated by create next app",
+};
+
+export default function RootLayout({
+ children,
+ params,
+}: Readonly<{
+ children: React.ReactNode;
+ params: { locale: string };
+}>) {
+ const messages = useMessages();
+
+ return (
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx
new file mode 100644
index 0000000..5a8f5bb
--- /dev/null
+++ b/src/app/[locale]/page.tsx
@@ -0,0 +1,5 @@
+import Image from "next/image";
+
+export default function Home() {
+ return ;
+}
diff --git a/src/app/favicon.ico b/src/app/favicon.ico
deleted file mode 100644
index 718d6fe..0000000
Binary files a/src/app/favicon.ico and /dev/null differ
diff --git a/src/app/globals.css b/src/app/globals.css
deleted file mode 100644
index 875c01e..0000000
--- a/src/app/globals.css
+++ /dev/null
@@ -1,33 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-:root {
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
- }
-}
-
-body {
- color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
-}
-
-@layer utilities {
- .text-balance {
- text-wrap: balance;
- }
-}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 3314e47..568d357 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,22 +1,9 @@
-import type { Metadata } from "next";
-import { Inter } from "next/font/google";
-import "./globals.css";
+import { ReactNode } from "react";
-const inter = Inter({ subsets: ["latin"] });
-
-export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+type Props = {
+ children: ReactNode;
};
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
{children}
-
- );
+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..04bb475
--- /dev/null
+++ b/src/app/not-found.tsx
@@ -0,0 +1,15 @@
+"use client";
+
+// import "./globals.scss";
+// import "@/shared/fonts/fonts.scss";
+import NotFound from "./widgets/NotFound/NotFound";
+
+export default function NotFoundPage() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 2acfd44..65bec62 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,113 +1,7 @@
-import Image from "next/image";
+import React from "react";
-export default function Home() {
- return (
-
-
-
- Get started by editing
- src/app/page.tsx
-
-
-
+const page = () => {
+ return RootPage
;
+};
-
-
-
-
-
-
- );
-}
+export default page;
diff --git a/src/app/shared/config/navigation.ts b/src/app/shared/config/navigation.ts
new file mode 100644
index 0000000..fa72bff
--- /dev/null
+++ b/src/app/shared/config/navigation.ts
@@ -0,0 +1,7 @@
+import { createSharedPathnamesNavigation } from "next-intl/navigation";
+
+export const locales = ["en", "ru", "kg"] as const;
+export const localePrefix = "always";
+
+export const { Link, redirect, usePathname, useRouter } =
+ createSharedPathnamesNavigation({ locales, localePrefix });
diff --git a/src/app/shared/variables/links_footer.ts b/src/app/shared/variables/links_footer.ts
new file mode 100644
index 0000000..38d6b30
--- /dev/null
+++ b/src/app/shared/variables/links_footer.ts
@@ -0,0 +1,17 @@
+import { useTranslations } from "next-intl";
+
+export const LINKS = () => {
+ const t = useTranslations("navigation");
+
+ const LINKS = [
+ { id: 1, pagename: t("home"), pathname: "/" },
+ { id: 2, pagename: t("about_us"), pathname: "/about-us" },
+ { id: 3, pagename: t("privacy"), pathname: "/privacy" },
+ { id: 3, pagename: t("support"), pathname: "/support" },
+ { id: 4, pagename: t("statistics"), pathname: "/statistics" },
+ { id: 5, pagename: t("news"), pathname: "/news" },
+ { id: 6, pagename: t("volunteers"), pathname: "/volunteers" },
+ ];
+
+ return LINKS;
+};
diff --git a/src/app/widgets/Footer/Footer.tsx b/src/app/widgets/Footer/Footer.tsx
new file mode 100644
index 0000000..ade8433
--- /dev/null
+++ b/src/app/widgets/Footer/Footer.tsx
@@ -0,0 +1,89 @@
+import Image from "next/image";
+import youtube from "./assets/youtube.svg";
+import facebook from "./assets/facebook.svg";
+import instagram from "./assets/instagram.svg";
+import app_store_btn from "./assets/app-store-btn.svg";
+import play_market_btn from "./assets/play-market-btn.svg";
+import { Link } from "@/app/shared/config/navigation";
+import { useTranslations } from "next-intl";
+import { LINKS } from "@/app/shared/variables/links_footer";
+
+const Footer = () => {
+ const t = useTranslations("general");
+ const tDisclaimer = useTranslations("disclaimer");
+ const tRights = useTranslations("rights");
+ return (
+
+ );
+};
+
+export default Footer;
diff --git a/src/app/widgets/Footer/assets/app-store-btn.svg b/src/app/widgets/Footer/assets/app-store-btn.svg
new file mode 100644
index 0000000..6ffe080
--- /dev/null
+++ b/src/app/widgets/Footer/assets/app-store-btn.svg
@@ -0,0 +1,31 @@
+
diff --git a/src/app/widgets/Footer/assets/facebook.svg b/src/app/widgets/Footer/assets/facebook.svg
new file mode 100644
index 0000000..6949748
--- /dev/null
+++ b/src/app/widgets/Footer/assets/facebook.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/app/widgets/Footer/assets/instagram.svg b/src/app/widgets/Footer/assets/instagram.svg
new file mode 100644
index 0000000..1792ce2
--- /dev/null
+++ b/src/app/widgets/Footer/assets/instagram.svg
@@ -0,0 +1,16 @@
+
diff --git a/src/app/widgets/Footer/assets/play-market-btn.svg b/src/app/widgets/Footer/assets/play-market-btn.svg
new file mode 100644
index 0000000..db84ca5
--- /dev/null
+++ b/src/app/widgets/Footer/assets/play-market-btn.svg
@@ -0,0 +1,15 @@
+
diff --git a/src/app/widgets/Footer/assets/youtube.svg b/src/app/widgets/Footer/assets/youtube.svg
new file mode 100644
index 0000000..638ad52
--- /dev/null
+++ b/src/app/widgets/Footer/assets/youtube.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/app/widgets/NotFound/NotFound.tsx b/src/app/widgets/NotFound/NotFound.tsx
new file mode 100644
index 0000000..98fb7c9
--- /dev/null
+++ b/src/app/widgets/NotFound/NotFound.tsx
@@ -0,0 +1,30 @@
+import Link from "next/link";
+import not_found from "./assets/not-found.svg";
+
+const NotFound = () => {
+ return (
+
+
+
+
+ Страница не найдена (404)
+
+
+ Неправильно набран адрес или такой страницы не существует.
+
+
+
+ На главную
+
+
+ );
+};
+
+export default NotFound;
diff --git a/src/app/widgets/NotFound/assets/not-found.svg b/src/app/widgets/NotFound/assets/not-found.svg
new file mode 100644
index 0000000..5c5309a
--- /dev/null
+++ b/src/app/widgets/NotFound/assets/not-found.svg
@@ -0,0 +1,16 @@
+
diff --git a/src/i18n.ts b/src/i18n.ts
new file mode 100644
index 0000000..fb87efc
--- /dev/null
+++ b/src/i18n.ts
@@ -0,0 +1,12 @@
+import { notFound } from "next/navigation";
+import { getRequestConfig } from "next-intl/server";
+// Can be imported from a shared config
+const locales = ["en", "ru", "kg"];
+
+export default getRequestConfig(async ({ locale }) => {
+ if (!locales.includes(locale as any)) notFound();
+
+ return {
+ messages: (await import(`../messages/${locale}.json`)).default,
+ };
+});
diff --git a/src/middleware.ts b/src/middleware.ts
new file mode 100644
index 0000000..9d616ab
--- /dev/null
+++ b/src/middleware.ts
@@ -0,0 +1,13 @@
+import createMiddleware from "next-intl/middleware";
+
+export default createMiddleware({
+ // A list of all locales that are supported
+ locales: ["en", "ru", "kg"],
+ // Used when no locale matches
+ defaultLocale: "ru",
+});
+
+export const config = {
+ // Match only internationalized pathnames
+ matcher: ["/", "/(en|ru|kg)/:path*"],
+};
diff --git a/tailwind.config.ts b/tailwind.config.ts
index e9a0944..c38a843 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -14,6 +14,11 @@ const config: Config = {
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
},
+ colors: {
+ "custom-dark": "#0b2f33",
+ "custom-blue": "#3998e8",
+ white: "#fff",
+ },
},
plugins: [],
};