lookingglass/hyperglass/ui/components/results/header.tsx
2024-11-15 18:40:53 +00:00

68 lines
1.9 KiB
TypeScript

import { AccordionIcon, Box, HStack, Spinner, Text, Tooltip } from '@chakra-ui/react';
import { useMemo } from 'react';
import { useConfig } from '~/context';
import { DynamicIcon } from '~/elements';
import { useOpposingColor, useStrf } from '~/hooks';
import type { ErrorLevels } from '~/types';
interface ResultHeaderProps {
title: string;
loading: boolean;
isError?: boolean;
errorMsg: string;
errorLevel: ErrorLevels;
runtime: number;
}
const runtimeText = (runtime: number, text: string): string => {
let unit = 'seconds';
if (runtime === 1) {
unit = 'second';
}
return `${text} ${unit}`;
};
export const ResultHeader = (props: ResultHeaderProps): JSX.Element => {
const { title, loading, isError, errorMsg, errorLevel, runtime } = props;
const status = 'primary.500';
const warning = `${errorLevel}.500`;
const defaultStatus = 'success.500';
const { web } = useConfig();
const strF = useStrf();
const text = strF(web.text.completeTime, { seconds: runtime });
const label = useMemo(() => runtimeText(runtime, text), [runtime, text]);
const color = useOpposingColor(isError ? warning : defaultStatus);
return (
<HStack alignItems="center" w="100%">
<Tooltip
hasArrow
placement="top"
isDisabled={loading}
label={isError ? errorMsg : label}
bg={isError ? warning : defaultStatus}
color={color}
>
<Box boxSize={6}>
{loading ? (
<Spinner size="sm" mr={4} color={status} />
) : (
<DynamicIcon
icon={isError ? { bi: 'BiError' } : { fa: 'FaCheckCircle' }}
color={isError ? warning : defaultStatus}
mr={4}
boxSize="100%"
/>
)}
</Box>
</Tooltip>
<Text fontSize="lg">{title}</Text>
<AccordionIcon ml="auto" />
</HStack>
);
};