Add home page layout

This commit is contained in:
ariari04 2024-08-16 11:58:38 +06:00
parent 5bda172d1b
commit d1308e066f
18 changed files with 307 additions and 76 deletions

View File

@ -47,17 +47,18 @@
}, },
"navigation": { "navigation": {
"home": "Home", "home": "Home",
"about_us": "About Us",
"privacy": "Privacy Policy",
"support": "Support",
"statistics": "Statistics",
"news": "News", "news": "News",
"volunteers": "Volunteers",
"profile": "Profile", "profile": "Profile",
"login": "Login", "login": "Login",
"tenders": "Tenders", "tenders": "Tenders",
"contacts": "Contacts" "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": { "rights": {
"text": "All rights reserved" "text": "All rights reserved"
} }

View File

@ -44,17 +44,18 @@
}, },
"navigation": { "navigation": {
"home": "Башкы бет", "home": "Башкы бет",
"about_us": "Биз жөнүндө",
"privacy": "Купуялык саясаты",
"support": "Колдоо",
"statistics": "Статистика",
"news": "Жаңылыктар", "news": "Жаңылыктар",
"volunteers": "Ыктыярчылар",
"profile": "Профиль", "profile": "Профиль",
"login": "Кирүү", "login": "Кирүү",
"tenders": "Тендерлер", "tenders": "Тендерлер",
"contacts": "Контактылар" "contacts": "Контактылар"
}, },
"home": {
"instructions": "Инструкциялар",
"instructionsInfo": "Нускоодо сиз мамлекеттик кызматкерлердин укуктары жана милдеттери жөнүндө биле аласыз, керектүү документтердин формалары жана үлгүлөрү менен таанышып, иш убактысын, керектүү мамлекеттик уюмдардын даректерин жана телефондорун биле аласыз.",
"articles": "Макалалар",
"articlesBtn": "Бардык макалаларды окуу"
},
"disclaimer": { "disclaimer": {
"text": "Бул веб-сайт Европа Биримдиги тарабынан каржыланат. Анын мазмуну үчүн Трансперенси Интернешнл Кыргызстан гана жоопкерчиликтүү жана ал Европа Биримдигинин көз карашын сөзсүз түрдө чагылдырбайт." "text": "Бул веб-сайт Европа Биримдиги тарабынан каржыланат. Анын мазмуну үчүн Трансперенси Интернешнл Кыргызстан гана жоопкерчиликтүү жана ал Европа Биримдигинин көз карашын сөзсүз түрдө чагылдырбайт."
}, },

View File

@ -45,16 +45,18 @@
"navigation": { "navigation": {
"home": "Главная", "home": "Главная",
"about_us": "О нас", "about_us": "О нас",
"privacy": "Политика конфиденциальности",
"support": "Поддержка",
"statistics": "Статистика",
"news": "Новости", "news": "Новости",
"volunteers": "Волонтеры",
"profile": "Профиль", "profile": "Профиль",
"login": "Войти", "login": "Войти",
"tenders": "Тендеры", "tenders": "Тендеры",
"contacts": "Контакты" "contacts": "Контакты"
}, },
"home": {
"instructions": "Инструкции",
"instructionsInfo": "В инструкциях Вы можете узнать о своих правах и обязанностях служащих госорганов, ознакомиться с формами и образцами необходимых документов, узнать режим работы, адреса и телефоны необходимых государственных организаций.",
"articles": "Статьи",
"articlesBtn": "Читать все статьи"
},
"disclaimer": { "disclaimer": {
"text": "Этот веб-сайт финансируется Европейским Союзом. Ответственность за его содержание лежит исключительно на Трансперенси Интернешнл Кыргызстан и не обязательно отражает точку зрения Европейского Союза." "text": "Этот веб-сайт финансируется Европейским Союзом. Ответственность за его содержание лежит исключительно на Трансперенси Интернешнл Кыргызстан и не обязательно отражает точку зрения Европейского Союза."
}, },

21
package-lock.json generated
View File

@ -9,11 +9,13 @@
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"clsx": "^2.1.1",
"next": "14.2.5", "next": "14.2.5",
"next-auth": "^4.24.7", "next-auth": "^4.24.7",
"next-intl": "^3.17.2", "next-intl": "^3.17.2",
"react": "^18", "react": "^18",
"react-dom": "^18" "react-dom": "^18",
"tailwind-merge": "^2.5.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20", "@types/node": "^20",
@ -1209,6 +1211,14 @@
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" "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": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -4722,6 +4732,15 @@
"url": "https://github.com/sponsors/ljharb" "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": { "node_modules/tailwindcss": {
"version": "3.4.10", "version": "3.4.10",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",

View File

@ -10,11 +10,13 @@
}, },
"dependencies": { "dependencies": {
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"clsx": "^2.1.1",
"next": "14.2.5", "next": "14.2.5",
"next-auth": "^4.24.7", "next-auth": "^4.24.7",
"next-intl": "^3.17.2", "next-intl": "^3.17.2",
"react": "^18", "react": "^18",
"react-dom": "^18" "react-dom": "^18",
"tailwind-merge": "^2.5.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20", "@types/node": "^20",

BIN
public/assets/Image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

BIN
public/assets/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

View File

@ -1,5 +1,147 @@
import { Container, Title } from "@/shared/ui";
import document from "../../../public/assets/document-ui.png";
import Image from "next/image"; 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() { export default function Home() {
return <main></main>; const t = useTranslations("home");
return (
<>
<Container className="mt-[52px] mb-[21px] max-w-[1280px]">
<section
className="bg-cover bg-center h-[517px] bg-no-repeat flex justify-center items-center text-white w-full px-5"
style={{ background: "url('./assets/bg.png')" }}
>
<div className="max-w-[943px] text-center">
<Title
size="md"
text={"Transparency International "}
className="text-[24px] leading-8"
/>
<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>
</>
);
} }

6
src/lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

View File

@ -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>
);
};

