Add interactive roadmap error handling and loading

pull/939/head
Kamran Ahmed 3 years ago
parent 8259a83921
commit 102cd8885c
  1. 26
      components/roadmap/roadmap-error.tsx
  2. 20
      components/roadmap/roadmap-loader.tsx
  3. 41
      pages/[roadmap]/interactive.tsx

@ -0,0 +1,26 @@
import { RoadmapType } from '../../lib/roadmap';
import { Container, Heading, Link, Text } from '@chakra-ui/react';
import siteConfig from '../../content/site.json';
type RoadmapProps = {
roadmap: RoadmapType;
};
export function RoadmapError(props: RoadmapProps) {
const { roadmap } = props;
return (
<Container
bg={'red.600'}
maxW={'container.md'}
position="relative"
mt="50px"
p='20px'
rounded='5px'
color='white'
>
<Heading mb='4px' size='md'>Oops! There's an error</Heading>
<Text>Try refreshing or <Link target='_blank' fontWeight={700} textDecoration={'underline'} fontSize='14px' href={siteConfig.url.issue}>report a bug</Link> and use the <Link fontWeight={700} textDecoration={'underline'} href={`/${roadmap.id}`}>non-interactive version</Link></Text>
</Container>
);
}

@ -0,0 +1,20 @@
import { Container, Spinner } from '@chakra-ui/react';
export function RoadmapLoader() {
return (
<Container
maxW={'container.md'}
position="relative"
mt="60px"
textAlign="center"
>
<Spinner
thickness="7px"
speed="0.65s"
emptyColor="gray.200"
color="gray.500"
size="xl"
/>
</Container>
);
}

@ -1,52 +1,33 @@
import { Box, Container, Flex, Heading, Spinner, Text } from '@chakra-ui/react'; import { useFetch } from 'use-http';
import { useEffect, useRef, useState } from 'react';
import { Box, Container } from '@chakra-ui/react';
import { GlobalHeader } from '../../components/global-header'; import { GlobalHeader } from '../../components/global-header';
import { OpensourceBanner } from '../../components/opensource-banner'; import { OpensourceBanner } from '../../components/opensource-banner';
import { UpdatesBanner } from '../../components/updates-banner'; import { UpdatesBanner } from '../../components/updates-banner';
import { Footer } from '../../components/footer'; import { Footer } from '../../components/footer';
import { getAllRoadmaps, getRoadmapById, RoadmapType } from '../../lib/roadmap'; import { getAllRoadmaps, getRoadmapById, RoadmapType } from '../../lib/roadmap';
import Helmet from '../../components/helmet'; import Helmet from '../../components/helmet';
import { useEffect, useRef, useState } from 'react';
import { wireframeJSONToSVG } from '../../lib/renderer'; import { wireframeJSONToSVG } from '../../lib/renderer';
import { RoadmapPageHeader } from '../../components/roadmap/roadmap-page-header'; import { RoadmapPageHeader } from '../../components/roadmap/roadmap-page-header';
import { ContentDrawer } from '../../components/roadmap/content-drawer'; import { ContentDrawer } from '../../components/roadmap/content-drawer';
import { useFetch } from 'use-http'; import { RoadmapError } from '../../components/roadmap/roadmap-error';
import { Simulate } from 'react-dom/test-utils'; import { RoadmapLoader } from '../../components/roadmap/roadmap-loader';
import load = Simulate.load;
type RoadmapProps = { type RoadmapProps = {
roadmap: RoadmapType; roadmap: RoadmapType;
}; };
function RoadmapLoader() {
return (
<Container
maxW={'container.md'}
position="relative"
mt="60px"
textAlign="center"
>
<Spinner
thickness="7px"
speed="0.65s"
emptyColor="gray.200"
color="gray.500"
size="xl"
/>
</Container>
);
}
function RoadmapRenderer(props: RoadmapProps) { function RoadmapRenderer(props: RoadmapProps) {
const { roadmap } = props; const { roadmap } = props;
const { loading: isLoading, error, get } = useFetch(); const { loading: isLoading, error: hasErrorLoading, get } = useFetch();
const roadmapRef = useRef(null); const roadmapRef = useRef(null);
const [isRendering, setIsRendering] = useState(false); const [isRendering, setIsRendering] = useState(false);
const [roadmapJson, setRoadmapJson] = useState(null); const [roadmapJson, setRoadmapJson] = useState(null);
const [groupId, setGroupId] = useState(''); const [groupId, setGroupId] = useState('');
const [hasError, setHasError] = useState(false); const [hasErrorRendering, setHasErrorRendering] = useState(false);
useEffect(() => { useEffect(() => {
get(`/project/${roadmap.id}.json`) get(`/project/${roadmap.id}.json`)
@ -55,7 +36,7 @@ function RoadmapRenderer(props: RoadmapProps) {
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.error(err);
setHasError(true); setHasErrorRendering(true);
}); });
}, [get, roadmap.id]); }, [get, roadmap.id]);
@ -113,13 +94,17 @@ function RoadmapRenderer(props: RoadmapProps) {
container.appendChild(svgElement); container.appendChild(svgElement);
}) })
.catch((err) => { .catch((err) => {
setHasError(true); setHasErrorRendering(true);
}) })
.finally(() => { .finally(() => {
setIsRendering(false); setIsRendering(false);
}); });
}, [roadmapJson]); }, [roadmapJson]);
if (hasErrorLoading || hasErrorRendering) {
return <RoadmapError roadmap={roadmap} />
}
return ( return (
<Container maxW={'container.lg'} position="relative"> <Container maxW={'container.lg'} position="relative">
{(isLoading || isRendering) && <RoadmapLoader />} {(isLoading || isRendering) && <RoadmapLoader />}

Loading…
Cancel
Save