Skip to content

Commit 8930d05

Browse files
committed
feat: enhance node card with xray uptime and improved layout
- Add xray uptime display with CPU icon - Improve node card layout using Stack and Group components - Update backend contract to version 0.2.7 - Reorganize traffic and uptime information for better readability
1 parent 53736a7 commit 8930d05

File tree

6 files changed

+90
-52
lines changed

6 files changed

+90
-52
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@mantine/nprogress": "^7.17.1",
4646
"@monaco-editor/react": "^4.7.0",
4747
"@paralleldrive/cuid2": "2.2.2",
48-
"@remnawave/backend-contract": "0.2.6",
48+
"@remnawave/backend-contract": "0.2.7",
4949
"@stablelib/base64": "^2.0.1",
5050
"@stablelib/x25519": "^2.0.1",
5151
"@tabler/icons-react": "^3.31.0",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* eslint-disable no-nested-ternary */
2+
/* eslint-disable indent */
3+
import dayjs from 'dayjs'
4+
5+
export function getXrayUptimeUtil(uptimeInSeconds: string): string {
6+
const totalSeconds = parseInt(uptimeInSeconds, 10)
7+
8+
const duration = dayjs.duration(totalSeconds, 'seconds')
9+
10+
return duration.humanize(false)
11+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './get-xray-uptime.util'

src/shared/utils/time-utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export * from './get-expiration-text/get-expiration-text.util'
1414
export * from './get-node-reset-days/get-node-reset-days.util'
1515
export * from './get-time-ago/get-time-ago.util'
1616
export * from './get-user-timezone/get-user-timezone.util'
17+
export * from './get-xray-uptime/get-xray-uptime.util'
1718
export * from './s-to-ms/s-to-ms.util'

src/widgets/dashboard/nodes/node-card/node-card.widget.tsx

Lines changed: 72 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { PiArrowsCounterClockwise, PiDotsSixVertical, PiUsersDuotone } from 'react-icons/pi'
2-
import { Badge, Box, Group, Paper, Progress, Text } from '@mantine/core'
1+
import { PiArrowsCounterClockwise, PiCpu, PiDotsSixVertical, PiUsersDuotone } from 'react-icons/pi'
2+
import { Badge, Box, Group, Paper, Progress, Stack, Text } from '@mantine/core'
33
import { notifications } from '@mantine/notifications'
44
import ReactCountryFlag from 'react-country-flag'
55
import { useTranslation } from 'react-i18next'
@@ -9,8 +9,8 @@ import ColorHash from 'color-hash'
99
import { useState } from 'react'
1010
import clsx from 'clsx'
1111

12+
import { getNodeResetDaysUtil, getXrayUptimeUtil } from '@shared/utils/time-utils'
1213
import { useNodesStoreActions } from '@entities/dashboard/nodes'
13-
import { getNodeResetDaysUtil } from '@shared/utils/time-utils'
1414
import { prettyBytesToAnyUtil } from '@shared/utils/bytes'
1515

1616
import { NodeStatusBadgeWidget } from '../node-status-badge'
@@ -95,7 +95,12 @@ export function NodeCardWidget(props: IProps) {
9595
{node.usersOnline}
9696
</Badge>
9797

98-
<Paper miw={'30ch'}>
98+
<Paper
99+
miw={{
100+
base: '15ch',
101+
sm: '30ch'
102+
}}
103+
>
99104
<Badge
100105
autoContrast
101106
color={ch.hex(node.uuid)}
@@ -124,58 +129,78 @@ export function NodeCardWidget(props: IProps) {
124129
</Paper>
125130

126131
<Paper miw={'22ch'}>
127-
<Text
128-
className={classes.hostInfoLabel}
129-
maw={'22ch'}
130-
miw={'22ch'}
131-
onClick={handleCopy}
132-
style={{ cursor: 'copy' }}
133-
truncate="end"
134-
>
135-
{node.address}
136-
{node.port ? `:${node.port}` : ''}
137-
</Text>
132+
<Stack align="stretch" gap="xs">
133+
<Text
134+
className={classes.hostInfoLabel}
135+
maw={'22ch'}
136+
miw={'22ch'}
137+
onClick={handleCopy}
138+
style={{ cursor: 'copy' }}
139+
truncate="end"
140+
>
141+
{node.address}
142+
{node.port ? `:${node.port}` : ''}
143+
</Text>
144+
145+
{node.xrayUptime !== '0' && (
146+
<Badge
147+
color="gray"
148+
leftSection={<PiCpu size={18} />}
149+
maw={'20ch'}
150+
radius="md"
151+
size="lg"
152+
style={{ cursor: 'pointer' }}
153+
variant="outline"
154+
>
155+
{getXrayUptimeUtil(node.xrayUptime)}
156+
</Badge>
157+
)}
158+
</Stack>
138159
</Paper>
139160

140-
<Badge
141-
autoContrast
142-
color={'gray'}
143-
ff={'monospace'}
144-
maw={'40ch'}
145-
miw={'25ch'}
146-
radius="md"
147-
size="lg"
148-
style={{ cursor: 'pointer' }}
149-
variant="outline"
150-
>
151-
{`${prettyUsedData} / ${maxData}`}
152-
</Badge>
153-
154-
{percentage >= 0 && node.isTrafficTrackingActive && (
155-
<Progress
156-
color={percentage > 95 ? 'red.9' : 'teal.9'}
157-
maw={'30ch'}
158-
radius="md"
159-
size="25"
160-
striped
161-
value={percentage}
162-
w={'10ch'}
163-
/>
164-
)}
165-
166-
{node.isTrafficTrackingActive && (
161+
<Stack align="stretch" gap="xs">
167162
<Badge
168-
color="gray"
169-
leftSection={<PiArrowsCounterClockwise size={18} />}
170-
maw={'20ch'}
163+
autoContrast
164+
color={'gray'}
165+
ff={'monospace'}
166+
maw={'40ch'}
167+
miw={'25ch'}
171168
radius="md"
172169
size="lg"
173170
style={{ cursor: 'pointer' }}
174171
variant="outline"
175172
>
176-
{getNodeResetDaysUtil(node.trafficResetDay ?? 1)}
173+
{`${prettyUsedData} / ${maxData}`}
177174
</Badge>
178-
)}
175+
176+
{node.isTrafficTrackingActive && (
177+
<Group>
178+
{percentage >= 0 && (
179+
<Progress
180+
color={percentage > 95 ? 'red.9' : 'teal.9'}
181+
maw={'30ch'}
182+
radius="md"
183+
size="25"
184+
striped
185+
value={percentage}
186+
w={'10ch'}
187+
/>
188+
)}
189+
190+
<Badge
191+
color="gray"
192+
leftSection={<PiArrowsCounterClockwise size={18} />}
193+
maw={'20ch'}
194+
radius="md"
195+
size="lg"
196+
style={{ cursor: 'pointer' }}
197+
variant="outline"
198+
>
199+
{getNodeResetDaysUtil(node.trafficResetDay ?? 1)}
200+
</Badge>
201+
</Group>
202+
)}
203+
</Stack>
179204
</Group>
180205
</Box>
181206
</Box>

0 commit comments

Comments
 (0)