header responsive update, fix worker tcp read
parent
7e694fd9b7
commit
4817fef547
|
|
@ -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> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -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,9 +28,15 @@ 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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -25,13 +25,11 @@ async function getStatus(monitor: MonitorTarget): Promise<{ ping: number; up: bo
|
|||
|
||||
// Write "PING\n"
|
||||
const socket = connect({ hostname: hostname, port: Number(port) })
|
||||
const reader = socket.readable.getReader()
|
||||
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}`)
|
||||
|
|
|
|||
Loading…
Reference in New Issue