dashboard.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { useList } from "@refinedev/core";
  2. import { Card, Col, Row, Statistic, Progress, Alert, Table, Typography } from "antd";
  3. import {
  4. AreaChart,
  5. Area,
  6. XAxis,
  7. YAxis,
  8. CartesianGrid,
  9. Tooltip,
  10. ResponsiveContainer
  11. } from "recharts";
  12. import {
  13. CheckCircleOutlined,
  14. WarningOutlined,
  15. ArrowUpOutlined,
  16. ArrowDownOutlined
  17. } from '@ant-design/icons';
  18. const { Title } = Typography;
  19. // Mock data for the chart
  20. const performanceData = [
  21. { name: '00:00', cpu: 40, memory: 55, network: 20 },
  22. { name: '03:00', cpu: 30, memory: 58, network: 28 },
  23. { name: '06:00', cpu: 20, memory: 40, network: 20 },
  24. { name: '09:00', cpu: 27, memory: 60, network: 40 },
  25. { name: '12:00', cpu: 90, memory: 76, network: 60 },
  26. { name: '15:00', cpu: 75, memory: 65, network: 50 },
  27. { name: '18:00', cpu: 80, memory: 70, network: 45 },
  28. { name: '21:00', cpu: 65, memory: 60, network: 30 },
  29. ];
  30. // Mock data for alerts
  31. const alertsData = [
  32. { id: 1, level: 'critical', message: 'Server CPU usage exceeds 90%', timestamp: '2025-05-08T12:30:00', status: 'active' },
  33. { id: 2, level: 'warning', message: 'Database memory utilization above 75%', timestamp: '2025-05-08T11:15:00', status: 'active' },
  34. { id: 3, level: 'info', message: 'Client deployment auto-scaled to 3 instances', timestamp: '2025-05-08T09:45:00', status: 'resolved' },
  35. { id: 4, level: 'warning', message: 'Network latency spiked to 250ms', timestamp: '2025-05-08T08:20:00', status: 'resolved' },
  36. ];
  37. export const MonitoringDashboard = () => {
  38. const { data: deploymentsData } = useList({
  39. resource: "deployments",
  40. });
  41. // Calculate some stats from deployments data
  42. const activeDeployments = deploymentsData?.data?.filter(item => item.status === "active").length || 0;
  43. const totalDeployments = deploymentsData?.data?.length || 0;
  44. const healthyDeployments = deploymentsData?.data?.filter(item => item.healthStatus === "healthy").length || 0;
  45. return (
  46. <>
  47. <Title level={4}>Infrastructure Monitoring</Title>
  48. <Row gutter={16} style={{ marginBottom: 24 }}>
  49. <Col span={6}>
  50. <Card>
  51. <Statistic
  52. title="Active Deployments"
  53. value={activeDeployments}
  54. precision={0}
  55. valueStyle={{ color: '#3f8600' }}
  56. prefix={<CheckCircleOutlined />}
  57. />
  58. <div style={{ marginTop: 10 }}>
  59. <Progress percent={totalDeployments > 0 ? Math.round((activeDeployments / totalDeployments) * 100) : 0} size="small" />
  60. </div>
  61. </Card>
  62. </Col>
  63. <Col span={6}>
  64. <Card>
  65. <Statistic
  66. title="Health Status"
  67. value={`${healthyDeployments}/${totalDeployments}`}
  68. valueStyle={{ color: healthyDeployments === totalDeployments ? '#3f8600' : '#faad14' }}
  69. prefix={healthyDeployments === totalDeployments ? <CheckCircleOutlined /> : <WarningOutlined />}
  70. suffix="deployments healthy"
  71. />
  72. <div style={{ marginTop: 10 }}>
  73. <Progress percent={totalDeployments > 0 ? Math.round((healthyDeployments / totalDeployments) * 100) : 0} size="small" status={healthyDeployments === totalDeployments ? "success" : "exception"} />
  74. </div>
  75. </Card>
  76. </Col>
  77. <Col span={6}>
  78. <Card>
  79. <Statistic
  80. title="Average CPU Usage"
  81. value={68}
  82. precision={0}
  83. valueStyle={{ color: '#1890ff' }}
  84. suffix="%"
  85. />
  86. <div style={{ marginTop: 10 }}>
  87. <Progress percent={68} size="small" status={68 > 80 ? "exception" : "active"} />
  88. </div>
  89. </Card>
  90. </Col>
  91. <Col span={6}>
  92. <Card>
  93. <Statistic
  94. title="Average Memory Usage"
  95. value={72}
  96. precision={0}
  97. valueStyle={{ color: '#1890ff' }}
  98. suffix="%"
  99. />
  100. <div style={{ marginTop: 10 }}>
  101. <Progress percent={72} size="small" status={72 > 80 ? "exception" : "active"} />
  102. </div>
  103. </Card>
  104. </Col>
  105. </Row>
  106. <Row gutter={16} style={{ marginBottom: 24 }}>
  107. <Col span={16}>
  108. <Card title="System Performance">
  109. <ResponsiveContainer width="100%" height={300}>
  110. <AreaChart
  111. data={performanceData}
  112. margin={{ top: 10, right: 30, left: 0, bottom: 0 }}
  113. >
  114. <CartesianGrid strokeDasharray="3 3" />
  115. <XAxis dataKey="name" />
  116. <YAxis />
  117. <Tooltip />
  118. <Area type="monotone" dataKey="cpu" stackId="1" stroke="#8884d8" fill="#8884d8" name="CPU %" />
  119. <Area type="monotone" dataKey="memory" stackId="2" stroke="#82ca9d" fill="#82ca9d" name="Memory %" />
  120. <Area type="monotone" dataKey="network" stackId="3" stroke="#ffc658" fill="#ffc658" name="Network MB/s" />
  121. </AreaChart>
  122. </ResponsiveContainer>
  123. </Card>
  124. </Col>
  125. <Col span={8}>
  126. <Card title="Active Alerts" style={{ height: '100%' }}>
  127. {alertsData
  128. .filter(alert => alert.status === 'active')
  129. .map(alert => (
  130. <Alert
  131. key={alert.id}
  132. message={alert.message}
  133. type={alert.level === 'critical' ? 'error' : alert.level === 'warning' ? 'warning' : 'info'}
  134. showIcon
  135. style={{ marginBottom: 10 }}
  136. />
  137. ))}
  138. </Card>
  139. </Col>
  140. </Row>
  141. <Row>
  142. <Col span={24}>
  143. <Card title="Recent System Events">
  144. <Table
  145. dataSource={alertsData}
  146. pagination={{ pageSize: 5 }}
  147. rowKey="id"
  148. columns={[
  149. { title: 'Level', dataIndex: 'level', key: 'level',
  150. render: (text) => {
  151. const color = text === 'critical' ? 'red' : text === 'warning' ? 'orange' : 'blue';
  152. return <span style={{ color }}>{text.toUpperCase()}</span>;
  153. }
  154. },
  155. { title: 'Message', dataIndex: 'message', key: 'message' },
  156. { title: 'Timestamp', dataIndex: 'timestamp', key: 'timestamp' },
  157. { title: 'Status', dataIndex: 'status', key: 'status',
  158. render: (text) => {
  159. return text === 'active' ?
  160. <span style={{ color: 'red' }}>ACTIVE</span> :
  161. <span style={{ color: 'green' }}>RESOLVED</span>;
  162. }
  163. }
  164. ]}
  165. />
  166. </Card>
  167. </Col>
  168. </Row>
  169. </>
  170. );
  171. };