11"use client" ;
22
3- import { Card } from "chakra/card" ;
4- import { Heading } from "chakra/heading" ;
5- import { Text } from "chakra/text" ;
6- import { ChartAreaIcon , InfoIcon } from "lucide-react" ;
7- import { Spinner } from "@/components/ui/Spinner/Spinner" ;
3+ import { CircleAlertIcon } from "lucide-react" ;
4+ import { GenericLoadingPage } from "@/components/blocks/skeletons/GenericLoadingPage" ;
5+ import { Alert , AlertDescription , AlertTitle } from "@/components/ui/alert" ;
86import { UnderlineLink } from "@/components/ui/UnderlineLink" ;
97import {
108 type EngineInstance ,
@@ -15,19 +13,17 @@ import { ErrorRate } from "./ErrorRate";
1513import { Healthcheck } from "./Healthcheck" ;
1614import { StatusCodes } from "./StatusCodes" ;
1715
18- interface EngineStatusProps {
19- instance : EngineInstance ;
20- teamSlug : string ;
21- projectSlug : string ;
22- authToken : string ;
23- }
24-
25- export const EngineSystemMetrics : React . FC < EngineStatusProps > = ( {
16+ export function EngineSystemMetrics ( {
2617 instance,
2718 teamSlug,
2819 projectSlug,
2920 authToken,
30- } ) => {
21+ } : {
22+ instance : EngineInstance ;
23+ teamSlug : string ;
24+ projectSlug : string ;
25+ authToken : string ;
26+ } ) {
3127 const systemMetricsQuery = useEngineSystemMetrics (
3228 instance . id ,
3329 teamSlug ,
@@ -39,58 +35,54 @@ export const EngineSystemMetrics: React.FC<EngineStatusProps> = ({
3935 pollInterval : 10_000 ,
4036 } ) ;
4137
42- let systemMetricsPanel = < Spinner className = "h-4 w-4" /> ;
38+ let systemMetricsPanel = < GenericLoadingPage /> ;
4339 if ( ! systemMetricsQuery . data || systemMetricsQuery . isError ) {
4440 systemMetricsPanel = (
45- < Card p = { 8 } >
46- < div className = "flex flex-col gap-4" >
47- < div className = "flex flex-row items-center gap-2" >
48- < InfoIcon className = "size-4" />
49- < Heading size = "title.xs" >
50- System metrics are unavailable for self-hosted Engine.
51- </ Heading >
52- </ div >
53- < Text >
41+ < div >
42+ < h2 className = "text-2xl font-semibold tracking-tight mb-4" >
43+ System Metrics
44+ </ h2 >
45+
46+ < Alert variant = "warning" >
47+ < CircleAlertIcon className = "size-5" />
48+ < AlertTitle >
49+ System metrics are not available for self-hosted Engine
50+ </ AlertTitle >
51+ < AlertDescription className = "text-muted-foreground text-sm" >
5452 Upgrade to a{ " " }
5553 < UnderlineLink
56- color = "blue.500"
5754 href = { `/team/${ teamSlug } /${ projectSlug } /engine/dedicated/create` }
5855 rel = "noopener noreferrer"
5956 target = "_blank"
6057 >
6158 Engine instance managed by thirdweb
6259 </ UnderlineLink > { " " }
63- to view these metrics.
64- </ Text >
65- </ div >
66- </ Card >
60+ to view system metrics
61+ </ AlertDescription >
62+ </ Alert >
63+ </ div >
6764 ) ;
6865 } else {
6966 systemMetricsPanel = (
70- < Card p = { 16 } >
71- < div className = "flex flex-col gap-4" >
72- < div className = "-mb-2 flex flex-row items-center gap-2" >
73- < ChartAreaIcon className = "size-4" />
74- < Heading size = "title.md" > System Metrics</ Heading >
75- </ div >
67+ < div >
68+ < div className = "flex items-center gap-3 mb-4" >
69+ < h2 className = "text-2xl font-semibold tracking-tight" >
70+ System Metrics
71+ </ h2 >
72+ < Healthcheck instance = { instance } />
73+ </ div >
7674
77- < div className = "mt-10 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3" >
78- < Healthcheck instance = { instance } />
79- </ div >
75+ < div className = "space-y-8" >
8076 < StatusCodes
8177 datapoints = { systemMetricsQuery . data . result . statusCodes }
8278 />
8379 < ErrorRate datapoints = { systemMetricsQuery . data . result . errorRate } />
8480 </ div >
85- </ Card >
81+ </ div >
8682 ) ;
8783 }
8884
89- let queueMetricsPanel = (
90- < div className = "flex min-h-[200px] items-center justify-center rounded-lg border border-border" >
91- < Spinner className = "size-6" />
92- </ div >
93- ) ;
85+ let queueMetricsPanel = < GenericLoadingPage /> ;
9486
9587 if (
9688 ! queueMetricsQuery . isPending &&
@@ -108,43 +100,39 @@ export const EngineSystemMetrics: React.FC<EngineStatusProps> = ({
108100 const msToMine = queueMetricsQuery . data . result . latency ?. msToMine ;
109101
110102 queueMetricsPanel = (
111- < Card p = { 8 } >
112- < div className = "flex flex-col gap-6" >
113- < div className = "flex flex-row items-center gap-2" >
114- < Heading size = "title.md" > Queue Metrics</ Heading >
115- </ div >
103+ < div className = "bg-card p-4 rounded-lg border lg:p-6" >
104+ < h2 className = "text-lg tracking-tight font-semibold mb-3" >
105+ Queue Metrics
106+ </ h2 >
116107
117- < div className = "flex flex-col gap-6 lg:flex-row lg:gap-12" >
118- < div className = "flex-col gap-y-4" >
119- < h2 className = "font-semibold" > Queued</ h2 >
120- < p className = "text-muted-foreground" > { numQueued } </ p >
121- </ div >
122- < div className = "flex-col gap-y-4" >
123- < h2 className = "font-semibold" > Pending</ h2 >
124- < p className = "text-muted-foreground" > { numPending } </ p >
125- </ div >
108+ < div className = "space-y-2" >
109+ < MetricRow label = "Queued" value = { numQueued } />
110+ < MetricRow label = "Pending" value = { numPending } />
126111
127- { msToSend && (
128- < div className = "flex-col gap-y-4" >
129- < h2 className = "font-semibold" > Time to send</ h2 >
130- < p className = "text-muted-foreground" >
112+ { msToSend && (
113+ < MetricRow
114+ label = "Time to send"
115+ value = {
116+ < span >
131117 p50 { ( msToSend . p50 / 1000 ) . toFixed ( 2 ) } s, p90{ " " }
132118 { ( msToSend . p90 / 1000 ) . toFixed ( 2 ) } s
133- </ p >
134- </ div >
135- ) }
136- { msToMine && (
137- < div className = "flex-col gap-y-4" >
138- < h2 className = "font-semibold" > Time to mine</ h2 >
139- < p className = "text-muted-foreground" >
119+ </ span >
120+ }
121+ />
122+ ) }
123+ { msToMine && (
124+ < MetricRow
125+ label = "Time to mine"
126+ value = {
127+ < span >
140128 p50 { ( msToMine . p50 / 1000 ) . toFixed ( 2 ) } s, p90{ " " }
141129 { ( msToMine . p90 / 1000 ) . toFixed ( 2 ) } s
142- </ p >
143- </ div >
144- ) }
145- </ div >
130+ </ span >
131+ }
132+ />
133+ ) }
146134 </ div >
147- </ Card >
135+ </ div >
148136 ) ;
149137 }
150138
@@ -154,4 +142,19 @@ export const EngineSystemMetrics: React.FC<EngineStatusProps> = ({
154142 { queueMetricsPanel }
155143 </ div >
156144 ) ;
157- } ;
145+ }
146+
147+ function MetricRow ( {
148+ label,
149+ value,
150+ } : {
151+ label : string ;
152+ value : React . ReactNode ;
153+ } ) {
154+ return (
155+ < div className = "grid grid-cols-2 w-[400px]" >
156+ < h3 className = "text-sm font-medium" > { label } </ h3 >
157+ < p className = "text-sm text-foreground" > { value } </ p >
158+ </ div >
159+ ) ;
160+ }
0 commit comments