first commit. added CI, Docker compose, blank client and server. used unit tests, they pass
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { pingApi, type PingResponse } from './api'
|
||||
import './index.css'
|
||||
|
||||
type ApiState =
|
||||
| { status: 'loading' }
|
||||
| { status: 'ok'; data: PingResponse }
|
||||
| { status: 'error'; error: string }
|
||||
|
||||
function App() {
|
||||
const [api, setApi] = useState<ApiState>({ status: 'loading' })
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
pingApi()
|
||||
.then((data) => {
|
||||
if (!cancelled) setApi({ status: 'ok', data })
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
if (!cancelled) setApi({ status: 'error', error: String(err) })
|
||||
})
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<main className="shell">
|
||||
<h1>Messenger</h1>
|
||||
<div className="card">
|
||||
<div className="status-row">
|
||||
<span className={`dot ${api.status}`} aria-hidden />
|
||||
<span className="status-label">
|
||||
{api.status === 'loading' && 'API: connecting…'}
|
||||
{api.status === 'ok' && 'API: connected'}
|
||||
{api.status === 'error' && 'API: unreachable'}
|
||||
</span>
|
||||
</div>
|
||||
{api.status === 'ok' && (
|
||||
<p className="detail">
|
||||
{api.data.message} · server time {api.data.time}
|
||||
</p>
|
||||
)}
|
||||
{api.status === 'error' && <p className="detail">{api.error}</p>}
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
Reference in New Issue
Block a user