Skip to content

Commit

Permalink
feat: nginx health check & selector loader. (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
morganney authored Jan 3, 2024
1 parent 4bf2a2b commit c9b5ede
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 32 deletions.
37 changes: 28 additions & 9 deletions packages/ui/src/components/busSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState, useCallback, useMemo, memo, useEffect, useRef } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useQuery, useIsFetching } from '@tanstack/react-query'
import { useNavigate, generatePath } from 'react-router-dom'
import { latLng, latLngBounds } from 'leaflet'
import styled from 'styled-components'
Expand Down Expand Up @@ -43,6 +43,8 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) {
const [routeName, setRouteName] = useState<RouteName>()
const { dispatch, agency, route, direction, stop } = useGlobals()
const vehiclesDispatch = useVehiclesDispatch()
const vehicleFetches = useIsFetching({ queryKey: ['vehicles'] })
const routeVehiclesLoaded = useRef(false)
const stops = useMemo(() => {
if (direction && route) {
return route.stops.filter(({ id }) => direction.stops.includes(id))
Expand All @@ -57,7 +59,7 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) {
const {
data: routes,
error: routesError,
isLoading: isRoutesLoading
isFetching: isRoutesFetching
} = useQuery({
queryKey: ['routes', agency?.id],
queryFn: () => getAllRoutes(agency?.id),
Expand All @@ -67,7 +69,7 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) {
const {
data: routeConfig,
error: routeError,
isLoading: isRouteLoading
isFetching: isRouteFetching
} = useQuery({
/**
* Use two attributes from a route to prevent collisions across agencies.
Expand Down Expand Up @@ -156,7 +158,9 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) {
}
}, [navigate, dispatch, vehiclesDispatch, agency, route, direction])
const error = getFirstDataError([routesError, routeError])
const isLoading = isRoutesLoading || isRouteLoading
const isFetching = isRoutesFetching || isRouteFetching
const isPageLoading =
isFetching || Boolean(!routeVehiclesLoaded.current && vehicleFetches)

/**
* Update page title and description.
Expand Down Expand Up @@ -286,8 +290,23 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) {
}
}, [dispatch, homeStop, agencies, agency, routeName, routes, route, direction, stop])

/**
* These effects are so that the loader only
* renders for the first load of vehicles
* when the route changes.
*/
useEffect(() => {
routeVehiclesLoaded.current = false
}, [route])

useEffect(() => {
if (!vehicleFetches && !routeVehiclesLoaded.current) {
routeVehiclesLoaded.current = true
}
}, [vehicleFetches])

return (
<Page title="Bus Selector">
<Page title="Bus Selector" loading={isPageLoading}>
{error instanceof Error && <SelectorError err={error} />}
<Form
onSubmit={evt => {
Expand All @@ -297,26 +316,26 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) {
agencies={agencies}
selected={agency}
onSelect={onSelectAgency}
isDisabled={isLoading}
isDisabled={isFetching}
/>
<Routes
routes={routes}
selected={routeName}
onSelect={onSelectRoute}
isDisabled={isLoading || !agency}
isDisabled={isFetching || !agency}
/>
<Directions
directions={route?.directions}
selected={direction}
onSelect={onSelectDirection}
isDisabled={isLoading || !agency || !route}
isDisabled={isFetching || !agency || !route}
/>
<Stops
stops={stops}
selected={stop}
onClear={onClearStop}
onSelect={onSelectStop}
isDisabled={isLoading || !agency || !route || !direction}
isDisabled={isFetching || !agency || !route || !direction}
/>
</Form>
</Page>
Expand Down
12 changes: 12 additions & 0 deletions packages/ui/src/components/dots.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Loading } from '@busmap/components/loading'
import { PB90T, PB20T } from '@busmap/components/colors'

import { useTheme } from '@module/settings/contexts/theme.js'

const Dots = () => {
const { mode } = useTheme()

return <Loading indent={2} color={mode === 'dark' ? PB90T : PB20T} />
}

export { Dots }
8 changes: 2 additions & 6 deletions packages/ui/src/components/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import styled from 'styled-components'
import { Loading as Dots } from '@busmap/components/loading'
import { PB20T, PB90T } from '@busmap/components/colors'

import { useTheme } from '../modules/settings/contexts/theme.js'
import { Dots } from './dots.js'

import type { FC } from 'react'

Expand All @@ -24,12 +22,10 @@ const Text = styled.p`
font-size: 1rem;
`
const Loading: FC<LoadingProps> = ({ text, useIcon = true }) => {
const { mode } = useTheme()

return (
<Text>
<span>
{text} {useIcon && <Dots indent={2} color={mode === 'dark' ? PB90T : PB20T} />}
{text} {useIcon && <Dots />}
</span>
</Text>
)
Expand Down
10 changes: 8 additions & 2 deletions packages/ui/src/components/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import styled from 'styled-components'

import { Dots } from './dots.js'

import type { FC, ReactNode } from 'react'

interface PageProps {
title: string
className?: string
loading?: boolean
children: ReactNode
}

Expand All @@ -23,10 +26,13 @@ const Section = styled.section`
line-height: 1.25;
}
`
const Page: FC<PageProps> = ({ title, children, className }) => {
const Page: FC<PageProps> = ({ title, children, className, loading = false }) => {
return (
<Section className={className}>
<h2>{title}</h2>
<h2>
{title}
{loading && <Dots />}
</h2>
{children}
</Section>
)
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { toast } from '@busmap/components/toast'
import { Button } from '@busmap/components/button'
import { SignOut } from '@busmap/components/icons/signOut'
import { PB80T, PB20T, PB90T } from '@busmap/components/colors'
import { Loading } from '@busmap/components/loading'

import { logout } from '@core/api/authn.js'
import { useGlobals } from '@core/globals.js'
import { useStorageDispatch } from '@core/contexts/storage.js'
import { useTheme } from '@module/settings/contexts/theme.js'

import { Page } from './page.js'
import { Dots } from './dots.js'

import type { FC } from 'react'
import type { Mode } from '@busmap/common/types/settings'
Expand Down Expand Up @@ -151,7 +151,7 @@ const Profile: FC = () => {
<div>
{loading ? (
<p>
Signing you out <Loading indent={2} color={mode === 'dark' ? PB90T : PB20T} />
Signing you out <Dots />
</p>
) : (
<SignOutBtn $mode={mode} disabled={loading} onClick={onClickSignOut}>
Expand Down
7 changes: 2 additions & 5 deletions packages/ui/src/components/signIn.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { useEffect, useRef, useState } from 'react'
import styled from 'styled-components'
import { toast } from '@busmap/components/toast'
import { Loading } from '@busmap/components/loading'
import { PB20T, PB90T } from '@busmap/components/colors'

import { login } from '@core/api/authn.js'
import { useGlobals } from '@core/globals.js'
import { useStorageDispatch } from '@core/contexts/storage.js'
import { useTheme } from '@module/settings/contexts/theme.js'
import { MAX_USER_FAVORITES } from '@module/favorites/common.js'
import { get as getFavorites } from '@module/favorites/api/get.js'

import { Page } from './page.js'
import { Dots } from './dots.js'

import type { FC } from 'react'
import type { RiderFavoriteItem } from '@busmap/common/types/favorites'
Expand All @@ -22,7 +20,6 @@ const Note = styled.em`
const SignIn: FC = () => {
const ref = useRef<HTMLDivElement>(null)
const { dispatch } = useGlobals()
const { mode } = useTheme()
const [riderFavorites, setRiderFavorites] = useState<RiderFavoriteItem[]>()
const [loading, setLoading] = useState(false)
const storageDispatch = useStorageDispatch()
Expand Down Expand Up @@ -81,7 +78,7 @@ const SignIn: FC = () => {
<Page title="Sign In">
{loading ? (
<p>
Signing you in <Loading indent={2} color={mode === 'dark' ? PB90T : PB20T} />
Signing you in <Dots />
</p>
) : (
<>
Expand Down
2 changes: 0 additions & 2 deletions packages/web/default.dev.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
include /etc/nginx/conf.d/core/compression.conf;

location / {
resolver 8.8.8.8 valid=30s;

proxy_pass http://dev_server;
proxy_http_version 1.1;
proxy_set_header Host $host;
Expand Down
14 changes: 8 additions & 6 deletions packages/web/templates/default.conf.template
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Configuration to stage a production build locally.
# Known differences:
# - TODO (when they arise)
# Configuration to stage a production build.

server {
# Redirect server configuration
Expand All @@ -14,6 +12,7 @@ server {

server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name ${SERVER_NAME};
root /var/www/${HOST_NAME};
Expand All @@ -22,10 +21,13 @@ server {
include /etc/nginx/conf.d/core/ssl.conf;
include /etc/nginx/conf.d/core/compression.conf;

location / {
resolver 8.8.8.8 valid=30s;
location = /healthcheck {
add_header Content-Type "application/json";
return 200 '{"status": "OK"}';
}

location ~ /(authn|restbus|rider|favorite) {
location / {
location ~ /(authn|restbus|rider|favorite|health) {
access_log /var/log/nginx/api.log api;
proxy_pass http://api_server;
# Allow keepalive to work with the upstream
Expand Down

0 comments on commit c9b5ede

Please sign in to comment.