@@ -30,12 +30,15 @@ import {
3030 CircleCheckBig ,
3131 CircleAlert ,
3232 CloudOff ,
33+ SearchX ,
3334} from 'lucide-react' ;
3435import { Page } from '@/components/layout/Page' ;
3536import { useQuery } from '@tanstack/react-query' ;
3637import { EndpointService } from '@/api/services/endpoint.service' ;
3738import { formatDistanceToNow } from 'date-fns' ;
3839import type { RawCheck , Outage } from '@/api/types' ;
40+ import { Skeleton } from '@/components/ui/skeleton' ;
41+ import { EmptyState } from '@/components/ui/empty-state' ;
3942
4043function getStatusColor ( status : string ) {
4144 switch ( status . toLowerCase ( ) ) {
@@ -218,10 +221,7 @@ function OutagesList({ outages }: OutagesListProps) {
218221
219222export default function EndpointDetail ( ) {
220223 const { id } = useParams < { id : string } > ( ) ;
221-
222- if ( ! id ) {
223- return < Navigate to = '/' replace /> ;
224- }
224+ if ( ! id ) return < Navigate to = '/' replace /> ;
225225
226226 const {
227227 data : endpointDetail ,
@@ -233,26 +233,66 @@ export default function EndpointDetail() {
233233 refetchInterval : 10000 , // Refresh every 10 seconds
234234 } ) ;
235235
236- if ( ! endpointDetail && ! isLoading && ! error ) {
236+ const backButton = (
237+ < RouterLink to = '/' >
238+ < Button variant = 'ghost' size = 'sm' h = '32px' mt = { - 4 } mr = { 7 } >
239+ < ArrowLeft size = { 16 } />
240+ Back to Dashboard
241+ </ Button >
242+ </ RouterLink >
243+ ) ;
244+
245+ if ( isLoading ) {
237246 return (
238- < Page
239- title = 'Endpoint Not Found'
240- description = { `The endpoint with ID "${ id } " was not found` }
241- actions = {
242- < RouterLink to = '/' >
243- < Button variant = 'ghost' size = 'sm' >
244- < ArrowLeft size = { 16 } />
245- Back to Dashboard
246- </ Button >
247- </ RouterLink >
248- }
249- >
250- < Text > The endpoint with ID "{ id } " was not found.</ Text >
247+ < Page title = 'Loading endpoint...' actions = { backButton } >
248+ < VStack gap = { 4 } align = 'stretch' >
249+ < Skeleton w = 'full' minH = '150px' />
250+ < Heading size = 'md' > Recent Performance</ Heading >
251+ < StatGroup w = 'full' gap = { 2 } >
252+ { Array ( 4 )
253+ . fill ( 0 )
254+ . map ( ( _ , i ) => (
255+ < Stat . Root key = { i } borderWidth = '1px' p = '4' rounded = 'md' h = 'full' w = '25%' >
256+ < HStack w = 'full' gap = { 3 } >
257+ < Skeleton boxSize = '12' borderRadius = 'full' />
258+ < VStack align = 'start' gap = { 1 } w = 'full' >
259+ < Skeleton minH = '12px' w = '60px' />
260+ < Skeleton minH = '16px' w = '80px' />
261+ < Skeleton minH = '12px' w = '100px' />
262+ </ VStack >
263+ </ HStack >
264+ </ Stat . Root >
265+ ) ) }
266+ </ StatGroup >
267+ < SimpleGrid columns = { { base : 1 , lg : 2 } } gap = { 2 } >
268+ < Skeleton w = 'full' minH = '50vh' />
269+ < Skeleton w = 'full' minH = '50vh' />
270+ </ SimpleGrid >
271+ </ VStack >
251272 </ Page >
252273 ) ;
253274 }
254275
255- if ( ! endpointDetail ) return null ;
276+ if ( error || ! endpointDetail ) {
277+ return (
278+ < Page title = 'Endpoint Not Found' actions = { backButton } >
279+ < EmptyState
280+ icon = { < SearchX /> }
281+ title = 'Endpoint Not Found'
282+ description = {
283+ < >
284+ < Text > The endpoint with ID "{ id } " does not exist.</ Text >
285+ { error && (
286+ < Text color = 'red.500' mt = { 2 } fontSize = 'sm' >
287+ Error: { ( error as Error ) . message }
288+ </ Text >
289+ ) }
290+ </ >
291+ }
292+ />
293+ </ Page >
294+ ) ;
295+ }
256296
257297 const { endpoint, recent, outages } = endpointDetail ;
258298
@@ -271,15 +311,6 @@ export default function EndpointDetail() {
271311 const latestCheck = recent . length > 0 ? recent [ 0 ] : null ;
272312 const currentStatus = latestCheck ?. status || 'unknown' ;
273313
274- const backButton = (
275- < RouterLink to = '/' >
276- < Button variant = 'ghost' size = 'sm' h = '32px' mt = { - 4 } mr = { 7 } >
277- < ArrowLeft size = { 16 } />
278- Back to Dashboard
279- </ Button >
280- </ RouterLink >
281- ) ;
282-
283314 return (
284315 < Page
285316 title = { endpoint . name }
@@ -506,9 +537,9 @@ export default function EndpointDetail() {
506537 < Card . Header p = { 4 } pb = { 0 } >
507538 < HStack justify = 'space-between' align = 'center' >
508539 < Heading size = 'md' > Recent Checks</ Heading >
509- < Text color = 'blue' fontSize = { 'xs ' } >
540+ < Badge fontSize = { 'xs' } colorPalette = { 'blue ' } >
510541 Last 60 minutes
511- </ Text >
542+ </ Badge >
512543 </ HStack >
513544 </ Card . Header >
514545 < Card . Body p = { 4 } >
0 commit comments