diff --git a/messages/en.json b/messages/en.json index bf9ab13..3dcb2a1 100644 --- a/messages/en.json +++ b/messages/en.json @@ -47,17 +47,18 @@ }, "navigation": { "home": "Home", - "about_us": "About Us", - "privacy": "Privacy Policy", - "support": "Support", - "statistics": "Statistics", "news": "News", - "volunteers": "Volunteers", "profile": "Profile", "login": "Login", "tenders": "Tenders", "contacts": "Contacts" }, + "home": { + "instructions": "Instructions", + "instructionsInfo": "In the instructions you can learn about your rights and obligations of government employees, familiarize yourself with the forms and samples of the necessary documents, find out the operating hours, addresses and telephone numbers of the necessary government organizations.", + "articles": "Articles", + "articlesBtn": "Read all articles" + }, "rights": { "text": "All rights reserved" } diff --git a/messages/kg.json b/messages/kg.json index 7005a7c..e7b9cc5 100644 --- a/messages/kg.json +++ b/messages/kg.json @@ -44,17 +44,18 @@ }, "navigation": { "home": "Башкы бет", - "about_us": "Биз жөнүндө", - "privacy": "Купуялык саясаты", - "support": "Колдоо", - "statistics": "Статистика", "news": "Жаңылыктар", - "volunteers": "Ыктыярчылар", "profile": "Профиль", "login": "Кирүү", "tenders": "Тендерлер", "contacts": "Контактылар" }, + "home": { + "instructions": "Инструкциялар", + "instructionsInfo": "Нускоодо сиз мамлекеттик кызматкерлердин укуктары жана милдеттери жөнүндө биле аласыз, керектүү документтердин формалары жана үлгүлөрү менен таанышып, иш убактысын, керектүү мамлекеттик уюмдардын даректерин жана телефондорун биле аласыз.", + "articles": "Макалалар", + "articlesBtn": "Бардык макалаларды окуу" + }, "disclaimer": { "text": "Бул веб-сайт Европа Биримдиги тарабынан каржыланат. Анын мазмуну үчүн Трансперенси Интернешнл Кыргызстан гана жоопкерчиликтүү жана ал Европа Биримдигинин көз карашын сөзсүз түрдө чагылдырбайт." }, diff --git a/messages/ru.json b/messages/ru.json index 0114b2a..d43a270 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -45,16 +45,18 @@ "navigation": { "home": "Главная", "about_us": "О нас", - "privacy": "Политика конфиденциальности", - "support": "Поддержка", - "statistics": "Статистика", "news": "Новости", - "volunteers": "Волонтеры", "profile": "Профиль", "login": "Войти", "tenders": "Тендеры", "contacts": "Контакты" }, + "home": { + "instructions": "Инструкции", + "instructionsInfo": "В инструкциях Вы можете узнать о своих правах и обязанностях служащих госорганов, ознакомиться с формами и образцами необходимых документов, узнать режим работы, адреса и телефоны необходимых государственных организаций.", + "articles": "Статьи", + "articlesBtn": "Читать все статьи" + }, "disclaimer": { "text": "Этот веб-сайт финансируется Европейским Союзом. Ответственность за его содержание лежит исключительно на Трансперенси Интернешнл Кыргызстан и не обязательно отражает точку зрения Европейского Союза." }, diff --git a/package-lock.json b/package-lock.json index 086f0a0..55e20cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,13 @@ "version": "0.1.0", "dependencies": { "autoprefixer": "^10.4.20", + "clsx": "^2.1.1", "next": "14.2.5", "next-auth": "^4.24.7", "next-intl": "^3.17.2", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "tailwind-merge": "^2.5.2" }, "devDependencies": { "@types/node": "^20", @@ -1209,6 +1211,14 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4722,6 +4732,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwind-merge": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz", + "integrity": "sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", diff --git a/package.json b/package.json index 85f8036..7b54664 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ }, "dependencies": { "autoprefixer": "^10.4.20", + "clsx": "^2.1.1", "next": "14.2.5", "next-auth": "^4.24.7", "next-intl": "^3.17.2", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "tailwind-merge": "^2.5.2" }, "devDependencies": { "@types/node": "^20", diff --git a/public/assets/Image.png b/public/assets/Image.png new file mode 100644 index 0000000..bad1e94 Binary files /dev/null and b/public/assets/Image.png differ diff --git a/public/assets/arrow-right.png b/public/assets/arrow-right.png new file mode 100644 index 0000000..c7c3cab Binary files /dev/null and b/public/assets/arrow-right.png differ diff --git a/public/assets/bg.png b/public/assets/bg.png new file mode 100644 index 0000000..13a1e09 Binary files /dev/null and b/public/assets/bg.png differ diff --git a/public/assets/document-ui.png b/public/assets/document-ui.png new file mode 100644 index 0000000..5e21a88 Binary files /dev/null and b/public/assets/document-ui.png differ diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx index 5a8f5bb..8f37eb1 100644 --- a/src/app/[locale]/page.tsx +++ b/src/app/[locale]/page.tsx @@ -1,5 +1,147 @@ +import { Container, Title } from "@/shared/ui"; +import document from "../../../public/assets/document-ui.png"; import Image from "next/image"; +import CardImg from "../../../public/assets/Image.png"; +import Arrow from "../../../public/assets/arrow-right.png"; +import { useTranslations } from "next-intl"; export default function Home() { - return
; + const t = useTranslations("home"); + + return ( + <> + +
+
+ + <Title + size="xl" + text={"Название проекта "} + className="font-extrabold leading-[76px]" + /> + <p className="leading-8"> + Torem ipsum dolor sit amet, consectetur adipiscing elit. Nunc + vulputate libero et velit interdum, ac aliquet odio mattis. Class + aptent taciti sociosqu ad litora torquent per conubia nostra + </p> + </div> + </section> + </Container> + + <section className="bg-[#FAFCFF]"> + <Container className="flex flex-col justify-center items-center"> + <div className="mt-[49px] mb-[45px] max-w-[730px]"> + <Title + size="2xl" + text={t("instructions")} + className="text-center text-black mb-[18px] leading-[60px] font-extrabold text-[40px]" + /> + <p className="text-center text-grey-text leading-[27px]"> + {t("instructionsInfo")} + </p> + </div> + <div className="flex justify-between gap-5 mb-[120px] flex-wrap sm:justify-center"> + <div className="bg-white w-[296px] h-[179px] p-[22px] rounded-lg shadow-md"> + <div className="flex text-black gap-[18px] items-center mb-7"> + <Image src={document} alt="document" /> + <p className="leading-6">Участие в тендере</p> + </div> + <p className="text-grey-text"> + Инструкция по тому как участвовать в тендерах + </p> + </div> + <div className="bg-white w-[296px] h-[179px] p-[22px] rounded-lg shadow-md"> + <div className="flex text-black gap-[18px] items-center mb-7"> + <Image src={document} alt="document" /> + <p className="leading-6">Подача жалобы</p> + </div> + <p className="text-grey-text"> + Инструкция по тому как подавать жалобы + </p> + </div> + <div className="bg-white w-[296px] h-[179px] p-[22px] rounded-lg shadow-md"> + <div className="flex text-black gap-[18px] items-center mb-7"> + <Image src={document} alt="document" /> + <p className="leading-6">Подача жалобы</p> + </div> + <p className="text-grey-text"> + Инструкция по тому как подавать жалобы + </p> + </div> + <div className="bg-white w-[296px] h-[179px] p-[22px] rounded-lg shadow-md"> + <div className="flex text-black gap-[18px] items-center mb-7"> + <Image src={document} alt="document" /> + <p className="leading-6">Подача жалобы</p> + </div> + <p className="text-grey-text"> + Инструкция по тому как подавать жалобы + </p> + </div> + </div> + <Title + text={t("articles")} + className="mb-[32px] font-extrabold text-black leading-[60px] text-[40px]" + size="lg" + /> + <section className="flex items-center gap-[33px] justify-between mb-[55px] flex-wrap"> + <article className="max-w-[393px] max-h-[508px] p-6 bg-white shadow-md text-grey-text rounded-md"> + <Image + src={CardImg} + alt="card" + width={345} + height={240} + className="rounded-md" + /> + <Title text="Worem ipsum dolor" className="mt-8 mb-3" /> + <p className="mb-12"> + Borem ipsum dolor sit amet, consectetur adipiscing elit. Borem + ipsum dolor sit amet + </p> + <p className="text-sm">26.10.2023</p> + </article> + <article className="max-w-[393px] max-h-[508px] p-6 bg-white shadow-md text-grey-text rounded-md"> + <Image + src={CardImg} + alt="card" + width={345} + height={240} + className="rounded-md" + /> + <Title text="Worem ipsum dolor" className="mt-8 mb-3" /> + <p className="mb-12"> + Borem ipsum dolor sit amet, consectetur adipiscing elit. Borem + ipsum dolor sit amet + </p> + <p className="text-sm">26.10.2023</p> + </article> + <article className="max-w-[393px] max-h-[508px] p-6 bg-white shadow-md text-grey-text rounded-md"> + <Image + src={CardImg} + alt="card" + width={345} + height={240} + className="rounded-md" + /> + <Title text="Worem ipsum dolor" className="mt-8 mb-3" /> + <p className="mb-12"> + Borem ipsum dolor sit amet, consectetur adipiscing elit. Borem + ipsum dolor sit amet + </p> + <p className="text-sm">26.10.2023</p> + </article> + </section> + <button className="flex gap-4 items-center justify-center text-blue w-[280px] h-[50px] rounded-md border border-blue ml-auto mb-[120px]"> + {t("articlesBtn")} <Image src={Arrow} alt="arrow" /> + </button> + </Container> + </section> + </> + ); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..365058c --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/src/shared/ui/Container.tsx b/src/shared/ui/Container.tsx new file mode 100644 index 0000000..6ecf532 --- /dev/null +++ b/src/shared/ui/Container.tsx @@ -0,0 +1,17 @@ +import { cn } from "@/lib/utils"; +import React from "react"; + +interface Props { + className?: string; +} + +export const Container: React.FC<React.PropsWithChildren<Props>> = ({ + className, + children, +}) => { + return ( + <div className={cn("mx-auto max-w-[1280px] px-2", className)}> + {children} + </div> + ); +}; diff --git a/src/shared/ui/Title.tsx b/src/shared/ui/Title.tsx new file mode 100644 index 0000000..8acc300 --- /dev/null +++ b/src/shared/ui/Title.tsx @@ -0,0 +1,39 @@ +import clsx from "clsx"; +import React from "react"; + +type TitleSize = "xs" | "sm" | "md" | "lg" | "xl" | "2xl"; + +interface Props { + size?: TitleSize; + className?: string; + text: string; +} + +export const Title: React.FC<Props> = ({ text, size = "sm", className }) => { + const mapTagBySize: Record<TitleSize, React.ElementType> = { + xs: "h5", + sm: "h4", + md: "h3", + lg: "h2", + xl: "h1", + "2xl": "h1", + }; + + const mapClassNameBySize: Record<TitleSize, string> = { + xs: "text-[16px]", + sm: "text-[22px]", + md: "text-[26px]", + lg: "text-[32px]", + xl: "text-[40px]", + "2xl": "text-[48px]", + }; + + const Tag = mapTagBySize[size] || "h4"; + const sizeClassName = mapClassNameBySize[size] || "text-[22px]"; + + return React.createElement( + Tag, + { className: clsx(sizeClassName, className) }, + text + ); +}; diff --git a/src/shared/ui/index.ts b/src/shared/ui/index.ts new file mode 100644 index 0000000..6d78d7e --- /dev/null +++ b/src/shared/ui/index.ts @@ -0,0 +1,2 @@ +export { Container } from "./Container"; +export { Title } from "./Title"; diff --git a/src/widgets/Footer/Footer.tsx b/src/widgets/Footer/Footer.tsx index 3516f59..3e944c7 100644 --- a/src/widgets/Footer/Footer.tsx +++ b/src/widgets/Footer/Footer.tsx @@ -6,14 +6,14 @@ import app_store_btn from "./assets/app-store-btn.svg"; import play_market_btn from "./assets/play-market-btn.svg"; import { Link } from "@/shared/config/navigation"; import { useTranslations } from "next-intl"; -import { LINKS } from "@/shared/variables/links_footer"; +import { LINKS } from "@/shared/variables/links"; const Footer = () => { const t = useTranslations("general"); const tDisclaimer = useTranslations("disclaimer"); const tRights = useTranslations("rights"); return ( - <footer className="px-12 py-20 grid grid-cols-4 gap-[30px] bg-custom-dark"> + <footer className="px-12 py-20 grid grid-cols-4 gap-[30px] bg-[#0F172A]"> <div className="flex flex-col gap-6"> <p className="text-white font-normal">© {tRights("text")}</p> <p className="text-white font-normal">{tDisclaimer("text")}</p> @@ -60,9 +60,6 @@ const Footer = () => { </Link> ))} </li> - <li className="h-fit flex justify-start text-base text-[#e2e8f0] font-normal leading-[140%] items-center gap-4"> - Photo By ThomasG, CC BY-SA 3.0 - </li> </ul> </div> diff --git a/src/widgets/Navbar/NavMenu/NavMenu.tsx b/src/widgets/Navbar/NavMenu/NavMenu.tsx index bae6f73..33b7b2b 100644 --- a/src/widgets/Navbar/NavMenu/NavMenu.tsx +++ b/src/widgets/Navbar/NavMenu/NavMenu.tsx @@ -46,8 +46,8 @@ const NavMenu: React.FC<INavMenuProps> = ({ setOpenMenu }: INavMenuProps) => { ]; return ( - <nav className="p-[48px] w-full h-full min-h-[600px] fixed left-0 flex flex-col gap-6 bg-white scroll inset-y-0 right-0 z-50 overflow-y-auto"> - <div className="flex items-center justify-between"> + <nav className="p-[48px] w-full h-full min-h-[600px] fixed left-0 top-[120px] flex flex-col gap-6 bg-white scroll inset-y-0 right-0 z-50 overflow-y-auto"> + {/* <div className="flex items-center justify-between"> <Link className="-m-1.5 p-1.5" href={"/"}> <Image src={logo} alt="Logo" className="h-8 w-auto" /> </Link> @@ -57,7 +57,7 @@ const NavMenu: React.FC<INavMenuProps> = ({ setOpenMenu }: INavMenuProps) => { > <Image src={cross} alt="cross" /> </button> - </div> + </div> */} {LINKS().map((link) => ( <Link onClick={() => setOpenMenu(false)} diff --git a/src/widgets/Navbar/Navbar.tsx b/src/widgets/Navbar/Navbar.tsx index 539259e..e80bc10 100644 --- a/src/widgets/Navbar/Navbar.tsx +++ b/src/widgets/Navbar/Navbar.tsx @@ -16,6 +16,7 @@ import founded_en from "./assets/founded-en.png"; import founded_kg from "./assets/founded-kg.png"; import { useParams } from "next/navigation"; import NavAuth from "./NavAuth/NavAuth"; +import { Container } from "@/shared/ui"; const Navbar = () => { const pathname = usePathname(); @@ -30,44 +31,46 @@ const Navbar = () => { return ( <header className="bg-white"> - <nav className="mx-auto flex items-center justify-between py-6 lg:px-[90px] px-[90px] mm:px-[20px]"> - <div className="flex items-center gap-[10px]"> - <Link href="/"> - <Image src={logo} alt="Logo" className="navbar__logo-ti" /> - </Link> - <Image - className="mt-[30px] h-[120px] w-[120px] inline-block mr-[10px] object-cover" - src={FOUNDED[locale as string]} - alt="Founded by EU Image" - /> - <NavLanguage /> - </div> - <nav className="hidden lg:flex lg:gap-x-6"> - {LINKS().map((link) => ( - <Link - className={`text-black opacity-0.5 size-4 font-normal min-w-[150px] flex justify-center${ - pathname === link.pathname ? "opacity-1 font-extrabold" : "" - }`} - key={link.id} - href={link.pathname} - > - {link.pagename} + <Container> + <nav className="mx-auto flex items-center justify-between py-6 mm:px-[20px]"> + <div className="flex items-center gap-[10px]"> + <Link href="/"> + <Image src={logo} alt="Logo" className="navbar__logo-ti" /> </Link> - ))} + <Image + className="mt-[30px] h-[120px] w-[120px] inline-block mr-[10px] object-cover" + src={FOUNDED[locale as string]} + alt="Founded by EU Image" + /> + <NavLanguage /> + </div> + <nav className="hidden lg:flex lg:gap-x-6"> + {LINKS().map((link) => ( + <Link + className={`text-black opacity-0.5 size-4 font-normal min-w-[150px] flex justify-center${ + pathname === link.pathname ? "opacity-1 font-extrabold" : "" + }`} + key={link.id} + href={link.pathname} + > + {link.pagename} + </Link> + ))} + </nav> + <div className="hidden lg:flex items-center gap-6"> + <NavAuth setOpenMenu={setOpenMenu} /> + </div> + + <button + onClick={() => setOpenMenu((prev) => !prev)} + className="flex lg:hidden" + > + <Image src={openMenu ? cross : menu} alt="menu icon" /> + </button> + + {openMenu && <NavMenu setOpenMenu={setOpenMenu} />} </nav> - <div className="hidden lg:flex items-center gap-6"> - <NavAuth setOpenMenu={setOpenMenu} /> - </div> - - <button - onClick={() => setOpenMenu((prev) => !prev)} - className="hidden sm:flex" - > - <Image src={openMenu ? cross : menu} alt="menu icon" /> - </button> - - {openMenu && <NavMenu setOpenMenu={setOpenMenu} />} - </nav> + </Container> </header> ); }; diff --git a/tailwind.config.ts b/tailwind.config.ts index 501d3e4..5bd5c4b 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -8,21 +8,21 @@ const config: Config = { "./src/widgets/**/*.{js,ts,jsx,tsx,mdx}", ], theme: { - extend: {}, - colors: { - "custom-dark": "#0b2f33", - "custom-blue": "#3998e8", - white: "#fff", - "light-blue": "rgb(72, 159, 225)", - blue: "#0077b6", - "red-500": "rgb(240, 68, 56)", - "light-green": "rgb(74, 192, 63)", - - "gray-300": "#d0d5dd", - "gray-500": "#667085", - "gray-700": "#344054", - "gray-900": "rgb(16, 24, 40)", - black: "rgb(50, 48, 58)", + extend: { + boxShadow: { + "custom-blue": "0px 1px 4px 0px #E3EBFC", + }, + colors: { + "custom-dark": "#0b2f33", + "custom-blue": "#3998e8", + white: "#fff", + "light-blue": "rgb(72, 159, 225)", + blue: "#3695D8", + "red-500": "rgb(240, 68, 56)", + "light-green": "rgb(74, 192, 63)", + "grey-text": "#66727F", + black: "#0B1F33", + }, }, }, plugins: [],