diff --git a/frontend-next-migration/src/shared/i18n/locales/en/navbar.json b/frontend-next-migration/src/shared/i18n/locales/en/navbar.json index 0893727d4..18f66c6d3 100644 --- a/frontend-next-migration/src/shared/i18n/locales/en/navbar.json +++ b/frontend-next-migration/src/shared/i18n/locales/en/navbar.json @@ -35,5 +35,20 @@ "about": "About", "education": "Education", "prg": "PRG", - "contactUs": "Contact us" + "contactUs": "Contact us", + "learnTheGame": "Get to know the game", + "story": "Story", + "defenseHeroes": "Defense heroes", + "balanceVoting": "Balance voting", + "scoreboard": "Scoreboard", + "sarjakuvat": "Comics", + "characterDevelopment": "Character development arc", + "soulCastleFurniture": "Soul castle furniture", + "gameIcons": "Other game icons", + "gameMusic": "Game music", + "opetuspaketti": "Teaching package", + "pelitaide": "Game art", + "whatIsPrg": "What is PRG", + "altZoneHistory": "ALT Zone's history", + "developersAndDesigners": "Developers and designers" } diff --git a/frontend-next-migration/src/shared/i18n/locales/fi/navbar.json b/frontend-next-migration/src/shared/i18n/locales/fi/navbar.json index 8f22ccba6..1b8f97cc8 100644 --- a/frontend-next-migration/src/shared/i18n/locales/fi/navbar.json +++ b/frontend-next-migration/src/shared/i18n/locales/fi/navbar.json @@ -33,5 +33,20 @@ "about": "Meistä", "education": "Opetus", "prg": "PRG", - "contactUs": "Ota yhteyttä" + "contactUs": "Ota yhteyttä", + "learnTheGame": "Tutustu peliin", + "story": "Tarina", + "defenseHeroes": "Defenssisoturit", + "balanceVoting": "Balanssiäänestys", + "scoreboard": "Tulostaulukko", + "sarjakuvat": "Sarjakuvat", + "characterDevelopment": "Pelihahmojen kehityskaari", + "soulCastleFurniture": "Sielunlinnan huonekalut", + "gameIcons": "Muut pelin ikonit", + "gameMusic": "Pelimusiikki", + "opetuspaketti": "Opetuspaketti", + "pelitaide": "Pelitaide", + "whatIsPrg": "Mikä on PRG", + "altZoneHistory": "ALT Zonen historia", + "developersAndDesigners": "Kehittäjät ja suunnittelijat" } diff --git a/frontend-next-migration/src/widgets/Navbar/model/data/dropdowns.ts b/frontend-next-migration/src/widgets/Navbar/model/data/dropdowns.ts index 13584ff0f..cdea346f3 100644 --- a/frontend-next-migration/src/widgets/Navbar/model/data/dropdowns.ts +++ b/frontend-next-migration/src/widgets/Navbar/model/data/dropdowns.ts @@ -1,139 +1,134 @@ -import { AppExternalLinks } from '@/shared/appLinks/appExternalLinks'; import { - getRouteHeroDevPage, - getRouteMyClanPage, getRouteComicsPage, - getRouteGalleryPage, getRouteGameArtPage, getRouteDefenseGalleryPage, - getRouteAllClanSearchPage, - //getRouteAllFurnitureSetsPage, - getRouteAllCollectionsPage, - getRouteJoinUsPage, + getRouteAllFurnitureSetsPage, + getRouteAllMusicCollectionsPage, getRouteAboutPage, getRouteTeamPage, getRoutePrgPage, + getRouteGamePage, + getRouteComingSoonPage, } from '@/shared/appLinks/RoutePaths'; export const dropdowns = { community: [ { - elementText: 'clanpage', + elementText: 'whatIsPrg', link: { - path: getRouteMyClanPage(), + path: getRoutePrgPage(), isExternal: false, }, }, { - elementText: 'join', + elementText: 'altZoneHistory', link: { - path: getRouteJoinUsPage(), + path: getRouteAboutPage(), isExternal: false, }, }, { - elementText: 'forum', + elementText: 'developersAndDesigners', link: { - path: AppExternalLinks.reddit, - isExternal: true, + path: getRouteTeamPage(), + isExternal: false, }, }, + ], + game: [ { - elementText: 'about', + elementText: 'learnTheGame', link: { - path: getRouteAboutPage(), + path: getRouteGamePage(), isExternal: false, }, }, - ], - game: [ { - elementText: 'play', + elementText: 'story', link: { - path: AppExternalLinks.webgl, - isExternal: true, + path: getRouteComingSoonPage(), + isExternal: false, }, }, { - elementText: 'heroes', + elementText: 'defenseHeroes', link: { path: getRouteDefenseGalleryPage(), isExternal: false, }, }, { - elementText: 'development', + elementText: 'balanceVoting', link: { - path: getRouteHeroDevPage(), + path: getRouteComingSoonPage(), isExternal: false, }, }, { elementText: 'clans', link: { - path: getRouteAllClanSearchPage(), + path: getRouteComingSoonPage(), isExternal: false, }, - isDisabled: { - status: false, - reason: 'Kirjaudu ensin!', + }, + { + elementText: 'scoreboard', + link: { + path: getRouteComingSoonPage(), + isExternal: false, }, }, - // { - // elementText: 'leaderboard', - // link: { - // path: getRouteClanLeadeboardPage(), - // isExternal: false, - // }, - // }, ], gallery: [ { - elementText: 'pictures', + elementText: 'sarjakuvat', link: { - path: getRouteGalleryPage(), + path: getRouteComicsPage(), isExternal: false, }, }, { - elementText: 'comics', + elementText: 'characterDevelopment', link: { - path: getRouteComicsPage(), + path: getRouteComingSoonPage(), isExternal: false, }, }, { - elementText: 'collections', + elementText: 'soulCastleFurniture', link: { - path: getRouteAllCollectionsPage(), + path: getRouteAllFurnitureSetsPage(), isExternal: false, }, - isDisabled: { - status: false, - reason: 'Kirjaudu ensin!', + }, + { + elementText: 'gameIcons', + link: { + path: getRouteComingSoonPage(), + isExternal: false, }, }, - ], - gameart: [ { - elementText: 'gameart', + elementText: 'gameMusic', link: { - path: getRouteGameArtPage(), + path: getRouteAllMusicCollectionsPage(), isExternal: false, }, }, + ], + gameart: [ { - elementText: 'dlPackage', + elementText: 'opetuspaketti', link: { - path: AppExternalLinks.dlpackage, - isExternal: true, + path: getRouteGameArtPage(), + isExternal: false, }, }, { - elementText: 'pastversions', + elementText: 'pelitaide', link: { - path: AppExternalLinks.pastversions, - isExternal: true, + path: getRouteComingSoonPage(), + isExternal: false, }, }, ], diff --git a/frontend-next-migration/src/widgets/NavbarV3/model/data/navbarMenuDesktop.ts b/frontend-next-migration/src/widgets/NavbarV3/model/data/navbarMenuDesktop.ts index 8c4160f32..3d83fdd0a 100644 --- a/frontend-next-migration/src/widgets/NavbarV3/model/data/navbarMenuDesktop.ts +++ b/frontend-next-migration/src/widgets/NavbarV3/model/data/navbarMenuDesktop.ts @@ -4,7 +4,6 @@ import { getRouteTeamPage, getRouteMainPage, getRouteAllNewsPage, - getRouteGameArtPage, } from '@/shared/appLinks/RoutePaths'; import { NavbarBuilder } from './NavbarBuilder'; @@ -13,7 +12,7 @@ navbarBuilder.addLogo('Nav logo', img as unknown as string, getRouteMainPage()); navbarBuilder.addLink('news', getRouteAllNewsPage()); navbarBuilder.addDropDown('game', dropdowns.game); navbarBuilder.addDropDown('gallery', dropdowns.gallery); -navbarBuilder.addDropDown('education', dropdowns.gameart, getRouteGameArtPage()); +navbarBuilder.addDropDown('education', dropdowns.gameart); navbarBuilder.addDropDown('community', dropdowns.community); navbarBuilder.addLink('contactUs', getRouteTeamPage()); diff --git a/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.module.scss b/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.module.scss index 3dbdaec39..b3d40ccb8 100644 --- a/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.module.scss +++ b/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.module.scss @@ -9,14 +9,6 @@ z-index: var(--navbar-z-index); user-select: none; overflow-y: visible; - - &.collapsed { - overflow: hidden; - } - - &.noBorder { - border-bottom: none; - } } .inner { @@ -30,12 +22,6 @@ height: 110px; transition: width 0.3s ease, height 0.3s ease; position: relative; - - &.collapsed { - width: 50px; - overflow: hidden; - } - } .logoSlot { @@ -45,12 +31,6 @@ height: 92px; transition: opacity 0.3s ease, transform 0.3s ease; - &.collapsed { - opacity: 0; - transform: scaleX(0); - pointer-events: none; - } - a { display: block; position: absolute; @@ -118,6 +98,11 @@ margin-left: 6px; font-size: 18px; color: var(--white); + transition: transform 0.2s ease; + + &.chevronOpen { + transform: rotate(180deg); + } } .actions { @@ -130,12 +115,6 @@ flex: none; margin-left: auto; transition: opacity 0.3s ease, transform 0.3s ease; - - &.collapsed { - opacity: 0; - transform: translateX(20px); - pointer-events: none; - } } .iconBtn { @@ -262,44 +241,45 @@ } } -.navDropdownCenter { - position: fixed !important; - left: 0 !important; - right: 0 !important; - top: 110px !important; - transform: none !important; - width: 100% !important; - max-width: none !important; - - display: flex; - justify-content: center; - gap: 1.5rem; - padding: var(--spacing-300) !important; - +.dropdownMenu { + position: absolute; + /* the li is 60px tall and vertically centered in the 110px navbar, + so the extra 25px pushes the panel flush against the navbar's bottom edge */ + top: calc(100% + 25px); + left: 0; + z-index: var(--navbar-z-index); + min-width: 180px; + padding: var(--spacing-200); background: var(--base-card-background); - border-bottom: 2px solid var(--black); + border: 2px solid var(--black); + border-radius: var(--border-radius-lg); box-shadow: var(--m); - + display: flex; + flex-direction: column; + gap: 0; opacity: 0; visibility: hidden; - transition: opacity 0.25s ease, visibility 0.25s ease; + transform: translateY(-4px); + transition: + opacity 0.2s ease, + visibility 0.2s ease, + transform 0.2s ease; + pointer-events: none; - &.open { + &.dropdownMenuOpen { opacity: 1; visibility: visible; + transform: translateY(0); + pointer-events: auto; } } -.dropdownGroup { - display: flex; - flex-direction: column; - gap: 0; -} - -.navDropdownCenter .dropdownItem { - padding: var(--spacing-100) var(--spacing-300); +.dropdownItem { + padding: 0 var(--spacing-300); min-width: auto; - display: block; + display: flex; + align-items: center; + height: 65px; white-space: nowrap; font: var(--font-dm-bold-l); color: var(--white); diff --git a/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.test.tsx b/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.test.tsx new file mode 100644 index 000000000..5c1c57d7a --- /dev/null +++ b/frontend-next-migration/src/widgets/NavbarV3/ui/NavbarDesktopV3/NavbarDesktop.test.tsx @@ -0,0 +1,156 @@ +import { render, screen, fireEvent, act } from '@testing-library/react'; +import NavbarDesktop from './NavbarDesktop'; +import { NavbarBuild, ItemType } from '../../model/types'; + +jest.mock('@/shared/i18n', () => ({ + useClientTranslation: jest.fn().mockReturnValue({ + t: jest.fn((key: string) => key), + }), +})); + +jest.mock('@/entities/Auth', () => ({ + useLogoutMutation: () => [jest.fn()], + useUserPermissionsV2: () => ({ + checkPermissionFor: () => ({ isGranted: false }), + }), +})); + +jest.mock('@/features/AuthByUsername', () => ({ + LoginForm: () =>
, +})); + +jest.mock('@/features/LangSwitcher', () => ({ + LangSwitcher: () => , +})); + +jest.mock('@/shared/ui/AppLink/AppLink', () => ({ + AppLink: ({ children, to, isExternal, ...props }: any) => ( + + {children} + + ), + AppLinkTheme: { PRIMARY: 'primary' }, +})); + +jest.mock('@fortawesome/react-fontawesome', () => ({ + FontAwesomeIcon: () => , +})); + +jest.mock('@/shared/lib/hooks/useDropdownManager', () => ({ + useDropdownManager: () => ({ + state: { isOpen: false, isToggled: false }, + actions: { toggle: jest.fn(), reset: jest.fn() }, + }), +})); + +const makeNavbarBuild = (): NavbarBuild => ({ + namedMenu: {}, + menu: [ + { + name: 'Nav logo', + src: 'logo.png', + path: '/', + type: ItemType.navLogo, + }, + { + name: 'news', + path: '/news', + type: ItemType.navLink, + }, + { + name: 'contactUs', + path: '/team', + type: ItemType.navLink, + }, + { + name: 'game', + type: ItemType.navDropDown, + elements: [ + { + elementText: 'learnTheGame', + link: { path: '/peli', isExternal: false }, + }, + { + elementText: 'scoreboard', + link: { path: '/leaderboard', isExternal: false }, + }, + ], + }, + ], +}); + +describe('NavbarDesktopV3', () => { + const navbarBuild = makeNavbarBuild(); + + test('renders nav element', () => { + render(