39
src/shared/ui/Title.tsx Normal file
View File

@ -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
);
};

2
src/shared/ui/index.ts Normal file
View File

@ -0,0 +1,2 @@
export { Container } from "./Container";
export { Title } from "./Title";

View File

@ -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 play_market_btn from "./assets/play-market-btn.svg";
import { Link } from "@/shared/config/navigation"; import { Link } from "@/shared/config/navigation";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { LINKS } from "@/shared/variables/links_footer"; import { LINKS } from "@/shared/variables/links";
const Footer = () => { const Footer = () => {
const t = useTranslations("general"); const t = useTranslations("general");
const tDisclaimer = useTranslations("disclaimer"); const tDisclaimer = useTranslations("disclaimer");
const tRights = useTranslations("rights"); const tRights = useTranslations("rights");
return ( 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"> <div className="flex flex-col gap-6">
<p className="text-white font-normal">© {tRights("text")}</p> <p className="text-white font-normal">© {tRights("text")}</p>
<p className="text-white font-normal">{tDisclaimer("text")}</p> <p className="text-white font-normal">{tDisclaimer("text")}</p>
@ -60,9 +60,6 @@ const Footer = () => {
</Link> </Link>
))} ))}
</li> </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> </ul>
</div> </div>

View File

@ -46,8 +46,8 @@ const NavMenu: React.FC<INavMenuProps> = ({ setOpenMenu }: INavMenuProps) => {
]; ];
return ( 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"> <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"> {/* <div className="flex items-center justify-between">
<Link className="-m-1.5 p-1.5" href={"/"}> <Link className="-m-1.5 p-1.5" href={"/"}>
<Image src={logo} alt="Logo" className="h-8 w-auto" /> <Image src={logo} alt="Logo" className="h-8 w-auto" />
</Link> </Link>
@ -57,7 +57,7 @@ const NavMenu: React.FC<INavMenuProps> = ({ setOpenMenu }: INavMenuProps) => {
> >
<Image src={cross} alt="cross" /> <Image src={cross} alt="cross" />
</button> </button>
</div> </div> */}
{LINKS().map((link) => ( {LINKS().map((link) => (
<Link <Link
onClick={() => setOpenMenu(false)} onClick={() => setOpenMenu(false)}

View File

@ -16,6 +16,7 @@ import founded_en from "./assets/founded-en.png";
import founded_kg from "./assets/founded-kg.png"; import founded_kg from "./assets/founded-kg.png";
import { useParams } from "next/navigation"; import { useParams } from "next/navigation";
import NavAuth from "./NavAuth/NavAuth"; import NavAuth from "./NavAuth/NavAuth";
import { Container } from "@/shared/ui";
const Navbar = () => { const Navbar = () => {
const pathname = usePathname(); const pathname = usePathname();
@ -30,44 +31,46 @@ const Navbar = () => {
return ( return (
<header className="bg-white"> <header className="bg-white">
<nav className="mx-auto flex items-center justify-between py-6 lg:px-[90px] px-[90px] mm:px-[20px]"> <Container>
<div className="flex items-center gap-[10px]"> <nav className="mx-auto flex items-center justify-between py-6 mm:px-[20px]">
<Link href="/"> <div className="flex items-center gap-[10px]">
<Image src={logo} alt="Logo" className="navbar__logo-ti" /> <Link href="/">
</Link> <Image src={logo} alt="Logo" className="navbar__logo-ti" />
<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> </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> </nav>
<div className="hidden lg:flex items-center gap-6"> </Container>
<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>
</header> </header>
); );
}; };

View File

@ -8,21 +8,21 @@ const config: Config = {
"./src/widgets/**/*.{js,ts,jsx,tsx,mdx}", "./src/widgets/**/*.{js,ts,jsx,tsx,mdx}",
], ],
theme: { theme: {
extend: {}, extend: {
colors: { boxShadow: {
"custom-dark": "#0b2f33", "custom-blue": "0px 1px 4px 0px #E3EBFC",
"custom-blue": "#3998e8", },
white: "#fff", colors: {
"light-blue": "rgb(72, 159, 225)", "custom-dark": "#0b2f33",
blue: "#0077b6", "custom-blue": "#3998e8",
"red-500": "rgb(240, 68, 56)", white: "#fff",
"light-green": "rgb(74, 192, 63)", "light-blue": "rgb(72, 159, 225)",
blue: "#3695D8",
"gray-300": "#d0d5dd", "red-500": "rgb(240, 68, 56)",
"gray-500": "#667085", "light-green": "rgb(74, 192, 63)",
"gray-700": "#344054", "grey-text": "#66727F",
"gray-900": "rgb(16, 24, 40)", black: "#0B1F33",
black: "rgb(50, 48, 58)", },
}, },
}, },
plugins: [], plugins: [],