diff --git a/components/Header.tsx b/components/Header.tsx
index c1605ab..cfc5870 100644
--- a/components/Header.tsx
+++ b/components/Header.tsx
@@ -34,11 +34,9 @@ export default function Header() {
);
diff --git a/components/MonitorDetail.tsx b/components/MonitorDetail.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/components/MonitorList.tsx b/components/MonitorList.tsx
new file mode 100644
index 0000000..e4c3edd
--- /dev/null
+++ b/components/MonitorList.tsx
@@ -0,0 +1,67 @@
+import { MonitorState, MonitorTarget } from "@/uptime.types";
+import { Card, Center, Divider, Text } from "@mantine/core";
+import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js';
+import { Line } from "react-chartjs-2";
+
+ChartJS.register(
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ Title,
+ Tooltip,
+ Legend
+);
+
+
+export const options = {
+ responsive: true,
+ interaction: {
+ mode: 'index' as const,
+ intersect: false,
+ },
+ plugins: {
+ legend: {
+ position: 'top' as const,
+ },
+ title: {
+ display: true,
+ text: 'Response times',
+ align: 'start' as const
+ },
+ },
+};
+
+const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
+
+export const data = {
+ labels,
+ datasets: [
+ {
+ data: labels.map(() => Math.round(Math.random() * 1000)),
+ borderColor: 'rgb(255, 99, 132)',
+ backgroundColor: 'rgba(255, 99, 132, 0.5)',
+ }
+ ],
+};
+
+
+export default function MonitorList({ config, state }: { config: any, state: MonitorState }) {
+
+ return (
+
+
+ {config.monitors.map((monitor: MonitorTarget) => (
+
+
+ {monitor.name}
+
+
+
+
+ ))}
+
+
+ );
+}
+
diff --git a/components/OverallStatus.tsx b/components/OverallStatus.tsx
index ca1b478..35351e9 100644
--- a/components/OverallStatus.tsx
+++ b/components/OverallStatus.tsx
@@ -1,32 +1,27 @@
-import { Center, Space, Title } from '@mantine/core'
+import { Center, Title } from '@mantine/core'
import { IconCircleCheck, IconAlertCircle } from '@tabler/icons-react'
export default function OverallStatus({ state }: { state: { overallUp: number, overallDown: number, lastUpdate: number }}) {
let statusString = ''
- let icon =
+ let icon =
if (state.overallUp === 0 && state.overallDown === 0) {
statusString = 'No data yet'
} else if (state.overallUp === 0) {
- statusString = 'All down'
+ statusString = 'All systems not operational'
} else if (state.overallDown === 0) {
- statusString = 'All up'
- icon =
+ statusString = 'All systems operational'
+ icon =
} else {
- statusString = `${state.overallUp} up, ${state.overallDown} down`
+ statusString = `Some systems not operational (${state.overallDown} out of ${state.overallUp + state.overallDown})`
}
return (<>
{icon}
-
-
- {statusString}
-
-
- Last updated on: {new Date(state.lastUpdate * 1000).toLocaleString()}
-
+ {statusString}
+ Last updated on: {new Date(state.lastUpdate * 1000).toLocaleString()} ({Math.round(Date.now() / 1000) - state.lastUpdate} sec ago)
>)
}
diff --git a/package-lock.json b/package-lock.json
index 53665de..db8556f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,8 +13,10 @@
"@mantine/ds": "^7.1.3",
"@mantine/hooks": "^7.1.3",
"@tabler/icons-react": "^2.39.0",
+ "chart.js": "^4.4.0",
"next": "13.5.4",
"react": "^18",
+ "react-chartjs-2": "^5.2.0",
"react-dom": "^18"
},
"devDependencies": {
@@ -664,6 +666,11 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "node_modules/@kurkle/color": {
+ "version": "0.3.2",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/@kurkle/color/-/color-0.3.2.tgz",
+ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
+ },
"node_modules/@mantine/code-highlight": {
"version": "7.1.3",
"resolved": "https://mirrors.cloud.tencent.com/npm/@mantine/code-highlight/-/code-highlight-7.1.3.tgz",
@@ -1534,6 +1541,17 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chart.js": {
+ "version": "4.4.0",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/chart.js/-/chart.js-4.4.0.tgz",
+ "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==",
+ "dependencies": {
+ "@kurkle/color": "^0.3.0"
+ },
+ "engines": {
+ "pnpm": ">=7"
+ }
+ },
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://mirrors.cloud.tencent.com/npm/chokidar/-/chokidar-3.5.3.tgz",
@@ -4007,6 +4025,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-chartjs-2": {
+ "version": "5.2.0",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
+ "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
+ "peerDependencies": {
+ "chart.js": "^4.1.1",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/react-dom/-/react-dom-18.2.0.tgz",
@@ -5489,6 +5516,11 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "@kurkle/color": {
+ "version": "0.3.2",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/@kurkle/color/-/color-0.3.2.tgz",
+ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
+ },
"@mantine/code-highlight": {
"version": "7.1.3",
"resolved": "https://mirrors.cloud.tencent.com/npm/@mantine/code-highlight/-/code-highlight-7.1.3.tgz",
@@ -6072,6 +6104,14 @@
"supports-color": "^7.1.0"
}
},
+ "chart.js": {
+ "version": "4.4.0",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/chart.js/-/chart.js-4.4.0.tgz",
+ "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==",
+ "requires": {
+ "@kurkle/color": "^0.3.0"
+ }
+ },
"chokidar": {
"version": "3.5.3",
"resolved": "https://mirrors.cloud.tencent.com/npm/chokidar/-/chokidar-3.5.3.tgz",
@@ -7871,6 +7911,12 @@
"loose-envify": "^1.1.0"
}
},
+ "react-chartjs-2": {
+ "version": "5.2.0",
+ "resolved": "https://mirrors.cloud.tencent.com/npm/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
+ "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
+ "requires": {}
+ },
"react-dom": {
"version": "18.2.0",
"resolved": "https://mirrors.cloud.tencent.com/npm/react-dom/-/react-dom-18.2.0.tgz",
diff --git a/package.json b/package.json
index 7e54c78..e4b6969 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,10 @@
"@mantine/ds": "^7.1.3",
"@mantine/hooks": "^7.1.3",
"@tabler/icons-react": "^2.39.0",
+ "chart.js": "^4.4.0",
"next": "13.5.4",
"react": "^18",
+ "react-chartjs-2": "^5.2.0",
"react-dom": "^18"
},
"devDependencies": {
diff --git a/pages/index.tsx b/pages/index.tsx
index 006b2de..d6e3262 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import Head from 'next/head'
import { Inter } from 'next/font/google'
@@ -6,6 +8,7 @@ import { KVNamespace } from '@cloudflare/workers-types'
import config from '@/uptime.config'
import OverallStatus from '@/components/OverallStatus'
import Header from '@/components/Header'
+import MonitorList from '@/components/MonitorList'
export const runtime = 'experimental-edge'
const inter = Inter({ subsets: ['latin'] })
@@ -19,18 +22,10 @@ export default function Home({ state }: { state: MonitorState }) {
-
-
- {
- config.monitors.map(monitor => (
-
-
{monitor.name}
-
- ))
- }
- {JSON.stringify(state)}
+
+ {/* {JSON.stringify(state)}
*/}
>
)