diff --git a/src/components/QueryError.tsx b/src/components/QueryError.tsx new file mode 100644 index 0000000..530dab5 --- /dev/null +++ b/src/components/QueryError.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { Box, Button, Typography, useTheme } from '@mui/material'; +import { FONTS } from '../theme'; + +interface QueryErrorProps { + onRetry: () => void; + title?: string; +} + +export const QueryError: React.FC = ({ + onRetry, + title = 'Failed to load data', +}) => { + const theme = useTheme(); + return ( + + + {title} + + + + ); +}; diff --git a/src/components/dashboard/EventFeed.tsx b/src/components/dashboard/EventFeed.tsx index 72d10b8..61f1573 100644 --- a/src/components/dashboard/EventFeed.tsx +++ b/src/components/dashboard/EventFeed.tsx @@ -3,8 +3,10 @@ import { Link as RouterLink } from 'react-router-dom'; import { Box, Button, Chip, Stack, Typography, useTheme } from '@mui/material'; import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; import { useLatestEvents } from '../../api'; +import type { ContractEvent } from '../../api/models/Events'; import { FONTS } from '../../theme'; import CopyableAddress from '../CopyableAddress'; +import { QueryError } from '../QueryError'; import { EventFeedSkeleton } from './Skeletons'; const getEventColor = ( @@ -39,7 +41,7 @@ const getEventColor = ( const EventFeed: React.FC = () => { const theme = useTheme(); - const { data: events, isLoading } = useLatestEvents(); + const { data: events, isLoading, isError, refetch } = useLatestEvents(); const scrollRef = useRef(null); const [scrolled, setScrolled] = useState(false); @@ -52,9 +54,11 @@ const EventFeed: React.FC = () => { scrollRef.current?.scrollTo({ top: 0, behavior: 'smooth' }); }, []); - return isLoading || !events ? ( - - ) : ( + if (isLoading) return ; + if (isError) return refetch()} title="Failed to load events" />; + if (!events) return ; + + return ( { }} > - {events?.map((event) => ( + {events?.map((event: ContractEvent) => ( {