header responsive update, fix worker tcp read

pull/5/head
lyc8503 2023-10-28 01:38:21 +08:00
parent 7e694fd9b7
commit 4817fef547
7 changed files with 60 additions and 40 deletions

View File

@ -1,5 +1,6 @@
import { MonitorState, MonitorTarget } from "@/uptime.types";
import { Tooltip } from "@mantine/core";
import { Box, Tooltip } from "@mantine/core";
import { useEffect, useRef } from "react";
export default function DetailBar({ monitor, state }: { monitor: MonitorTarget, state: MonitorState }) {
@ -22,14 +23,24 @@ export default function DetailBar({ monitor, state }: { monitor: MonitorTarget,
uptimePercentBars.push(
<Tooltip key={i} label="Tooltip">
<div style={{ height: '20px', width: '0.8%', background: 'green', borderRadius: '2px', marginLeft: '0.155%', marginRight: '0.155%' }}/>
<div style={{ height: '20px', width: '7px', background: 'green', borderRadius: '2px', marginLeft: '1px', marginRight: '1px' }}/>
</Tooltip>
)
}
return (
<div style={{ display: 'flex', flexWrap: 'nowrap', marginTop: '10px', marginBottom: '5px' }}>
{uptimePercentBars}
</div>
<>
<Box style={{ display: 'flex', flexWrap: 'nowrap', marginTop: '10px', marginBottom: '5px' }} visibleFrom='540'>
{uptimePercentBars}
</Box>
{/* <Box style={{ display: 'flex', flexWrap: 'nowrap', marginTop: '10px', marginBottom: '5px' }} visibleFrom='270' hiddenFrom='540'>
{uptimePercentBars.slice(-60)}
</Box>
<Box style={{ display: 'flex', flexWrap: 'nowrap', marginTop: '10px', marginBottom: '5px' }} hiddenFrom='270'>
{uptimePercentBars.slice(-30)}
</Box> */}
</>
)
}

View File

@ -1,31 +1,23 @@
import { useState } from 'react';
import { Container, Group, Text } from '@mantine/core';
import classes from '@/styles/Header.module.css';
import config from '@/uptime.config';
const links = [
{ link: '/about', label: 'Features' },
{ link: '/pricing', label: 'Pricing' },
{ link: '/learn', label: 'Learn' },
{ link: '/community', label: 'Community' },
];
export default function Header() {
const [active, setActive] = useState(links[0].link);
const items = links.map((link) => (
<a
key={link.label}
href={link.link}
className={classes.link}
data-active={active === link.link || undefined}
onClick={(event) => {
event.preventDefault();
setActive(link.link);
}}
>
{link.label}
</a>
));
const linkToElement = (link: { label: string; link: string; highlight?: boolean; }) => {
return (
<a
key={link.label}
href={link.link}
target='_blank'
className={classes.link}
data-active={link.highlight}
>
{link.label}
</a>
)
}
return (
<header className={classes.header}>
@ -36,10 +28,16 @@ export default function Header() {
<Text size='xl' span fw={700} variant="gradient" gradient={{ from: 'blue', to: 'cyan', deg: 90 }}>UptimeFlare</Text>
</a>
</div>
<Group gap={5}>
{items}
<Group gap={5} visibleFrom='sm'>
{config.page.links.map(linkToElement)}
</Group>
<Group gap={5} hiddenFrom='sm'>
{config.page.links.filter(link => link.highlight).map(linkToElement)}
</Group>
</Container>
</header>
);
}
}

View File

@ -27,7 +27,7 @@ export default function MonitorDetail({ monitor, state }: { monitor: MonitorTarg
</>
)
const statusIcon = state.incident[monitor.id].slice(-1)[0].end === undefined ? <IconAlertCircle style={{ width: '1em', height: '1em', color: '#b91c1c' }} /> : <IconCircleCheck style={{ width: '1em', height: '1em', color: '#059669' }} />
const statusIcon = state.incident[monitor.id].slice(-1)[0].end === undefined ? <IconAlertCircle style={{ width: '1.25em', height: '1.25em', color: '#b91c1c' }} /> : <IconCircleCheck style={{ width: '1.25em', height: '1.25em', color: '#059669' }} />
let totalTime = Date.now() / 1000 - state.incident[monitor.id][0].start[0]
let downTime = 0
@ -42,7 +42,7 @@ export default function MonitorDetail({ monitor, state }: { monitor: MonitorTarg
return (
<>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Text mt='sm' style={{ display: 'inline-flex', alignItems: 'center' }}>{statusIcon} {monitor.name}</Text>
<Text mt='sm' fw={700} style={{ display: 'inline-flex', alignItems: 'center' }}>{statusIcon} {monitor.name}</Text>
<Text mt='sm' fw={700} style={{ display: 'inline', color: getColor(uptimePercent, true) }}>Overall: {uptimePercent}%</Text>
</div>

View File

@ -6,7 +6,7 @@ export default function MonitorList({ config, state }: { config: any, state: Mon
return (
<Center>
<Card shadow="sm" padding="lg" radius="md" ml="xl" mr="xl" mt="xl" withBorder style={{ width: '800px' }}>
<Card shadow="sm" padding="lg" radius="md" ml="xl" mr="xl" mt="xl" withBorder style={{ width: '865px' }}>
{config.monitors.map((monitor: MonitorTarget) => (
<div key={monitor.id}>
<Card.Section ml="xs" mr="xs">

View File

@ -7,7 +7,7 @@ import config from '@/uptime.config'
import OverallStatus from '@/components/OverallStatus'
import Header from '@/components/Header'
import MonitorList from '@/components/MonitorList'
import { Center, Text } from '@mantine/core'
import { Center, Divider, Text } from '@mantine/core'
export const runtime = 'experimental-edge'
const inter = Inter({ subsets: ['latin'] })
@ -39,6 +39,14 @@ export default function Home({ state }: { state: MonitorState }) {
</div>
)
}
<Divider mt='lg' />
<Center>
<Text size='xs' mt='xs' mb='xs'>
Open-source monitoring and status page powered by <a href='https://github.com/lyc8503/UptimeFlare' target='_blank'>Uptimeflare</a> and <a href='https://www.cloudflare.com/' target='_blank'>Cloudflare</a>, made with by <a href='https://github.com/lyc8503' target='_blank'>lyc8503</a>.
</Text>
</Center>
</main>
</>
)

View File

@ -4,7 +4,12 @@ const config = {
dateLocale: "zh-CN",
timezone: "Asia/Shanghai",
page: {
title: "lyc8503's Status Page"
title: "lyc8503's Status Page",
links: [
{ link: 'https://github.com/lyc8503', label: 'GitHub' },
{ link: 'https://blog.lyc8503.site/', label: 'Blog' },
{ link: 'mailto:me@lyc8503.site', label: 'Email Me', highlight: true }
]
},
callback: async (statusChangeMsg: string) => {
await fetch('https://server.lyc8503.site/wepush?key=wepushkey&msg=' + statusChangeMsg)

View File

@ -24,14 +24,12 @@ async function getStatus(monitor: MonitorTarget): Promise<{ ping: number; up: bo
const [hostname, port] = monitor.target.split(":")
// Write "PING\n"
const socket = connect({ hostname: hostname, port: Number(port) })
const reader = socket.readable.getReader()
const socket = connect({ hostname: hostname, port: Number(port) })
const writer = socket.writable.getWriter()
await writer.write(new TextEncoder().encode("PING\n"))
await reader.read() // This now works as a workaround for https://github.com/cloudflare/workerd/issues/1305
await socket.close()
// Can't do this: await socket.close()
// TODO: should throw an error here but it doesn't?
// https://github.com/cloudflare/workerd/issues/1305
await socket.closed
console.log(`${monitor.name} connected to ${monitor.target}`)