Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

feat(network-status): Notify users when they're working offline #2109

Merged
merged 8 commits into from
Jun 7, 2020
2 changes: 2 additions & 0 deletions src/HospitalRun.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Switch, Route } from 'react-router-dom'

import Breadcrumbs from './breadcrumbs/Breadcrumbs'
import Navbar from './components/Navbar'
import { NetworkStatus } from './components/network-status/NetworkStatus'
import PrivateRoute from './components/PrivateRoute'
import Sidebar from './components/Sidebar'
import Dashboard from './dashboard/Dashboard'
Expand All @@ -23,6 +24,7 @@ const HospitalRun = () => {

return (
<div>
<NetworkStatus />
<Navbar />
<div className="container-fluid">
<Sidebar />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { render, shallow } from 'enzyme'
import React from 'react'

import {
NetworkStatusMessage,
OFFLINE_MESSAGE,
ONLINE_MESSAGE,
} from '../../../components/network-status/NetworkStatusMessage'

describe('NetworkStatusMessage', () => {
it('returns null if the app has always been online', () => {
const wrapper = shallow(<NetworkStatusMessage online wasOffline={false} />)
expect(wrapper.equals(null as any)).toBe(true)
})
it(`shows the message "${OFFLINE_MESSAGE}" if the app goes offline`, () => {
const wrapper = render(<NetworkStatusMessage online={false} wasOffline={false} />)
expect(wrapper.text()).toContain(OFFLINE_MESSAGE)
})
it(`shows the message "${ONLINE_MESSAGE}" if the app goes back online after it was offline`, () => {
const wrapper = render(<NetworkStatusMessage online wasOffline />)
expect(wrapper.text()).toContain(ONLINE_MESSAGE)
})
})
29 changes: 29 additions & 0 deletions src/components/network-status/NetworkStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useState, useEffect } from 'react'

import { NetworkStatusMessage } from './NetworkStatusMessage'

export const NetworkStatus = () => {
This conversation was marked as resolved.
Show resolved Hide resolved
const [networkStatus, setNetworkStatus] = useState({
isOnline: true,
wasOffline: false,
})
const handleOnline = () => {
setNetworkStatus((prevState) => ({ ...prevState, isOnline: true }))
}
const handleOffline = () => {
setNetworkStatus((prevState) => ({ ...prevState, isOnline: false, wasOffline: true }))
}
useEffect(() => {
window.addEventListener('online', handleOnline)
window.addEventListener('offline', handleOffline)

return () => {
window.removeEventListener('online', handleOnline)
window.removeEventListener('offline', handleOffline)
}
}, [])

return (
<NetworkStatusMessage online={networkStatus.isOnline} wasOffline={networkStatus.wasOffline} />
)
}
43 changes: 43 additions & 0 deletions src/components/network-status/NetworkStatusMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { useState } from 'react'

import './styles.css'

interface Props {
online: boolean
wasOffline: boolean
}

export const OFFLINE_MESSAGE = 'you are working in offline mode'
export const ONLINE_MESSAGE = 'you are back online'
This conversation was marked as resolved.
Show resolved Hide resolved
const OPACITY_TRANSITION_TIME = 4000

export const NetworkStatusMessage = (props: Props) => {
const { online, wasOffline } = props
const [display, setDisplay] = useState('flex')
const [opacity, setOpacity] = useState(1)

if (online && !wasOffline) {
return null
}

if (!online && opacity !== 1) {
setDisplay('flex')
setOpacity(1)
}

if (online && wasOffline && opacity !== 0) {
setOpacity(0)
setTimeout(() => {
setDisplay('none')
}, OPACITY_TRANSITION_TIME)
}

return (
<div
className={`network-status-message ${online ? 'online' : 'offline'}`}
style={{ display, opacity, transition: `opacity ${OPACITY_TRANSITION_TIME}ms ease-in` }}
>
{online ? ONLINE_MESSAGE : OFFLINE_MESSAGE}
</div>
)
}
18 changes: 18 additions & 0 deletions src/components/network-status/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.network-status-message {
align-items: center;
bottom: 0;
height: 50px;
justify-content: center;
pointer-events: none;
position: absolute;
width: 100vw;
z-index: 9999;
}

.network-status-message.offline {
background-color: rgba(255, 0, 0, 0.65);
}

.network-status-message.online {
background-color: rgba(0, 255, 0, 0.55);
}
This conversation was marked as resolved.
Show resolved Hide resolved