diff --git a/.env.development b/.env similarity index 75% rename from .env.development rename to .env index d29bb5a..41de27d 100644 --- a/.env.development +++ b/.env @@ -2,5 +2,4 @@ IMAGES_PROTOCOL=https IMAGES_DOMAIN=cdn-tp1.mozu.com IMAGES_PORT=80 -NEXT_PUBLIC_BASE_URL=http://127.0.0.1:3000 NEXT_PUBLIC_API_URL=https://jellybellywikiapi.onrender.com/api \ No newline at end of file diff --git a/README.md b/README.md index c403366..5f82fee 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,57 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +# JellyBelly Wiki +> JellyBelly Wiki - сайт о бобах JellyBelly -## Getting Started -First, run the development server: -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` +## Стек +- TypeScript +- React 18 +- Next.js 14 (App Router) +- Tailwind CSS +- Zod +- next-themes -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +## О проекте +- Написан за 10 часов (с использованием произвольных библиотек и snippet-ов прошлых проектов), в качестве тестового задания перед собеседованием +- Основан на открытом API https://jelly-belly-wiki.netlify.app +- Server Side Rendering (SSR) - в ответ на запрос пользователя сервер отправляет сгенерированный HTML заполненный контентом, а затем загружается весь необходимый для работы JavaScript. Для пользователя страница загружается быстрее +- Search Engine Optimization (SEO) - благодаря SSR поисковые боты могут индексировать страницы (в отличии от приложений написанных с использованием SPA подхода) +- Адаптивная верстка + - Поддержка мобильных устройств (в том числе планшетов) + - Верстка на основе rem + - Автоматическое масштабирование для малых и больших разрешений (сайт выглядит одинаково при любых разрешениях 16:9) +- Написан в соответствии с [Feature-Sliced Design (FSD)](https://feature-sliced.design/ru/) +- Легко масштабируемый + - Сущности, для которых необходимо реализовать общий функционал (например ленивую загрузку карточек) объедены абстракцией [item](./src//entities//item/) - это позволяет переиспользовать компонент [Grid](./src/widgets/grid/), а так же писать компоненты обёртки, например [ItemCard](./src/features/itemCard/) или [ItemInfo](./src/features/itemInfo/) + - Каждой сущности в рамках [item](./src//entities//item/), поставлена в соответствие секция [section](./src/features/sections/) - это позволяет написать переискользуемую страницу [\[section\]](./src/app/%5Bsection%5D/) и динамический [header](./src/widgets/header/) + - Вместе эти уровни абстракции позволяют, при необходимости, легко добавить новые сущности +- Валидация данных с помощью схем Zod + - Все данные, полученные с API валидируются с помощью библиотеки Zod + - При получении списка объектов, каждый валидируется отдельно, в случае возникновения ошибок, бракованный объект удаляется из списка, а остальные данные поступают в рендер - это обеспечивает отказоустойчивость, при единичных ошибках в данных +- Lazy loading - новые карточки подгружаются по мере необходимости при просмотре (скроллинге) страницы +- Используется цветовая схема [Solarized](https://en.wikipedia.org/wiki/Solarized). Есть возможность переключения между тёмной и светлой схемой -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. +## Скриншоты -## Learn More +#### Desktop (HD+) +|![](./screenshots/HD%2B_root_dark.png)|![](./screenshots/HD%2B_root_light.png)| +|-|-| +|![](./screenshots/HD%2B_beans_light.png)|![](./screenshots/HD%2B_recipes_dark.png)| +|![](./screenshots/HD%2B_bean_light.png)|![](./screenshots/HD%2B_recipe_dark.png)| -To learn more about Next.js, take a look at the following resources: +#### Tablet (iPad) +|![](./screenshots/iPad_beans_light.png)|![](./screenshots/iPad_recipes_dark.png)| +|-|-| +|![](./screenshots/iPad_bean_light.png)|![](./screenshots/iPad_recipe_dark.png)| +|![](./screenshots/iPad_history_light.png)|![](./screenshots/iPad_facts_dark.png)| -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +#### Mobile (iPhoneX) +|![](./screenshots/iPhoneX_beans_light.png)|![](./screenshots/iPhoneX_bean_light.png)|![](./screenshots/iPhoneX_combinations_light.png)| +|-|-|-| +|![](./screenshots/iPhoneX_recipes_dark.png)|![](./screenshots/iPhoneX_recipe_dark.png)|![](./screenshots/iPhoneX_facts_dark.png)| -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. +## Запуск +#### Локально + npm install + npm run dev \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 952bd5e..8b15c0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,19 +8,16 @@ "name": "jelly_belly_wiki", "version": "0.1.0", "dependencies": { - "clsx": "^2.1.1", "next": "14.2.4", "next-themes": "^0.3.0", "react": "^18", "react-dom": "^18", - "react-responsive-masonry": "^2.2.1", "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", - "@types/react-responsive-masonry": "^2.1.3", "eslint": "^8", "eslint-config-next": "14.2.4", "postcss": "^8", @@ -477,15 +474,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-responsive-masonry": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/react-responsive-masonry/-/react-responsive-masonry-2.1.3.tgz", - "integrity": "sha512-aOFUtv3QwNMmy0BgpQpvivQ/+vivMTB6ARrzf9eTSXsLzXpVnfEtjpHpSknYDnr8KaQmlgeauAj8E7wo/qMOTg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@typescript-eslint/parser": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", @@ -1094,14 +1082,6 @@ "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", @@ -3830,14 +3810,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, - "node_modules/react-responsive-masonry": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-responsive-masonry/-/react-responsive-masonry-2.2.1.tgz", - "integrity": "sha512-QY1vH8vWd8YpW2g40zsFp4CjttK2NWw2btzHbxks8vDRe+0JZfsrtK7Ob3siCtg+9mttwsofmAB6dp9ujSYwKw==", - "dependencies": { - "caniuse-lite": "^1.0.30001638" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/package.json b/package.json index ec815fa..46c1386 100644 --- a/package.json +++ b/package.json @@ -9,19 +9,16 @@ "lint": "next lint" }, "dependencies": { - "clsx": "^2.1.1", "next": "14.2.4", "next-themes": "^0.3.0", "react": "^18", "react-dom": "^18", - "react-responsive-masonry": "^2.2.1", "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", - "@types/react-responsive-masonry": "^2.1.3", "eslint": "^8", "eslint-config-next": "14.2.4", "postcss": "^8", diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/screenshots/HD+_bean_light.png b/screenshots/HD+_bean_light.png new file mode 100644 index 0000000..4d96611 Binary files /dev/null and b/screenshots/HD+_bean_light.png differ diff --git a/screenshots/HD+_beans_light.png b/screenshots/HD+_beans_light.png new file mode 100644 index 0000000..be9dbf5 Binary files /dev/null and b/screenshots/HD+_beans_light.png differ diff --git a/screenshots/HD+_recipe_dark.png b/screenshots/HD+_recipe_dark.png new file mode 100644 index 0000000..b1c39e7 Binary files /dev/null and b/screenshots/HD+_recipe_dark.png differ diff --git a/screenshots/HD+_recipes_dark.png b/screenshots/HD+_recipes_dark.png new file mode 100644 index 0000000..8f16d6f Binary files /dev/null and b/screenshots/HD+_recipes_dark.png differ diff --git a/screenshots/HD+_root_dark.png b/screenshots/HD+_root_dark.png new file mode 100644 index 0000000..c3db597 Binary files /dev/null and b/screenshots/HD+_root_dark.png differ diff --git a/screenshots/HD+_root_light.png b/screenshots/HD+_root_light.png new file mode 100644 index 0000000..0607b74 Binary files /dev/null and b/screenshots/HD+_root_light.png differ diff --git a/screenshots/iPad_bean_light.png b/screenshots/iPad_bean_light.png new file mode 100644 index 0000000..9261976 Binary files /dev/null and b/screenshots/iPad_bean_light.png differ diff --git a/screenshots/iPad_beans_light.png b/screenshots/iPad_beans_light.png new file mode 100644 index 0000000..4e6140e Binary files /dev/null and b/screenshots/iPad_beans_light.png differ diff --git a/screenshots/iPad_facts_dark.png b/screenshots/iPad_facts_dark.png new file mode 100644 index 0000000..779c6cc Binary files /dev/null and b/screenshots/iPad_facts_dark.png differ diff --git a/screenshots/iPad_history_light.png b/screenshots/iPad_history_light.png new file mode 100644 index 0000000..833aa9c Binary files /dev/null and b/screenshots/iPad_history_light.png differ diff --git a/screenshots/iPad_recipe_dark.png b/screenshots/iPad_recipe_dark.png new file mode 100644 index 0000000..447c04b Binary files /dev/null and b/screenshots/iPad_recipe_dark.png differ diff --git a/screenshots/iPad_recipes_dark.png b/screenshots/iPad_recipes_dark.png new file mode 100644 index 0000000..a2f111a Binary files /dev/null and b/screenshots/iPad_recipes_dark.png differ diff --git a/screenshots/iPhoneX_bean_light.png b/screenshots/iPhoneX_bean_light.png new file mode 100644 index 0000000..18ea0a6 Binary files /dev/null and b/screenshots/iPhoneX_bean_light.png differ diff --git a/screenshots/iPhoneX_beans_light.png b/screenshots/iPhoneX_beans_light.png new file mode 100644 index 0000000..63f2717 Binary files /dev/null and b/screenshots/iPhoneX_beans_light.png differ diff --git a/screenshots/iPhoneX_combinations_light.png b/screenshots/iPhoneX_combinations_light.png new file mode 100644 index 0000000..bba188d Binary files /dev/null and b/screenshots/iPhoneX_combinations_light.png differ diff --git a/screenshots/iPhoneX_facts_dark.png b/screenshots/iPhoneX_facts_dark.png new file mode 100644 index 0000000..480ef88 Binary files /dev/null and b/screenshots/iPhoneX_facts_dark.png differ diff --git a/screenshots/iPhoneX_recipe_dark.png b/screenshots/iPhoneX_recipe_dark.png new file mode 100644 index 0000000..c656698 Binary files /dev/null and b/screenshots/iPhoneX_recipe_dark.png differ diff --git a/screenshots/iPhoneX_recipes_dark.png b/screenshots/iPhoneX_recipes_dark.png new file mode 100644 index 0000000..69ac82b Binary files /dev/null and b/screenshots/iPhoneX_recipes_dark.png differ diff --git a/src/app/[section]/[item_id]/page.tsx b/src/app/[section]/[item_id]/page.tsx index c17fafc..d963244 100644 --- a/src/app/[section]/[item_id]/page.tsx +++ b/src/app/[section]/[item_id]/page.tsx @@ -10,7 +10,7 @@ export async function generateMetadata({ }: { params: { section: string; item_id: number }; }): Promise { - if (!SectionService.isSection(section)) redirect("/"); // + if (!SectionService.isSection(section)) redirect("/"); return { title: `JellyBelly: ${SectionService.sectionsConfiguration[section].sectionName}`, }; diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000..7dc364a Binary files /dev/null and b/src/app/favicon.ico differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 0dc27b1..c3efc1a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,4 +1,3 @@ -import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; import { ThemeProvider } from "next-themes"; @@ -6,11 +5,6 @@ import { Header } from "@/widgets/header"; const inter = Inter({ subsets: ["latin"] }); -export const metadata: Metadata = { - title: "Jelly Belly Wiki", - description: "Information about everything Jelly belly", -}; - export default function RootLayout({ children, }: Readonly<{ diff --git a/src/app/page.tsx b/src/app/page.tsx index 117cc72..f630e68 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,10 +4,10 @@ import { SectionService, SectionType } from "@/features/sections"; import { Metadata } from "next"; import Link from "next/link"; +export const revalidate = 0; export const metadata: Metadata = { - title: ".Torrent", - description: - ".Torrent - сервис обмена .torrent файлами видеоигр, фильмов и аудиокниг", + title: "JellyBelly Wiki", + description: "Information about JellyBelly beans", }; export default async function Home() { diff --git a/src/features/itemCard/beanCard.tsx b/src/features/itemCard/beanCard.tsx index 4e4ab1d..7e3201c 100644 --- a/src/features/itemCard/beanCard.tsx +++ b/src/features/itemCard/beanCard.tsx @@ -39,3 +39,4 @@ export const BeanCard = React.forwardRef( ); } ); +BeanCard.displayName = "BeanCard"; diff --git a/src/features/itemCard/combinationCard.tsx b/src/features/itemCard/combinationCard.tsx index 67205e6..dce58a9 100644 --- a/src/features/itemCard/combinationCard.tsx +++ b/src/features/itemCard/combinationCard.tsx @@ -1,7 +1,4 @@ -import { CombinationType, TypesOfItems } from "@/entities/item"; -import Link from "next/link"; -import { SectionService } from "@/features/sections"; -import Image from "next/image"; +import { CombinationType } from "@/entities/item"; import React from "react"; export const CombinationCard = React.forwardRef< @@ -23,3 +20,4 @@ export const CombinationCard = React.forwardRef< ); }); +CombinationCard.displayName = "CombinationCard"; diff --git a/src/features/itemCard/factCard.tsx b/src/features/itemCard/factCard.tsx index 115fcc3..22c4036 100644 --- a/src/features/itemCard/factCard.tsx +++ b/src/features/itemCard/factCard.tsx @@ -1,7 +1,4 @@ -import { FactType, TypesOfItems } from "@/entities/item"; -import Link from "next/link"; -import { SectionService } from "@/features/sections"; -import Image from "next/image"; +import { FactType } from "@/entities/item"; import React from "react"; export const FactCard = React.forwardRef( @@ -25,3 +22,4 @@ export const FactCard = React.forwardRef( ); } ); +FactCard.displayName = "FactCard"; diff --git a/src/features/itemCard/itemCard.tsx b/src/features/itemCard/itemCard.tsx index 5062c67..52e66a3 100644 --- a/src/features/itemCard/itemCard.tsx +++ b/src/features/itemCard/itemCard.tsx @@ -37,3 +37,4 @@ export const ItemCard = React.forwardRef( return ItemTypeToCard(item, ref); } ); +ItemCard.displayName = "ItemCard"; diff --git a/src/features/itemCard/mileStoneCard.tsx b/src/features/itemCard/mileStoneCard.tsx index ab3ad79..bd2302a 100644 --- a/src/features/itemCard/mileStoneCard.tsx +++ b/src/features/itemCard/mileStoneCard.tsx @@ -1,7 +1,3 @@ -import { TypesOfItems } from "@/entities/item"; -import Link from "next/link"; -import { SectionService } from "@/features/sections"; -import Image from "next/image"; import React from "react"; import { MileStoneType } from "@/entities/item/mileStones"; @@ -24,3 +20,4 @@ export const MileStoneCard = React.forwardRef< ); }); +MileStoneCard.displayName = "MileStoneCard"; diff --git a/src/features/itemCard/recipeCard.tsx b/src/features/itemCard/recipeCard.tsx index 3505bce..30f3e45 100644 --- a/src/features/itemCard/recipeCard.tsx +++ b/src/features/itemCard/recipeCard.tsx @@ -1,4 +1,4 @@ -import { BeanType, RecipeType, TypesOfItems } from "@/entities/item"; +import { RecipeType, TypesOfItems } from "@/entities/item"; import Link from "next/link"; import { SectionService } from "@/features/sections"; import Image from "next/image"; @@ -40,3 +40,4 @@ export const RecipeCard = React.forwardRef< ); }); +RecipeCard.displayName = "RecipeCard"; diff --git a/src/features/itemInfo/beanInfo.tsx b/src/features/itemInfo/beanInfo.tsx index f64379a..1c9e5a9 100644 --- a/src/features/itemInfo/beanInfo.tsx +++ b/src/features/itemInfo/beanInfo.tsx @@ -28,7 +28,9 @@ export const BeanInfo = ({ item: bean }: { item: BeanType }) => {
    {bean.ingredients.length > 0 && bean.ingredients.map((ingredient) => ( -
  • - {ingredient}
  • +
  • + - {ingredient} +
  • ))}
{bean.ingredients.length == 0 && ( @@ -40,7 +42,9 @@ export const BeanInfo = ({ item: bean }: { item: BeanType }) => { In theese groups:
    {bean.groupName.map((group) => ( -
  • - {group}
  • +
  • + - {group} +
  • ))}
@@ -52,7 +56,7 @@ export const BeanInfo = ({ item: bean }: { item: BeanType }) => { BeanPropertyDescription ) as (keyof typeof BeanPropertyDescription)[] ).map((property) => ( -
  • +
  • - {BeanPropertyDescription[property]}:{" "} {bean[property] ? ( diff --git a/src/features/itemInfo/recipeInfo.tsx b/src/features/itemInfo/recipeInfo.tsx index d5b60e4..eaf1b8a 100644 --- a/src/features/itemInfo/recipeInfo.tsx +++ b/src/features/itemInfo/recipeInfo.tsx @@ -38,39 +38,35 @@ export const RecipeInfo = ({ item: recipe }: { item: RecipeType }) => { RecipeСookingDescription ) as (keyof typeof RecipeСookingDescription)[] ).map((property) => ( - <> - - {(recipe[property] as string[]).length > 0 && - RecipeСookingDescription[property] + ":"} - +
    + {(recipe[property] as string[]).length > 0 && + RecipeСookingDescription[property] + ":"}
      {(recipe[property] as string[]).length > 0 && (recipe[property] as string[]).map((ingredient) => ( -
    • - {ingredient}
    • +
    • + - {ingredient} +
    • ))}
    - +
    ))}
    - How long does it take: + How long does it take:
      {( Object.keys( RecipePropertyDescription ) as (keyof typeof RecipePropertyDescription)[] ).map((property) => ( - <> - { -
    • - {`- ${RecipePropertyDescription[property]}: ${recipe[property]}`} - {recipe[property] == "" && ( - Classified - )} -
    • - } - +
    • + {`- ${RecipePropertyDescription[property]}: ${recipe[property]}`} + {recipe[property] == "" && ( + Classified + )} +
    • ))}
    @@ -80,18 +76,18 @@ export const RecipeInfo = ({ item: recipe }: { item: RecipeType }) => { RecipeIngredientsDescription ) as (keyof typeof RecipeIngredientsDescription)[] ).map((property) => ( - <> - - {(recipe[property] as string[]).length > 0 && - RecipeIngredientsDescription[property] + ":"} - + + {(recipe[property] as string[]).length > 0 && + RecipeIngredientsDescription[property] + ":"}
      {(recipe[property] as string[]).length > 0 && (recipe[property] as string[]).map((ingredient) => ( -
    • - {ingredient}
    • +
    • + - {ingredient} +
    • ))}
    - +
    ))}
    diff --git a/src/shared/assets/icons/check.tsx b/src/shared/assets/icons/check.tsx index d787ac3..4694870 100644 --- a/src/shared/assets/icons/check.tsx +++ b/src/shared/assets/icons/check.tsx @@ -9,8 +9,8 @@ export const CheckIcon = ({ className }: { className?: string }) => { { fill="none" className={className} > - + diff --git a/src/widgets/grid/grid.tsx b/src/widgets/grid/grid.tsx index 9d819cc..3590107 100644 --- a/src/widgets/grid/grid.tsx +++ b/src/widgets/grid/grid.tsx @@ -9,7 +9,6 @@ import { import { ItemCard } from "@/features/itemCard"; import React, { useRef } from "react"; import { useState } from "react"; -import Masonry, { ResponsiveMasonry } from "react-responsive-masonry"; export const Grid = ({ firstPage, @@ -30,7 +29,12 @@ export const Grid = ({ ) => { const { scrollTop, scrollHeight, clientHeight } = e.target as HTMLDivElement; - if ((scrollTop + clientHeight) / scrollHeight > 0.5) { + if ( + firstItemRef && + firstItemRef.current && + scrollHeight - (scrollTop + clientHeight) < + firstItemRef.current?.clientHeight * 3 + ) { if (!loadingPage) { changeLoadingPage(true); setTimeout(() => changeLoadingPage(false), 1000); diff --git a/src/widgets/header/header.tsx b/src/widgets/header/header.tsx index ec532cb..a5e2d03 100644 --- a/src/widgets/header/header.tsx +++ b/src/widgets/header/header.tsx @@ -3,7 +3,6 @@ import { MobileMenu } from "./mobileMenu/mobileMenu"; import Link from "next/link"; import { useSelectedLayoutSegment } from "next/navigation"; -import clsx from "clsx"; import { SectionService } from "@/features/sections"; import { ColorSchemeSwitch } from "@/features/colorSchemeSwitch"; @@ -26,10 +25,10 @@ export const Header = () => { {SectionService.sections.map((section) => ( {SectionService.sectionsConfiguration[section].sectionName} @@ -37,22 +36,6 @@ export const Header = () => { ))} - - {/* */} ); diff --git a/src/widgets/header/mobileMenu/mobileMenu.tsx b/src/widgets/header/mobileMenu/mobileMenu.tsx index b480368..8a97f4b 100644 --- a/src/widgets/header/mobileMenu/mobileMenu.tsx +++ b/src/widgets/header/mobileMenu/mobileMenu.tsx @@ -1,7 +1,6 @@ "use client"; import { SectionService } from "@/features/sections"; -import clsx from "clsx"; import Link from "next/link"; import { useState } from "react"; @@ -19,20 +18,15 @@ export const MobileMenu = () => { }} onBlur={() => changeMenuOpen(false)} > -
    -
    -
    +
    +
    +
    changeMenuOpen(false)} > {SectionService.sections.map((section) => (