Skip to content

Commit

Permalink
feat: error boundary, pull in leaflet. (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
morganney committed Sep 6, 2023
1 parent b6c117d commit 2f357fb
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 62 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
with:
name: npm-debug-log-${{ hashFiles('package-lock.json') }}
path: npm-debug.log
- name: Build Docker
run: docker compose build
- name: Build Components
run: npm run build -w @busmap/components
- name: Build UI
Expand Down
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ RUN npm config set registry https://registry.npmjs.org/
RUN npm install
EXPOSE 3000 5173 9000

FROM busmap AS uibuild
WORKDIR /app
COPY . .
RUN npm run build -w @busmap/components
RUN npm run build -w ui

FROM nginx:1.25.2 AS dev
# core nginx conf
COPY packages/web/nginx.local.conf /etc/nginx/nginx.conf
Expand All @@ -24,5 +30,4 @@ COPY packages/web/conf.d/ /etc/nginx/conf.d/
# ssl certs
COPY packages/web/certs/ /etc/nginx/certs/
# ui build
COPY packages/ui/dist /usr/share/nginx/html
#COPY --from=ui packages/ui/dist /usr/share/nginx/html
COPY --from=uibuild /app/packages/ui/dist /usr/share/nginx/html
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion packages/components/src/autoSuggest/mod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SelectWrap, SelectMenuWrap, SelectMenu, SelectItem } from '../core.js'
import { focusedStyles, sizing } from '../styles.js'
import { Input } from '../input/mod.js'
import { PB40T, SLB30T } from '../colors.js'
import { ChevronDown } from '../icons/chevronDown/mod.js'
import { ChevronDown as ChevronDownIcon } from '../icons/chevronDown/mod.js'

