diff --git a/components/DetailChart.tsx b/components/DetailChart.tsx
new file mode 100644
index 0000000..8b712cb
--- /dev/null
+++ b/components/DetailChart.tsx
@@ -0,0 +1,79 @@
+import { Line } from "react-chartjs-2"
+import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip as ChartTooltip, Legend, TimeScale } from 'chart.js'
+import 'chartjs-adapter-moment'
+import { MonitorState, MonitorTarget } from "@/uptime.types"
+
+ChartJS.register(
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ Title,
+ ChartTooltip,
+ Legend,
+ TimeScale
+)
+
+
+export default function DetailChart({ monitor, state }: { monitor: MonitorTarget, state: MonitorState }) {
+
+ const latencyData = state.latency[monitor.id].recent.map((point) => ({ x: point.time * 1000, y: point.ping, loc: point.loc }))
+
+ let data = {
+ datasets: [
+ {
+ data: latencyData,
+ borderColor: 'rgb(112, 119, 140)',
+ borderWidth: 2,
+ radius: 0,
+ cubicInterpolationMode: 'monotone' as const,
+ tension: 0.4
+ }
+ ]
+ }
+
+ let options = {
+ responsive: true,
+ maintainAspectRatio: false,
+ interaction: {
+ mode: 'index' as const,
+ intersect: false,
+ },
+ plugins: {
+ tooltip: {
+ callbacks: {
+ label: (item: any) => {
+ if (item.parsed.y) {
+ return `${item.parsed.y}ms (${item.raw.loc})`
+ }
+ }
+ }
+ },
+ legend: {
+ display: false
+ },
+ title: {
+ display: true,
+ text: 'Response times(ms)',
+ align: 'start' as const
+ },
+ },
+ scales: {
+ x: {
+ type: 'time' as const,
+ ticks: {
+ source: 'auto' as const,
+ maxRotation: 0,
+ autoSkip: true
+ }
+ }
+ }
+ }
+
+ return (
+
+
+
+ )
+}
+
diff --git a/components/MonitorDetail.tsx b/components/MonitorDetail.tsx
index 4ce876a..1a63792 100644
--- a/components/MonitorDetail.tsx
+++ b/components/MonitorDetail.tsx
@@ -1,21 +1,21 @@
-import { Line } from "react-chartjs-2"
-import { Text } from "@mantine/core"
-import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, TimeScale } from 'chart.js'
+import { Text, Tooltip } from "@mantine/core"
import { MonitorState, MonitorTarget } from "@/uptime.types";
-import 'chartjs-adapter-moment'
import { IconAlertCircle, IconCircleCheck } from "@tabler/icons-react";
+import DetailChart from "./DetailChart";
-ChartJS.register(
- CategoryScale,
- LinearScale,
- PointElement,
- LineElement,
- Title,
- Tooltip,
- Legend,
- TimeScale
-)
+function getColor(percent: number | string, darker: boolean): string {
+ percent = Number(percent)
+ if (percent >= 99.9) {
+ return darker ? '#059669' : '#3bd671'
+ } else if (percent >= 99) {
+ return darker ? '#3bd671' : '#9deab8'
+ } else if (percent >= 95) {
+ return '#f29030'
+ } else {
+ return '#df484a'
+ }
+}
export default function MonitorDetail({ monitor, state }: { monitor: MonitorTarget, state: MonitorState }) {
@@ -27,75 +27,50 @@ export default function MonitorDetail({ monitor, state }: { monitor: MonitorTarg
>
)
- const statusIcon = (state.incident[monitor.id].slice(-1)[0] ?? { end: 'dummy' }).end === undefined ? :
+ const statusIcon = state.incident[monitor.id].slice(-1)[0].end === undefined ? :
- const latencyData = state.latency[monitor.id].recent.map((point) => ({ x: point.time * 1000, y: point.ping, loc: point.loc }))
+ 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]
+ }
- let data = {
- datasets: [
- {
- data: latencyData,
- borderColor: 'rgb(112, 119, 140)',
- borderWidth: 2,
- radius: 0,
- cubicInterpolationMode: 'monotone' as const,
- tension: 0.4
- }
- ]
- }
-
- let options = {
- responsive: true,
- maintainAspectRatio: false,
- interaction: {
- mode: 'index' as const,
- intersect: false,
- },
- plugins: {
- tooltip: {
- callbacks: {
- label: (item: any) => {
- if (item.parsed.y) {
- return `${item.parsed.y}ms (${item.raw.loc})`
- }
- }
- }
- },
- legend: {
- display: false
- },
- title: {
- display: true,
- text: 'Response times(ms)',
- align: 'start' as const
- },
- },
- scales: {
- x: {
- type: 'time' as const,
- ticks: {
- source: 'auto' as const,
- maxRotation: 0,
- autoSkip: true
- }
- }
- }
- }
+ console.log(totalTime)
+ console.log(downTime)
+ const uptimePercent = ((totalTime - downTime) / totalTime * 100).toPrecision(4)
const uptimePercentBars = []
+
+ // const day = new Date()
+ // day.setHours(0, 0, 0, 0)
+ // const dayStart = day.getTime()
+
for (let i = 0; i < 90; i++) {
- uptimePercentBars.push()
+
+ let dayDownTime = 0
+ let dayTotalTime = 0
+
+ if (state.incident[monitor.id][0].end)
+
+ uptimePercentBars.push(
+
+
+
+ )
}
return (
<>
- {statusIcon} {monitor.name}
- {/*
- {uptimePercentBars}
-
*/}
-
-
+
+ {statusIcon} {monitor.name}
+ Overall: {uptimePercent}%
+
+
+ {uptimePercentBars}
+
+
+
>
)
}
\ No newline at end of file