Skip to content

Commit

Permalink
refactor: use modern routing + get some data for line profile page (#291
Browse files Browse the repository at this point in the history
)
  • Loading branch information
NoamGaash authored Dec 14, 2023
1 parent 5d3dc4c commit 9393b6f
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 265 deletions.
118 changes: 9 additions & 109 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,115 +1,15 @@
import { useCallback, useEffect } from 'react'
import 'antd/dist/antd.min.css'
import './App.scss'
import { ConfigProvider } from 'antd'
import 'leaflet/dist/leaflet.css'
import heIL from 'antd/es/locale/he_IL'
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 { useLocation } from 'react-router-dom'
import ReactGA from 'react-ga4'
import { CacheProvider } from '@emotion/react'
import createCache from '@emotion/cache'
import rtlPlugin from 'stylis-plugin-rtl'
import 'moment/locale/he'
import { heIL as heILmui } from '@mui/x-date-pickers/locales'
import { ThemeProvider, createTheme } from '@mui/material'
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'
import { LocalizationProvider } from '@mui/x-date-pickers'
import { EasterEgg } from './pages/EasterEgg/EasterEgg'
import { usePages } from './routes'
import MainLayout from './layout'
import { Envelope } from './pages/EasterEgg/Envelope'

const theme = createTheme(
{
direction: 'rtl',
palette: {
primary: {
main: '#5f5bff',
},
},
},
heILmui,
)

// Create rtl cache
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [rtlPlugin],
})

const App = () => {
const location = useLocation()

const [searchParams, setSearchParams] = useSearchParams()
const operatorId = searchParams.get('operatorId')
const lineNumber = searchParams.get('lineNumber')
const routeKey = searchParams.get('routeKey')
const timestamp = searchParams.get('timestamp')
const pages = usePages()

useEffect(() => {
ReactGA.send({ hitType: 'pageview', page: location.pathname + location.search })
}, [location])

const [search, setSearch] = useSessionStorage<PageSearchState>('search', {
timestamp: +timestamp! || moment().valueOf(),
operatorId: operatorId || '',
lineNumber: lineNumber || '',
routeKey: routeKey || '',
})

useEffect(() => {
const page = pages.find((page) => page.path === location.pathname)
if (page?.searchParamsRequired) {
const params = new URLSearchParams({ timestamp: search.timestamp.toString() })

if (search.operatorId) {
params.set('operatorId', search.operatorId)
}
if (search.lineNumber) {
params.set('lineNumber', search.lineNumber)
}
if (search.routeKey) {
params.set('routeKey', search.routeKey)
}
setSearchParams(params)
}
}, [search.lineNumber, search.operatorId, search.routeKey, search.timestamp, location.pathname])

const safeSetSearch = useCallback((mutate: (prevState: PageSearchState) => PageSearchState) => {
setSearch((current: PageSearchState) => {
const newSearch = mutate(current)
return newSearch
})
}, [])

return (
<SearchContext.Provider value={{ search, setSearch: safeSetSearch }}>
<CacheProvider value={cacheRtl}>
<ThemeProvider theme={theme}>
<LocalizationProvider dateAdapter={AdapterMoment} adapterLocale="he">
<ConfigProvider direction="rtl" locale={heIL}>
<MainLayout />
</ConfigProvider>
</LocalizationProvider>
</ThemeProvider>
</CacheProvider>
</SearchContext.Provider>
)
}