import type { ChangeEvent, FC, ReactNode } from 'react'
import type { UseComboboxStateChange, UseComboboxStateChangeTypes } from 'downshift'
Expand Down Expand Up @@ -70,6 +70,14 @@ const getRightPosition = ({ size }: { size: Size }) => {
return `calc(${right} + 30px)`
}
}
const ChevronDown = styled(ChevronDownIcon)`
position: relative;
right: -2px;
&.isOpen {
transform: rotate(180deg);
}
`
const Combobox = styled.div`
display: flex;
align-items: center;
Expand Down
4 changes: 0 additions & 4 deletions packages/components/src/icons/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ const Icon = styled.span<{ size: Size; color: string }>`
border: 1px solid ${SLB30T};
border-radius: 50%;
}
&.isOpen {
transform: rotate(180deg);
}
`

export { getSizing, Icon }
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/input/mod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const Wrapper = styled.span`
`
const Close = styled(CloseIcon)`
position: absolute;
right: 9px;
right: 10px;
`
const StyledInput = styled.input<{
color: string
Expand Down
6 changes: 3 additions & 3 deletions packages/components/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const sizing = {
padding: '8px 14px 8px 38px'
},
clearable: {
padding: '8px 38px 8px 14px'
padding: '8px 28px 8px 14px'
},
iconClearable: {
padding: '8px 38px 8px 38px'
Expand All @@ -30,7 +30,7 @@ const sizing = {
padding: '10px 16px 10px 40px'
},
clearable: {
padding: '10px 40px 10px 16px'
padding: '10px 30px 10px 16px'
},
iconClearable: {
padding: '10px 40px 10px 40px'
Expand All @@ -46,7 +46,7 @@ const sizing = {
padding: '14px 16px 14px 40px'
},
clearable: {
padding: '14px 40px 14px 16px'
padding: '14px 30px 14px 16px'
},
iconClearable: {
padding: '14px 40px 14px 40px'
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css"
integrity="sha512-h9FcoyWjHcOcmEVkxOfTLnmZFWIH0iZhZT1H2TbOq55xssQGEJHEaIm+PgoUaZbRvQTNTluNOEfb1ZRy6D3BOw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link rel="stylesheet" href="src/global.css" />
<title>BusMap</title>
</head>
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@
],
"author": "Morgan Ney <[email protected]>",
"devDependencies": {
"@types/geojson": "^7946.0.10",
"@types/leaflet": "^1.9.4",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.4",
"vite": "^4.4.9"
},
"dependencies": {
"@busmap/components": "^1.0.0-alpha.0",
"leaflet": "^1.9.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.3",
Expand Down
17 changes: 10 additions & 7 deletions packages/ui/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { Providers } from './providers.js'
import { Layout } from './layout.js'
import { Home } from './home.js'
import { ErrorBoundary } from './components/errorBoundary.js'

import type { FC } from 'react'

const BusMap: FC = () => {
return (
<Providers>
<Layout>
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</BrowserRouter>
</Layout>
<ErrorBoundary>
<Layout>
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</BrowserRouter>
</Layout>
</ErrorBoundary>
</Providers>
)
}
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/components/agencies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Agencies: FC<Props> = ({ agencies }) => {
<p>Selection: {selection || 'n/a'}</p>
<AutoSuggest
onClear
caseInsensitive
inputBoundByItems
placeholder="Select a transit agency"
items={items}
Expand Down
41 changes: 41 additions & 0 deletions packages/ui/src/components/errorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Component } from 'react'

import type { ReactNode } from 'react'

interface ErrorBoundaryProps {
children: ReactNode
}
interface State {
hasError: boolean
error?: Error
}

class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
constructor(props: ErrorBoundaryProps) {
super(props)

this.state = {
hasError: false
}
}
static getDerivedStateFromError(error: Error) {
return {
hasError: true,
error
}
}

render() {
if (this.state.hasError) {
return (
<div>
<p>Oops!: {this.state.error?.message}</p>
</div>
)
}

return this.props.children
}
}

export { ErrorBoundary }
1 change: 1 addition & 0 deletions packages/ui/src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ aside {
position: absolute;
top: 10px;
right: 10px;
z-index: 999;
background: #ffffff88;
padding: 20px;
width: 35%;
Expand Down
48 changes: 36 additions & 12 deletions packages/ui/src/home.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
import styled from 'styled-components'
import { Clear } from '@busmap/components/icons/clear'

const Content = styled.p`
font-weight: 700;
`
export const Home = () => {
return (
<Content>
This is Home page content. <Clear />
</Content>
)
import { useQuery } from 'react-query'
import { createPortal } from 'react-dom'

import { Agencies } from './components/agencies.js'

import type { ReactNode, FC } from 'react'

export interface HomeProps {
children?: ReactNode
}
export const Home: FC<HomeProps> = () => {
const { data, error } = useQuery('agencies', async () => {
const resp = await fetch('/restbus/agencies')
const json = await resp.json()

return json
})

if (error) {
if (error instanceof Error) {
return <p>An unexpected error occured: {error.message}</p>
}
}

if (data) {
return (
<>
{createPortal(
<Agencies agencies={data} />,
document.querySelector('body > aside') as HTMLElement
)}
</>
)
}

return <>Loading...</>
}
48 changes: 21 additions & 27 deletions packages/ui/src/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import { useQuery } from 'react-query'
import { createPortal } from 'react-dom'

import { Agencies } from './components/agencies.js'
import L from 'leaflet'
import { useEffect } from 'react'

import type { FC, ReactNode } from 'react'

export const Layout: FC<{ children: ReactNode }> = ({ children }) => {
const { data, error } = useQuery('agencies', async () => {
const resp = await fetch('/restbus/agencies')
const json = await resp.json()
export interface LayoutProps {
children: ReactNode
}
export const Layout: FC<LayoutProps> = ({ children }) => {
useEffect(() => {
const main = document.querySelector('main') as HTMLElement
const map = L.map(main, {
center: [32.79578, -95.45166],
zoom: 13
})

return json
})
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map)

if (error) {
if (error instanceof Error) {
return <p>An unexpected error occured: {error.message}</p>
return () => {
map.remove()
}
}

if (data) {
return (
<>
{createPortal(
<Agencies agencies={data} />,
document.querySelector('body > aside') as HTMLElement
)}
{children}
</>
)
}
}, [])

return <>Loading...</>
return children
}
6 changes: 1 addition & 5 deletions packages/ui/src/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ const queryClient = new QueryClient({
}
})
const Providers: FC<{ children: ReactNode }> = ({ children }) => {
return (
<>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</>
)
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}

export { Providers }

0 comments on commit 2f357fb

Please sign in to comment.