mirror of https://github.com/lukechilds/docs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.8 KiB
102 lines
2.8 KiB
import React from 'react';
|
|
import useSWR from 'swr';
|
|
import { Box, Flex, space, color, BoxProps } from '@stacks/ui';
|
|
import { border, transition } from '@common/utils';
|
|
import { Link } from '@components/mdx';
|
|
import { LinkProps, Text } from '@components/typography';
|
|
import { Spinner } from '@stacks/ui';
|
|
import { CircleCheck } from '@components/icons/circle-check';
|
|
import { AlertCircleIcon } from '@components/icons/alert-circle';
|
|
import { STATUS_CHECKER_URL } from '@common/constants';
|
|
import { css } from '@stacks/ui-core';
|
|
import { getCapsizeStyles } from '@components/mdx/typography';
|
|
|
|
const fetcher = url => fetch(url.replace(navigator.language, '')).then(r => r.json());
|
|
|
|
type Status = 'online' | 'slow' | 'degraded' | 'loading' | undefined;
|
|
|
|
const getColor = (status: Status) => {
|
|
switch (status) {
|
|
case 'degraded':
|
|
return 'feedback-error';
|
|
case 'online':
|
|
return 'feedback-success';
|
|
case 'slow':
|
|
return 'feedback-alert';
|
|
}
|
|
};
|
|
|
|
const StatusWords: React.FC<BoxProps & { status?: Status }> = ({ status, ...rest }) => (
|
|
<>
|
|
<Box as="span">:</Box>
|
|
<Box as="span" color={color(getColor(status))}>{` ${status}`}</Box>
|
|
</>
|
|
);
|
|
|
|
const getStatus = (data: number): Status | 'loading' => {
|
|
switch (data) {
|
|
case 0:
|
|
return 'online';
|
|
case 1:
|
|
return 'slow';
|
|
case 2:
|
|
return 'degraded';
|
|
default:
|
|
return 'loading';
|
|
}
|
|
};
|
|
|
|
export const StatusCheck: React.FC<LinkProps> = props => {
|
|
const { data, error } = useSWR(`/api/status`, fetcher);
|
|
|
|
const status = getStatus(data);
|
|
|
|
const critical = error || status === 'degraded';
|
|
const warn = status === 'slow';
|
|
|
|
return (
|
|
<Link
|
|
href={STATUS_CHECKER_URL}
|
|
target="_blank"
|
|
textDecoration="none"
|
|
border={border()}
|
|
borderRadius="6px"
|
|
px={space('base-tight')}
|
|
py={space('tight')}
|
|
color={color('text-caption')}
|
|
_hover={{ cursor: 'pointer', bg: color('bg-alt') }}
|
|
opacity={data || error ? 1 : 0}
|
|
transition={transition()}
|
|
{...props}
|
|
>
|
|
<Flex alignItems="center">
|
|
<Box mr={space('tight')}>
|
|
{!data && !error ? (
|
|
<Box
|
|
style={{
|
|
display: 'grid',
|
|
placeItems: 'center',
|
|
}}
|
|
size="24px"
|
|
>
|
|
<Spinner color={color('accent')} speed="1s" thickness="2px" size="sm" />
|
|
</Box>
|
|
) : critical || warn ? (
|
|
<AlertCircleIcon color={color(getColor(status))} size="24px" />
|
|
) : (
|
|
<CircleCheck size="24px" color={color('feedback-success')} />
|
|
)}
|
|
</Box>
|
|
<Text
|
|
{...{
|
|
color: 'currentColor',
|
|
...getCapsizeStyles(14, 24),
|
|
}}
|
|
>
|
|
Stacks 2.0 testnet status
|
|
<StatusWords status={status} />
|
|
</Text>
|
|
</Flex>
|
|
</Link>
|
|
);
|
|
};
|
|
|