diff --git a/src/App.scss b/src/App.scss index 0cb361bd..4ce8e644 100644 --- a/src/App.scss +++ b/src/App.scss @@ -5,10 +5,4 @@ .main { flex-direction: row; font-family: Heebo; - - > .sidebar { - height: 100vh; - background-color: white; - padding: 10px; - } } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index b5bcc506..788d867f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,7 +9,7 @@ import { BrowserRouter as Router, useSearchParams } from 'react-router-dom' import { PageSearchState, SearchContext } from './model/pageState' import moment from 'moment' import { useSessionStorage } from 'usehooks-ts' -import SideBar from './pages/components/header/sidebar/SideBar' + import { useLocation } from 'react-router-dom' import ReactGA from 'react-ga4' import { CacheProvider } from '@emotion/react' @@ -22,7 +22,8 @@ import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment' import { LocalizationProvider } from '@mui/x-date-pickers' import RoutesList, { PAGES } from './routes' -import MainHeader from './pages/components/header/Header' +import MainHeader from './layout/header/Header' +import SideBar from './layout/sidebar/SideBar' import LayoutContext from './layout/LayoutContext' import { EasterEgg } from './pages/EasterEgg/EasterEgg' const { Content } = Layout diff --git a/src/pages/components/header/Header.tsx b/src/layout/header/Header.tsx similarity index 100% rename from src/pages/components/header/Header.tsx rename to src/layout/header/Header.tsx diff --git a/src/pages/components/header/sidebar/GitHubLink/GitHubLink.scss b/src/layout/sidebar/GitHubLink/GitHubLink.scss similarity index 100% rename from src/pages/components/header/sidebar/GitHubLink/GitHubLink.scss rename to src/layout/sidebar/GitHubLink/GitHubLink.scss diff --git a/src/pages/components/header/sidebar/GitHubLink/GitHubLink.tsx b/src/layout/sidebar/GitHubLink/GitHubLink.tsx similarity index 100% rename from src/pages/components/header/sidebar/GitHubLink/GitHubLink.tsx rename to src/layout/sidebar/GitHubLink/GitHubLink.tsx diff --git a/src/layout/sidebar/SideBar.tsx b/src/layout/sidebar/SideBar.tsx new file mode 100644 index 00000000..43378959 --- /dev/null +++ b/src/layout/sidebar/SideBar.tsx @@ -0,0 +1,44 @@ +import Menu from './menu/Menu' +import './sidebar.scss' +import { Drawer, Layout } from 'antd' +import { useContext, useState } from 'react' +import { LayoutContextInterface, LayoutCtx } from '../LayoutContext' + +const { Sider } = Layout + +const Logo = () => ( +
+

דאטאבוס

+
+) +const CollapsedLogo = () =>

🚌

