Add Tippy.js for tooltips in UptimeStatusIsland component and update styles

- Integrated Tippy.js for enhanced tooltip functionality in the UptimeStatusIsland component, providing detailed heartbeat information on hover.
- Added custom styles for Tippy.js tooltips to support light and dark themes.
- Updated package.json and package-lock.json to include @tippyjs/react and its dependencies.
This commit is contained in:
2025-06-11 21:12:20 +02:00
parent ed10a2b65c
commit 9b0c7a66a0
4 changed files with 100 additions and 11 deletions

View File

@@ -98,3 +98,21 @@
.dd *:first-child {
margin-top: 0;
}
/* Custom Tippy.js theme for light/dark mode */
.tippy-box[data-theme~='devnet'] {
background-color: #fff;
color: #222;
border-radius: 12px;
box-shadow: 0 4px 24px rgba(0,0,0,0.10);
font-size: 1rem;
padding: 0.75rem 1rem;
}
.dark .tippy-box[data-theme~='devnet'] {
background-color: #23272f;
color: #f3f4f6;
box-shadow: 0 4px 24px rgba(0,0,0,0.40);
}
.tippy-box[data-theme~='devnet'] .tippy-arrow {
color: inherit;
}

View File

@@ -1,6 +1,8 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import { FiAward, FiPercent, FiActivity } from 'react-icons/fi';
import { FiAward, FiPercent, FiActivity, FiCheckCircle, FiClock, FiGlobe, FiLock } from 'react-icons/fi';
import { DateTime } from 'luxon';
import Tippy from '@tippyjs/react';
import 'tippy.js/dist/tippy.css';
function getStatusColor(validCert) {
if (validCert === false) return 'bg-red-600';
@@ -55,6 +57,39 @@ function formatLocalTime(rawTime, zone = 'utc') {
: 'Invalid DateTime';
}
function HeartbeatPopup({ hb, userZone, monitor }) {
const localTime = hb ? formatLocalTime(hb.time, userZone) : '';
const utcTime = hb ? formatLocalTime(hb.time, 'utc') : '';
return (
<div style={{ minWidth: 220 }}>
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 4 }}>
<FiCheckCircle color={hb.status === 1 ? 'green' : 'red'} style={{ marginRight: 6 }} />
<b>{hb.status === 1 ? 'Up' : 'Down'}</b>
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<FiClock style={{ marginRight: 6 }} />
Local: {localTime}
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<FiGlobe style={{ marginRight: 6 }} />
UTC: {utcTime}
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<FiActivity style={{ marginRight: 6 }} />
Ping: {hb.ping ?? '--'} ms
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<FiPercent style={{ marginRight: 6 }} />
Uptime 24h: {monitor.uptime24h?.toFixed(2) ?? '--'}%
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<FiLock style={{ marginRight: 6 }} />
Cert valid for: {monitor.certExpiryDaysRemaining ?? '--'} days
</div>
</div>
);
}
export default function UptimeStatusIsland() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
@@ -239,18 +274,20 @@ export default function UptimeStatusIsland() {
{Array.from({ length: 40 }).map((_, i) => {
const hbArr = monitor.heartbeatHistory ?? [];
const hb = hbArr.slice(-40)[i];
const localTime = hb ? formatLocalTime(hb.time, userZone) : '';
const utcTime = hb ? formatLocalTime(hb.time, 'utc') : '';
return (
<span
<Tippy
key={i}
title={
hb
? `Status: ${hb.status === 1 ? 'Up' : 'Down'}\nLocal: ${localTime}\nUTC: ${utcTime}`
: ''
}
className={`w-full h-4 rounded-sm ${hb ? getHeartbeatColor(hb.status) : 'bg-gray-400 dark:bg-gray-600'} block`}
></span>
content={<HeartbeatPopup hb={hb} userZone={userZone} monitor={monitor} />}
placement="top"
animation="shift-away"
theme="devnet"
delay={[0, 0]}
>
<span
className={`w-full h-4 rounded-sm ${hb ? getHeartbeatColor(hb.status) : 'bg-gray-400 dark:bg-gray-600'} block`}
style={{ cursor: 'pointer' }}
></span>
</Tippy>
);
})}
</div>