Skip to content

Instantly share code, notes, and snippets.

@kedoska
Last active August 18, 2020 21:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kedoska/8abc9859d81d220e8e963a1c327ffcd9 to your computer and use it in GitHub Desktop.
Save kedoska/8abc9859d81d220e8e963a1c327ffcd9 to your computer and use it in GitHub Desktop.
A mini reactemoji-monitor
import React, { FunctionComponent, useReducer, useEffect } from 'react'
export interface MonitorProps {
url: string
active: boolean
interval?: number
}
export interface MonitorState {
pinging: boolean
pinged: boolean
ok: boolean
status: number
}
export const getDefaultState = (): MonitorState => ({
pinging: false,
pinged: false,
ok: false,
status: 0,
})
export type ActionType = {
type: 'PING_STARTED' | 'PING_ENDED'
ok?: boolean
status?: number
}
export const reducer = (
state: MonitorState,
action: ActionType
): MonitorState => {
switch (action.type) {
case 'PING_STARTED':
return { ...state, pinging: true }
case 'PING_ENDED':
const { ok = false, status = 0 } = action
return { ...state, pinging: false, pinged: true, ok, status }
default:
return state
}
}
export const Monitor: FunctionComponent<MonitorProps> = ({
url,
interval = 30000,
active = false,
}) => {
const [state, dispatch] = useReducer(reducer, getDefaultState())
useEffect(() => {
const timer = setTimeout(async () => {
if (!active) {
return
}
try {
dispatch({ type: 'PING_STARTED' })
const { ok, status } = await fetch(url)
dispatch({ type: 'PING_ENDED', ok, status })
} catch ({ message }) {
dispatch({ type: 'PING_ENDED', ok: false, status: 0 })
}
}, interval)
return () => clearTimeout(timer)
})
if (!active) {
return <>⛔</>
}
if (!state.pinged) {
return <>❔</>
}
if (state.pinging) {
return <>❕</>
}
if (!state.ok) {
return <>🔴</>
} else {
return <>🟢</>
}
}
@kedoska
Copy link
Author

kedoska commented Aug 18, 2020

import React, { FunctionComponent, useState } from 'react'
import { Monitor } from '../components/monitor'

export const Dashboard: FunctionComponent<{}> = () => {

  const [active, setMonitor] = useState(false)

  console.log(active)

  const monitors = [
    { url: 'https://www.google.com', interval: 5000 },
    { url: 'https://amazon.com', interval: 7000 },
  ].map((x) => (
    <Monitor key={x.url} url={x.url} active={active} interval={x.interval} />
  ))

  return (
    <>
    <button onClick={() => setMonitor(!active)}>Toggle</button>
    <div>{monitors}</div>
    </>
  )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment