mirror of
https://github.com/ChenQihan666/Lolia-Nodes-Status-Pages.git
synced 2026-08-14 07:52:34 +08:00
Initial commit
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { Text, Tooltip } from '@mantine/core'
|
||||
import { MonitorState, MonitorTarget } from '@/types/config'
|
||||
import { IconAlertCircle, IconAlertTriangle, IconCircleCheck } from '@tabler/icons-react'
|
||||
import DetailChart from './DetailChart'
|
||||
import DetailBar from './DetailBar'
|
||||
import { getColor } from '@/util/color'
|
||||
import { maintenances } from '@/uptime.config'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export default function MonitorDetail({
|
||||
monitor,
|
||||
state,
|
||||
}: {
|
||||
monitor: MonitorTarget
|
||||
state: MonitorState
|
||||
}) {
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
if (!state.latency[monitor.id])
|
||||
return (
|
||||
<>
|
||||
<Text mt="sm" fw={700}>
|
||||
{monitor.name}
|
||||
</Text>
|
||||
<Text mt="sm" fw={700}>
|
||||
{t('No data available')}
|
||||
</Text>
|
||||
</>
|
||||
)
|
||||
|
||||
let statusIcon =
|
||||
state.incident[monitor.id].slice(-1)[0].end === null ? (
|
||||
<IconAlertCircle
|
||||
style={{ width: '1.25em', height: '1.25em', color: '#b91c1c', marginRight: '3px' }}
|
||||
/>
|
||||
) : (
|
||||
<IconCircleCheck
|
||||
style={{ width: '1.25em', height: '1.25em', color: '#059669', marginRight: '3px' }}
|
||||
/>
|
||||
)
|
||||
|
||||
// Hide real status icon if monitor is in maintenance
|
||||
const now = new Date()
|
||||
const hasMaintenance = maintenances
|
||||
.filter((m) => now >= new Date(m.start) && (!m.end || now <= new Date(m.end)))
|
||||
.find((maintenance) => maintenance.monitors?.includes(monitor.id))
|
||||
if (hasMaintenance)
|
||||
statusIcon = (
|
||||
<IconAlertTriangle
|
||||
style={{
|
||||
width: '1.25em',
|
||||
height: '1.25em',
|
||||
color: '#fab005',
|
||||
marginRight: '3px',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
let totalTime = Date.now() / 1000 - state.incident[monitor.id][0].start[0]
|
||||
let downTime = 0
|
||||
for (let incident of state.incident[monitor.id]) {
|
||||
downTime += (incident.end ?? Date.now() / 1000) - incident.start[0]
|
||||
}
|
||||
|
||||
const uptimePercent = (((totalTime - downTime) / totalTime) * 100).toPrecision(4)
|
||||
|
||||
// Conditionally render monitor name with or without hyperlink based on monitor.url presence
|
||||
const monitorNameElement = (
|
||||
<Text mt="sm" fw={700} style={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||
{monitor.statusPageLink ? (
|
||||
<a
|
||||
href={monitor.statusPageLink}
|
||||
target="_blank"
|
||||
style={{ display: 'inline-flex', alignItems: 'center', color: 'inherit' }}
|
||||
>
|
||||
{statusIcon} {monitor.name}
|
||||
</a>
|
||||
) : (
|
||||
<>
|
||||
{statusIcon} {monitor.name}
|
||||
</>
|
||||
)}
|
||||
</Text>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
{monitor.tooltip ? (
|
||||
<Tooltip label={monitor.tooltip}>{monitorNameElement}</Tooltip>
|
||||
) : (
|
||||
monitorNameElement
|
||||
)}
|
||||
|
||||
<Text mt="sm" fw={700} style={{ display: 'inline', color: getColor(uptimePercent, true) }}>
|
||||
{t('Overall', { percent: uptimePercent })}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<DetailBar monitor={monitor} state={state} />
|
||||
{!monitor.hideLatencyChart && <DetailChart monitor={monitor} state={state} />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user