+ +export default function SideBar() { + const { drawerOpen, setDrawerOpen } = useContext(LayoutCtx) + const [collapsed, setCollapsed] = useState(false) + return ( + <> + setDrawerOpen(false)} + open={drawerOpen} + className="hideOnDesktop" + bodyStyle={{ padding: '0' }}> + + + setCollapsed(value)} + className="hideOnMobile"> + {collapsed ? : } + + + + ) +} diff --git a/src/layout/sidebar/menu/Menu.tsx b/src/layout/sidebar/menu/Menu.tsx new file mode 100644 index 00000000..dfe95114 --- /dev/null +++ b/src/layout/sidebar/menu/Menu.tsx @@ -0,0 +1,67 @@ +import React, { useEffect, useState } from 'react' +import { Link, useLocation } from 'react-router-dom' +import './menu.scss' +import { useTranslation } from 'react-i18next' +import { PAGES as pages } from 'src/routes' + +import type { MenuProps } from 'antd' +import { Menu } from 'antd' + +type MenuItem = Required['items'][number] +function getItem( + label: React.ReactNode, + key: React.Key, + icon?: React.ReactNode, + children?: MenuItem[], +): MenuItem { + return { + key, + icon, + children, + label, + } as MenuItem +} + +const MainMenu = () => { + const { t, i18n } = useTranslation() + const items: MenuItem[] = pages.map((itm) => { + return getItem({t(itm.label)}, itm.path, itm.icon) + }) + const [currentLanguage, setCurrentLanguage] = useState('en') + + const handleChangeLanguage = () => { + const newLanguage = currentLanguage === 'en' ? 'he' : 'en' + setCurrentLanguage(newLanguage) + i18n.changeLanguage(newLanguage) + } + const location = useLocation() + const [current, setCurrent] = useState( + location.pathname === '/' || location.pathname === '' ? '/dashboard' : location.pathname, + ) + + useEffect(() => { + if (location) { + if (current !== location.pathname) { + setCurrent(location.pathname) + } + } + }, [location, current]) + + const handleClick: MenuProps['onClick'] = ({ key }) => { + setCurrent(key) + } + return ( + <> + + {null && } + + ) +} + +export default MainMenu diff --git a/src/pages/components/header/sidebar/menu/menu.scss b/src/layout/sidebar/menu/menu.scss similarity index 93% rename from src/pages/components/header/sidebar/menu/menu.scss rename to src/layout/sidebar/menu/menu.scss index f219e8db..7362e77d 100644 --- a/src/pages/components/header/sidebar/menu/menu.scss +++ b/src/layout/sidebar/menu/menu.scss @@ -1,4 +1,4 @@ -@import '../../../../../resources/variables'; +@import '../../../resources/variables'; .menu { flex-direction: column; diff --git a/src/layout/sidebar/sidebar.scss b/src/layout/sidebar/sidebar.scss new file mode 100644 index 00000000..574464dd --- /dev/null +++ b/src/layout/sidebar/sidebar.scss @@ -0,0 +1,61 @@ +@import '../../resources/variables'; + + +.hideOnMobile { + display: none; +} +@media only screen and (min-width: 768px) { + .hideOnMobile { + display: block; + } +} +.hideOnDesktop { + display: block; +} +@media only screen and (min-width: 768px) { + .hideOnDesktop { + display: none; + } +} + +.sidebar-logo { + position: relative; + margin: 20px auto; + width: 119px; + font-size: 30px; + border-top: 6px solid gray; + border-bottom: 8px solid gray; + padding-bottom: 0; + line-height: 25px; + &::before { + height: 10px; + width: 10px; + border-radius: 5px; + position: absolute; + background: gray; + top: 28px; + right: 24px; + content: ' ' +} +&::after { + height: 10px; + width: 10px; + border-radius: 5px; + position: absolute; + background: gray; + top: 28px; + left: 17px; + content: ' ' +} +} + +.sidebar-logo-collapsed { + position: relative; + margin: 20px auto; + text-align: center; + font-size: 22px; + border-top: 6px solid gray; + border-bottom: 8px solid gray; + padding-bottom: 0; + line-height: 25px; +} \ No newline at end of file diff --git a/src/locale/he.json b/src/locale/he.json index d788d706..2dfd2081 100644 --- a/src/locale/he.json +++ b/src/locale/he.json @@ -33,7 +33,7 @@ "ride_extra": "נסיעה שלא תוכננה 🧐", "ride_duped": "נסיעה כפולה ❇️", "checkbox_only_gaps": "רק פערים", - "dashboard_page_title": "מפעילי תח\"צ לפי קיום נסיעות מתוכננות", + "dashboard_page_title": "קיום נסיעות", "dashboard_tooltip_content": "על כל קו בישראל מוצמד GPS שמדווח את מיקום האוטובוס כל כמה רגעים.\nאז מה היא נסיעה שלא בוצעה? זאת נסיעה שתוכננה, אבל לא דווח שיצאה בנתוני הGPS. תוכלו לראות אותה באפליקציה למשל, אבל כשתחכו בתחנה, היא לעולם לא תגיע", "worst_lines_page_title": "הקווים הגרועים ביותר של 5 המפעילות הגדולות", "rides_planned": "נסיעות שתוכננו", diff --git a/src/pages/components/header/sidebar/menu/Menu.tsx b/src/pages/components/header/sidebar/menu/Menu.tsx deleted file mode 100644 index 378951e4..00000000 --- a/src/pages/components/header/sidebar/menu/Menu.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { useState } from 'react' -import { useLocation, useNavigate } from 'react-router-dom' -import cn from 'classnames' -import './menu.scss' -import { useTranslation } from 'react-i18next' -import { PAGES as pages } from 'src/routes' - -const Menu = () => { - const { t, i18n } = useTranslation() - - const [currentLanguage, setCurrentLanguage] = useState('en') - - const navigate = useNavigate() - const { pathname: currpage } = useLocation() - - const handleChangeLanguage = () => { - const newLanguage = currentLanguage === 'en' ? 'he' : 'en' - setCurrentLanguage(newLanguage) - i18n.changeLanguage(newLanguage) - } - - return ( -
    - {pages.map((page) => ( -
  • - page.path[0] === '/' ? navigate(page.path) : window.open(page.path, '_blank') - }> - {React.createElement(page.icon)} - { - - } - {t(page.label)} -
  • - ))} - {null && } -
- ) -} - -export default Menu diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 4cade905..c5b01395 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -26,58 +26,58 @@ export const PAGES = [ { label: TEXT_KEYS.dashboard_page_title, path: '/dashboard', - icon: LaptopOutlined, + icon: , element: , }, { label: TEXT_KEYS.timeline_page_title, path: '/timeline', searchParamsRequired: true, - icon: FieldTimeOutlined, + icon: , element: , }, { label: TEXT_KEYS.gaps_page_title, path: '/gaps', searchParamsRequired: true, - icon: BarChartOutlined, + icon: , element: , }, { label: TEXT_KEYS.gaps_patterns_page_title, path: '/gaps_patterns', - icon: LineChartOutlined, + icon: , element: , }, { label: TEXT_KEYS.realtime_map_page_title, path: '/map', - icon: HeatMapOutlined, + icon: , element: , }, { label: TEXT_KEYS.singleline_map_page_title, path: '/single-line-map', searchParamsRequired: true, - icon: RadarChartOutlined, + icon: , element: , }, { label: TEXT_KEYS.about_title, path: '/about', - icon: BellOutlined, + icon: , element: , }, { label: TEXT_KEYS.report_a_bug_title, path: 'https://github.com/hasadna/open-bus-map-search/issues', - icon: BugOutlined, + icon: , element: null, }, { label: TEXT_KEYS.donate_title, path: 'https://www.jgive.com/new/he/ils/donation-targets/3268#donation-modal', - icon: DollarOutlined, + icon: , element: null, }, ] diff --git a/tests/about.spec.ts b/tests/about.spec.ts index e0585ce2..92df1c94 100644 --- a/tests/about.spec.ts +++ b/tests/about.spec.ts @@ -4,8 +4,8 @@ test.describe('About Page Tests', () => { await page.goto('/') await page.getByText('אודות').click() await expect(page).toHaveURL('http://localhost:3000/about') - const locator = await page.getByText('אודות') - await expect(locator).toHaveClass('menu-item active') + const locator = await page.locator('li:has-text("אודות")') + await expect(locator).toHaveClass(/ant-menu-item-selected/) }) test('page display title `מהו אתר “דאטאבוס”?`', async ({ page }) => { await page.goto('/about') diff --git a/tests/menu.spec.ts b/tests/menu.spec.ts index f8bc623c..e1249cbb 100644 --- a/tests/menu.spec.ts +++ b/tests/menu.spec.ts @@ -4,7 +4,7 @@ test('menu', async ({ page }) => { await page.goto('/') await expect(page.locator('h1')).toContainText('דאטאבוס') const menuItemsInOrder = [ - 'מפעילי תח"צ לפי קיום נסיעות מתוכננות', + 'קיום נסיעות', 'לוח זמנים היסטורי', 'נסיעות שלא יצאו', 'דפוסי נסיעות שלא יצאו', @@ -14,5 +14,5 @@ test('menu', async ({ page }) => { 'דיווח על באג', 'לתרומות', ] - await expect(page.locator('ul > li')).toContainText(menuItemsInOrder) + await expect(page.locator('ul > li a')).toContainText(menuItemsInOrder) })