const RoutedApp = () => (
<Router>
<App />
<EasterEgg code="storybook">
<a href="/storybook/index.html">
<Envelope />
</a>
</EasterEgg>
</Router>
import router from './routes'
import { RouterProvider } from 'react-router-dom'
import { Suspense } from 'react'
import Preloader from './shared/Preloader'

export const RoutedApp = () => (
<Suspense fallback={<Preloader />}>
<RouterProvider router={router} />
</Suspense>
)
export default RoutedApp
19 changes: 14 additions & 5 deletions src/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import MainHeader from './header/Header'
import SideBar from './sidebar/SideBar'
import styled from 'styled-components'
import LayoutContext from './LayoutContext'
import RoutesList from '../routes'
import { Outlet } from 'react-router-dom'
import { Suspense } from 'react'
import Preloader from 'src/shared/Preloader'
import { EasterEgg } from 'src/pages/EasterEgg/EasterEgg'
import { Envelope } from 'src/pages/EasterEgg/Envelope'

const { Content } = Layout

Expand All @@ -19,7 +23,7 @@ const StyledBody = styled.div`
min-height: 360px;
`

function MainLayout() {
export function MainLayout() {
return (
<StyledLayout className="main">
<LayoutContext>
Expand All @@ -28,13 +32,18 @@ function MainLayout() {
<MainHeader />
<StyledContent>
<StyledBody>
<RoutesList />
<Suspense fallback={<Preloader />}>
<Outlet />
<EasterEgg code="storybook">
<a href="/storybook/index.html">
<Envelope />
</a>
</EasterEgg>
</Suspense>
</StyledBody>
</StyledContent>
</Layout>
</LayoutContext>
</StyledLayout>
)
}

export default MainLayout
5 changes: 2 additions & 3 deletions src/layout/sidebar/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useContext, useState } from 'react'
import { LayoutContextInterface, LayoutCtx } from '../LayoutContext'
import GitHubLink from './GitHubLink/GitHubLink'
import { Link } from 'react-router-dom'
import { usePages } from 'src/routes'
import { PAGES } from 'src/routes'
const { Sider } = Layout

const Logo = () => (
Expand All @@ -18,7 +18,6 @@ const CollapsedLogo = () => <h1 className={'sidebar-logo-collapsed'}>🚌</h1>
export default function SideBar() {
const { drawerOpen, setDrawerOpen } = useContext<LayoutContextInterface>(LayoutCtx)
const [collapsed, setCollapsed] = useState(false)
const pages = usePages()
return (
<>
<Drawer
Expand All @@ -43,7 +42,7 @@ export default function SideBar() {
collapsed={collapsed}
onCollapse={(value: boolean) => setCollapsed(value)}
className="hideOnMobile">
<Link to={pages[0].path} replace>
<Link to={PAGES[0].path} replace>
{collapsed ? <CollapsedLogo /> : <Logo />}
</Link>
<div className="sidebar-divider"></div>
Expand Down
5 changes: 2 additions & 3 deletions src/layout/sidebar/menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
import './menu.scss'
import { useTranslation } from 'react-i18next'
import { usePages } from 'src/routes'
import { PAGES } from 'src/routes'

import type { MenuProps } from 'antd'
import { Menu } from 'antd'
Expand All @@ -25,8 +25,7 @@ function getItem(

const MainMenu = () => {
const { t } = useTranslation()
const pages = usePages()
const items: MenuItem[] = pages.map((itm) => {
const items: MenuItem[] = PAGES.map((itm) => {
return getItem(<Link to={t(itm.path)}>{t(itm.label)}</Link>, itm.path, itm.icon)
})

Expand Down
6 changes: 5 additions & 1 deletion src/locale/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,9 @@
"bearing": "מעלות",
"coords": "נ.צ.",
"hide_document": "הסתר מידע לגיקים",
"show_document": "הצג מידע לגיקים"
"show_document": "הצג מידע לגיקים",
"lineProfile": {
"title": "פרופיל קו",
"notFound":"לא הצלחנו למצוא את הקו שחיפשת :("
}
}
92 changes: 26 additions & 66 deletions src/pages/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,15 @@
import styled from 'styled-components'
import React from 'react'
// import { useContext, useState } from 'react'
import { useContext } from 'react'
import Grid from '@mui/material/Unstable_Grid2' // Grid version 2
import moment from 'moment'

import { Label } from './components/Label'
import { NotFound } from './components/NotFound'
import { PageContainer } from './components/PageContainer'

import { useTranslation } from 'react-i18next'
// import GapsPage from './GapsPage'
// import SingleLineMapPage from './SingleLineMapPage'
import { PageSearchState, SearchContext } from '../model/pageState'
import LineNumberSelector from './components/LineSelector'
import OperatorSelector from './components/OperatorSelector'
import RouteSelector from './components/RouteSelector'

//API
// import { /*getGtfsRidesList,*/ getRidesAsync } from 'src/api/profileService'
import { getRoutesAsync } from '../api/gtfsService'
import Widget from 'src/shared/Widget'

// time inputs
// import { DateSelector } from './components/DateSelector'
// import { TimeSelector } from './components/TimeSelector'
// import { useDate } from './components/DateTimePicker'
import { useLoaderData } from 'react-router-dom'

const Profile = () => {
return (
Expand All @@ -36,71 +20,47 @@ const Profile = () => {
}

const GeneralDetailsAboutLine = () => {
const { search, setSearch } = useContext(SearchContext)
const { operatorId, lineNumber, routes, routeKey } = search
const { t } = useTranslation()
return (
<>
<PageContainer className="line-data-container">
{/* choose operator */}
<Grid xs={8}>
<OperatorSelector
operatorId={operatorId}
setOperatorId={(id) => setSearch((current) => ({ ...current, operatorId: id }))}
/>
</Grid>

{/* choose line number */}
<Grid xs={8}>
<LineNumberSelector
lineNumber={lineNumber}
setLineNumber={(number) => setSearch((current) => ({ ...current, lineNumber: number }))}
/>
</Grid>

{/* choose route*/}
<Grid xs={12}>
{routes &&
(routes.length === 0 ? (
<NotFound>{t('line_not_found')}</NotFound>
) : (
<RouteSelector
routes={routes}
routeKey={routeKey}
setRouteKey={(key) => setSearch((current) => ({ ...current, routeKey: key }))}
/>
))}
</Grid>

<LineProfileComponent search={search} />
<LineProfileComponent />
</PageContainer>
</>
)
}

const LineProfileComponent = ({ search }: { search: PageSearchState }) => {
const LineProfileComponent = () => {
const { t } = useTranslation()

// const resp = getRidesAsync(search.operatorId, search.lineNumber, search.routeKey, new Date())
// const resp = getGtfsRidesList(new Date(), '3', '271', '1')
const resp = getRoutesAsync(
moment(search.timestamp),
moment(search.timestamp),
search.operatorId,
search.lineNumber,
)
const route = useLoaderData() as {
// TODO: find better type definition
agency_name: string
route_short_name: string
route_long_name: string
message?: string
}
console.log('route', route)

if (route.message)
return (
<NotFound>
<Widget>
<h1>{t('lineProfile.notFound')}</h1>
<pre>{route.message}</pre>
</Widget>
</NotFound>
)

return (
<Grid xs={12} lg={6}>
<Widget>
<h2 className="title">{t('profile_page')}</h2>
<label> מפעיל: {search.operatorId} </label>
<h2 className="title">{t('lineProfile.title')}</h2>
<label> מפעיל: {route.agency_name} </label>
<br></br>
<label> מספר קו: {search.lineNumber} </label>
<label> מספר קו: {route.route_short_name} </label>
<br></br>
<label> כיוון נסיעה: {search.routeKey} </label>
<label> כיוון נסיעה: {route.route_long_name} </label>
<div>
<div>{resp.toString()}</div>
<pre style={{ direction: 'ltr' }}>{JSON.stringify(route, null, 2)}</pre>
<Label text="שעות פעילות" />
{/* GET the earliest and the latest bus drive departure time for each day */}
<TableStyle>
Expand Down
Loading

0 comments on commit 9393b6f

Please sign in to comment.