From 6b84a312f7a703a061361d3be5be23dafaf5b703 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 04:35:32 +0500 Subject: [PATCH] anix/refactor: navbar --- app/App.tsx | 12 +- app/components/Navbar/NavBarMobile.tsx | 168 ++++++++++++++ app/components/Navbar/NavBarPc.tsx | 139 +++++++++++ app/components/Navbar/NavbarUpdate.tsx | 215 ------------------ .../RelatedSection/RelatedSection.tsx | 2 +- .../ReleaseSection/ReleaseSection.tsx | 4 +- .../SettingsModal/SettingsModal.tsx | 18 +- app/menu/page.tsx | 11 - app/pages/MobileMenuPage.tsx | 130 ----------- app/pages/Search.tsx | 2 +- app/store/preferences.ts | 5 +- 11 files changed, 332 insertions(+), 374 deletions(-) create mode 100644 app/components/Navbar/NavBarMobile.tsx create mode 100644 app/components/Navbar/NavBarPc.tsx delete mode 100644 app/components/Navbar/NavbarUpdate.tsx delete mode 100644 app/menu/page.tsx delete mode 100644 app/pages/MobileMenuPage.tsx diff --git a/app/App.tsx b/app/App.tsx index 8cccbd0..34052c1 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -1,7 +1,6 @@ "use client"; import { useUserStore } from "./store/auth"; import { usePreferencesStore } from "./store/preferences"; -import { Navbar } from "./components/Navbar/NavbarUpdate"; import { Inter } from "next/font/google"; import { useEffect, useState } from "react"; import { @@ -14,6 +13,9 @@ import { import { Spinner } from "./components/Spinner/Spinner"; import { ChangelogModal } from "#/components/ChangelogModal/ChangelogModal"; import { Bounce, ToastContainer } from "react-toastify"; +import { NavBarPc } from "./components/Navbar/NavBarPc"; +import { NavBarMobile } from "./components/Navbar/NavBarMobile"; +import { SettingsModal } from "./components/SettingsModal/SettingsModal"; const inter = Inter({ subsets: ["latin"] }); @@ -23,6 +25,7 @@ export const App = (props) => { const [showChangelog, setShowChangelog] = useState(false); const [currentVersion, setCurrentVersion] = useState(""); const [previousVersions, setPreviousVersions] = useState([]); + const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); useEffect(() => { async function _checkVersion() { @@ -68,7 +71,7 @@ export const App = (props) => { - +
{props.children}
@@ -123,6 +126,11 @@ export const App = (props) => { theme="colored" transition={Bounce} /> + + ); }; diff --git a/app/components/Navbar/NavBarMobile.tsx b/app/components/Navbar/NavBarMobile.tsx new file mode 100644 index 0000000..3431566 --- /dev/null +++ b/app/components/Navbar/NavBarMobile.tsx @@ -0,0 +1,168 @@ +"use client"; +import { + Avatar, + Dropdown, + DropdownDivider, + DropdownItem, +} from "flowbite-react"; +import { useUserStore } from "#/store/auth"; +import Link from "next/link"; +import { usePathname, useRouter } from "next/navigation"; +import { usePreferencesStore } from "#/store/preferences"; + +const NavbarItems = [ + { + title: "Домашняя", + icon: "mdi--home", + href: "/", + auth: false, + }, + { + title: "Поиск", + icon: "mdi--search", + href: "/search", + auth: false, + }, + { + title: "Закладки", + icon: "mdi--bookmark-multiple", + href: "/bookmarks", + auth: true, + }, +]; + +const FifthButton = { + favorites: { + title: "Избранное", + icon: "mdi--favorite", + href: "/favorites", + auth: true, + }, + collections: { + title: "Коллекции", + icon: "mdi--collections-bookmark", + href: "/collections", + auth: true, + }, + history: { + title: "История", + icon: "mdi--history", + href: "/history", + auth: true, + }, + discovery: { + title: "Обзор", + icon: "mdi--compass", + href: "/discovery", + auth: true, + }, +}; + +export const NavBarMobile = (props: { setIsSettingModalOpen: any }) => { + const userStore = useUserStore(); + const router = useRouter(); + const pathname = usePathname(); + const preferenceStore = usePreferencesStore(); + + return ( + <> +
+
+ {NavbarItems.map((item) => { + if (item.auth && !userStore.isAuth) return <>; + return ( + + + {item.title} + + ); + })} + {userStore.isAuth && preferenceStore.flags.showFifthButton ? + + + + {FifthButton[preferenceStore.flags.showFifthButton].title} + + + : ""} + + +

+ {userStore.isAuth ? userStore.user.login : "Аноним"} +

+
+ } + > + {userStore.isAuth && ( + <> + router.push(`/profile/${userStore.user.id}`)} + > + + Профиль + + {Object.entries(FifthButton).map(([key, item]) => { + if (item.auth && !userStore.isAuth) return <>; + if (preferenceStore.flags.showFifthButton === key) + return <>; + return ( + router.push(item.href)} + > + + {item.title} + + ); + })} + + + )} + props.setIsSettingModalOpen(true)} + className="relative flex" + > + + Настройки + + {userStore.isAuth ? + userStore.logout()}> + + Выйти + + : router.push(`/login?redirect=${pathname}`)} + > + + Войти + + } + + +
+ + ); +}; diff --git a/app/components/Navbar/NavBarPc.tsx b/app/components/Navbar/NavBarPc.tsx new file mode 100644 index 0000000..b8886f4 --- /dev/null +++ b/app/components/Navbar/NavBarPc.tsx @@ -0,0 +1,139 @@ +"use client"; +import { + Avatar, + Dropdown, + DropdownDivider, + DropdownItem, +} from "flowbite-react"; +import { useUserStore } from "#/store/auth"; +import Link from "next/link"; +import { usePathname, useRouter } from "next/navigation"; + +const NavbarItems = [ + { + title: "Домашняя", + icon: "mdi--home", + href: "/", + auth: false, + }, + { + title: "Поиск", + icon: "mdi--search", + href: "/search", + auth: false, + }, + { + title: "Закладки", + icon: "mdi--bookmark-multiple", + href: "/bookmarks", + auth: true, + }, + { + title: "Избранное", + icon: "mdi--favorite", + href: "/favorites", + auth: true, + }, + { + title: "Коллекции", + icon: "mdi--collections-bookmark", + href: "/collections", + auth: true, + }, + { + title: "История", + icon: "mdi--history", + href: "/history", + auth: true, + }, + { + title: "Обзор", + icon: "mdi--compass", + href: "/discovery", + auth: true, + }, +]; + +export const NavBarPc = (props: { setIsSettingModalOpen: any }) => { + const userStore = useUserStore(); + const router = useRouter(); + const pathname = usePathname(); + + return ( + <> +
+
+
+ {NavbarItems.map((item) => { + if (item.auth && !userStore.isAuth) return <>; + return ( + + + {item.title} + + ); + })} +
+ + +

+ {userStore.isAuth ? userStore.user.login : "Аноним"} +

+
+ } + > + {userStore.isAuth ? + router.push(`/profile/${userStore.user.id}`)} + className="relative flex" + > + + Профиль + + : ""} + props.setIsSettingModalOpen(true)} + className="relative flex" + > + + Настройки + + {userStore.isAuth ? + userStore.logout()} + className="relative flex" + > + + Выйти + + : router.push(`/login?redirect=${pathname}`)} + className="relative flex" + > + + Войти + + } + + +
+ + ); +}; diff --git a/app/components/Navbar/NavbarUpdate.tsx b/app/components/Navbar/NavbarUpdate.tsx deleted file mode 100644 index a6219c0..0000000 --- a/app/components/Navbar/NavbarUpdate.tsx +++ /dev/null @@ -1,215 +0,0 @@ -"use client"; - -import Link from "next/link"; -import Image from "next/image"; -import { useUserStore } from "#/store/auth"; -import { usePathname } from "next/navigation"; -import { useState } from "react"; -import { SettingsModal } from "#/components/SettingsModal/SettingsModal"; -import { usePreferencesStore } from "#/store/preferences"; - -export const Navbar = () => { - const pathname = usePathname(); - const userStore = useUserStore(); - const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); - const preferenceStore = usePreferencesStore(); - - const menuItems = [ - { - id: 1, - title: "Домашняя", - href: "/", - hrefInCategory: "/home", - icon: { - default: "material-symbols--home-outline", - active: "material-symbols--home", - }, - isAuthRequired: false, - isShownOnMobile: true, - }, - { - id: 2, - title: "Поиск", - href: "/search", - icon: { - default: "material-symbols--search", - active: "material-symbols--search", - }, - isAuthRequired: false, - isShownOnMobile: true, - }, - { - id: 3, - title: "Закладки", - href: "/bookmarks", - icon: { - default: "material-symbols--bookmarks-outline", - active: "material-symbols--bookmarks", - }, - isAuthRequired: true, - isShownOnMobile: true, - }, - { - id: 4, - title: "Избранное", - href: "/favorites", - icon: { - default: "material-symbols--favorite-outline", - active: "material-symbols--favorite", - }, - isAuthRequired: true, - isShownOnMobile: false, - }, - { - id: 5, - title: "Коллекции", - href: "/collections", - icon: { - default: "material-symbols--collections-bookmark-outline", - active: "material-symbols--collections-bookmark", - }, - isAuthRequired: true, - isShownOnMobile: false, - }, - { - id: 6, - title: "История", - href: "/history", - icon: { - default: "material-symbols--history", - active: "material-symbols--history", - }, - isAuthRequired: true, - isShownOnMobile: false, - }, - ]; - - return ( - <> -
-
-
- {menuItems.map((item) => { - return ( - - - - {item.title} - - - ); - })} -
-
- {!userStore.isAuth ? - - - - Войти - - - : <> - - - - {userStore.user.login} - - - {preferenceStore.flags.showFifthButton ? - - - - {menuItems[preferenceStore.flags.showFifthButton].title} - - - : ""} - - - - {userStore.user.login} - - - - } - - {userStore.isAuth && ( - - )} -
-
-
- - - ); -}; diff --git a/app/components/RelatedSection/RelatedSection.tsx b/app/components/RelatedSection/RelatedSection.tsx index 368793d..fa640b8 100644 --- a/app/components/RelatedSection/RelatedSection.tsx +++ b/app/components/RelatedSection/RelatedSection.tsx @@ -15,7 +15,7 @@ export const RelatedSection = (props: any) => {
{props.images.map((item, index) => { return ( -
+
diff --git a/app/components/SettingsModal/SettingsModal.tsx b/app/components/SettingsModal/SettingsModal.tsx index 56d9291..8a703b6 100644 --- a/app/components/SettingsModal/SettingsModal.tsx +++ b/app/components/SettingsModal/SettingsModal.tsx @@ -43,9 +43,10 @@ const NavbarTitles = { }; const FifthButton = { - 3: "Избранное", - 4: "Коллекции", - 5: "История", + favorites: "Избранное", + collections: "Коллекции", + history: "История", + discovery: "Обзор", }; export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { @@ -56,7 +57,8 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { const [isPlayerConfigured, setIsPlayerConfigured] = useState(false); useEffect(() => { - const NEXT_PUBLIC_PLAYER_PARSER_URL = env("NEXT_PUBLIC_PLAYER_PARSER_URL") || null; + const NEXT_PUBLIC_PLAYER_PARSER_URL = + env("NEXT_PUBLIC_PLAYER_PARSER_URL") || null; if (NEXT_PUBLIC_PLAYER_PARSER_URL) { setIsPlayerConfigured(true); } @@ -204,7 +206,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
{userStore.isAuth ? -
+

Пятый пункт в навигации

@@ -229,11 +231,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { return ( - preferenceStore.setFlags({ - showFifthButton: Number(key) as 3 | 4 | 5, - }) - } + onClick={() => preferenceStore.setFlags({showFifthButton: key})} > {FifthButton[key]} diff --git a/app/menu/page.tsx b/app/menu/page.tsx deleted file mode 100644 index 61305cc..0000000 --- a/app/menu/page.tsx +++ /dev/null @@ -1,11 +0,0 @@ -export const metadata = { - title: "Меню", -}; - -import { MenuPage } from "#/pages/MobileMenuPage"; - -export const dynamic = "force-static"; - -export default function Index() { - return ; -} diff --git a/app/pages/MobileMenuPage.tsx b/app/pages/MobileMenuPage.tsx deleted file mode 100644 index f1f73b8..0000000 --- a/app/pages/MobileMenuPage.tsx +++ /dev/null @@ -1,130 +0,0 @@ -"use client"; -import { Card } from "flowbite-react"; -import { useUserStore } from "#/store/auth"; -import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { SettingsModal } from "#/components/SettingsModal/SettingsModal"; -import { useEffect, useState } from "react"; -import Image from "next/image"; -import { usePreferencesStore } from "#/store/preferences"; - -export const MenuPage = () => { - const userStore = useUserStore(); - const preferenceStore = usePreferencesStore(); - const router = useRouter(); - const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); - - useEffect(() => { - if (!userStore.user) { - router.push("/"); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [userStore.user]); - - return ( - <> - {userStore.user && ( -
-
- - -
- -
-

- {userStore.user.login} -

-

- {userStore.user.status} -

-
-
-
- -
- - -
-
- {preferenceStore.flags.showFifthButton != 3 ? - - -
- -

Избранное

-
-
- - : ""} - {preferenceStore.flags.showFifthButton != 4 ? - - -
- -

Коллекции

-
-
- - : ""} - {preferenceStore.flags.showFifthButton != 5 ? - - -
- -

История

-
-
- - : ""} - -
- )} - - ); -}; diff --git a/app/pages/Search.tsx b/app/pages/Search.tsx index c5ee065..6647906 100644 --- a/app/pages/Search.tsx +++ b/app/pages/Search.tsx @@ -279,7 +279,7 @@ export function SearchPage() { return (
diff --git a/app/store/preferences.ts b/app/store/preferences.ts index 1225c2d..bfce3af 100644 --- a/app/store/preferences.ts +++ b/app/store/preferences.ts @@ -10,7 +10,7 @@ interface preferencesState { saveWatchHistory?: boolean; showChangelog?: boolean; showNavbarTitles?: "always" | "links" | "selected" | "never"; - showFifthButton?: null | 3 | 4 | 5; + showFifthButton?: null | string; }; params: { isFirstLaunch?: boolean; @@ -80,6 +80,7 @@ export const usePreferencesStore = create()( persistedState as preferencesState ); }, - } + version: 2, + }, ) );