mirror of https://github.com/yb/uptime-status
"更新 uptime-status 为 jj-status,增加新依赖和功能
- 重命名项目从 uptime-status 到 jj-status。 - 添加 react-simple-typewriter 依赖,引入打字机效果。 - 更新相关配置文件和代码,适应新依赖和特性。 - 增加博客链接和云助手导航,移除旧的 Homepage 和 GitHub 导航。 - 引入每日一言(hitokoto)功能。 - 调整样式变量和组件pull/55/head
parent
bb67f7f2a7
commit
3fad902619
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "uptime-status",
|
"name": "jj-status",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "uptime-status",
|
"name": "jj-status",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
|
"react-simple-typewriter": "^5.0.1",
|
||||||
"react-tooltip": "^4.2.21",
|
"react-tooltip": "^4.2.21",
|
||||||
"sass": "^1.53.0"
|
"sass": "^1.53.0"
|
||||||
}
|
}
|
||||||
|
@ -13538,6 +13539,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-simple-typewriter": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-simple-typewriter/-/react-simple-typewriter-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-vA5HkABwJKL/DJ4RshSlY/igdr+FiVY4MLsSQYJX6FZG/f1/VwN4y1i3mPXRyfaswrvI8xii1kOVe1dYtO2Row==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18.0.0",
|
||||||
|
"react-dom": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-tooltip": {
|
"node_modules/react-tooltip": {
|
||||||
"version": "4.2.21",
|
"version": "4.2.21",
|
||||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
||||||
|
@ -25752,6 +25765,12 @@
|
||||||
"workbox-webpack-plugin": "^6.4.1"
|
"workbox-webpack-plugin": "^6.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-simple-typewriter": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/react-simple-typewriter/-/react-simple-typewriter-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-vA5HkABwJKL/DJ4RshSlY/igdr+FiVY4MLsSQYJX6FZG/f1/VwN4y1i3mPXRyfaswrvI8xii1kOVe1dYtO2Row==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"react-tooltip": {
|
"react-tooltip": {
|
||||||
"version": "4.2.21",
|
"version": "4.2.21",
|
||||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "uptime-status",
|
"name": "jj-status",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
|
"react-simple-typewriter": "^5.0.1",
|
||||||
"react-tooltip": "^4.2.21",
|
"react-tooltip": "^4.2.21",
|
||||||
"sass": "^1.53.0"
|
"sass": "^1.53.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
window.Config = {
|
window.Config = {
|
||||||
|
|
||||||
// 显示标题
|
// 显示标题
|
||||||
SiteName: 'Public Status',
|
SiteName: '站点检测',
|
||||||
|
|
||||||
// UptimeRobot Api Keys
|
// UptimeRobot Api Keys
|
||||||
// 支持 Monitor-Specific 和 Read-Only
|
// 支持 Monitor-Specific 和 Read-Only
|
||||||
ApiKeys: [
|
ApiKeys: [
|
||||||
'm784488775-dd1ad84b209c05f8e185c33e',
|
'ur2648744-49ccec99d7a4ea70c9e441f3'
|
||||||
'm784490063-7b5da437e7f1e0d67613714d',
|
|
||||||
'm784497419-de55aa09902ccb3ab22d548a',
|
|
||||||
'm784496436-71a4bf7b1e3bdf7756be131b',
|
|
||||||
],
|
],
|
||||||
|
|
||||||
// 日志天数
|
// 日志天数
|
||||||
|
@ -21,16 +18,17 @@ window.Config = {
|
||||||
// 导航栏菜单
|
// 导航栏菜单
|
||||||
Navi: [
|
Navi: [
|
||||||
{
|
{
|
||||||
text: 'Homepage',
|
text: 'Blog',
|
||||||
url: 'https://status.org.cn/'
|
url: 'https://wzue.cn/'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '云助手',
|
||||||
|
url: 'https://mz.wzue.cn/'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'GitHub',
|
text: 'GitHub',
|
||||||
url: 'https://github.com/yb/uptime-status'
|
url: 'https://github.com/9075512'
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Blog',
|
|
||||||
url: 'https://abo.xyz/'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
|
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
|
||||||
<title>Uptime Status</title>
|
<title>Uptime Status</title>
|
||||||
<script src="./config.js"></script>
|
<script src="./config.js"></script>
|
||||||
|
<!-- 本例不能添加链接内容,放在此处只是因为此接口比较方便,也许能够解决大部分的需求-->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
10
src/app.scss
10
src/app.scss
|
@ -27,7 +27,7 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
#header {
|
#header {
|
||||||
background-color: #121a26;
|
background-color: $primary-color;
|
||||||
padding: 30px 0 60px 0;
|
padding: 30px 0 60px 0;
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -39,6 +39,7 @@ a {
|
||||||
.logo {
|
.logo {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
.navi {
|
.navi {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -48,7 +49,7 @@ a {
|
||||||
transition: color ease 150ms;
|
transition: color ease 150ms;
|
||||||
}
|
}
|
||||||
a:hover {
|
a:hover {
|
||||||
color: $primary-color;
|
// color: $primary-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,4 +171,9 @@ a {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
|
.hitokoto{
|
||||||
|
font-weight: bold;
|
||||||
|
color: $primary-color;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export async function GetHitokoto() {
|
||||||
|
const response = await axios.get('https://v1.hitokoto.cn');
|
||||||
|
return response;
|
||||||
|
}
|
|
@ -1,30 +1,54 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from "react";
|
||||||
import Link from './link';
|
import Link from "./link";
|
||||||
import Header from './header';
|
import Header from "./header";
|
||||||
import UptimeRobot from './uptimerobot';
|
import UptimeRobot from "./uptimerobot";
|
||||||
import Package from '../../package.json';
|
import Package from "../../package.json";
|
||||||
|
import { GetHitokoto } from "../common/hitokoto";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Typewriter } from 'react-simple-typewriter'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
const apikeys = useMemo(() => {
|
const apikeys = useMemo(() => {
|
||||||
const { ApiKeys } = window.Config;
|
const { ApiKeys } = window.Config;
|
||||||
if (Array.isArray(ApiKeys)) return ApiKeys;
|
if (Array.isArray(ApiKeys)) return ApiKeys;
|
||||||
if (typeof ApiKeys === 'string') return [ApiKeys];
|
if (typeof ApiKeys === "string") return [ApiKeys];
|
||||||
return [];
|
return [];
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const [hitokoto, setHitokoto] = useState(['结局是什么,我们自己决定!']);
|
||||||
|
|
||||||
|
function getText() {
|
||||||
|
GetHitokoto().then(({ data }) => {
|
||||||
|
setHitokoto([...hitokoto,data.hitokoto]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getText();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
<div className='container'>
|
<div className="container">
|
||||||
<div id='uptime'>
|
<div id="uptime">
|
||||||
{apikeys.map((key) => (
|
{apikeys.map((key) => (
|
||||||
<UptimeRobot key={key} apikey={key} />
|
<UptimeRobot key={key} apikey={key} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id="footer">
|
||||||
<p>基于 <Link to='https://uptimerobot.com/' text='UptimeRobot' /> 接口制作,检测频率 5 分钟</p>
|
<p className="hitokoto">
|
||||||
<p>© 2020 <Link to='https://status.org.cn/' text='STATUS.ORG.CN' />, Version {Package.version}</p>
|
<Typewriter cursor="true" delaySpeed="6000" cursorStyle="⚡" words={hitokoto} onDelay={getText}/>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
基于 <Link to="https://uptimerobot.com/" text="UptimeRobot" />{" "}
|
||||||
|
接口制作,检测频率 5 分钟
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
© 2020{" "}
|
||||||
|
<Link to="https://status.wzue.cn/" text="STATUS.WZUE.CN" />, Version{" "}
|
||||||
|
{Package.version}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
import ReactTooltip from 'react-tooltip';
|
import ReactTooltip from "react-tooltip";
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from "react";
|
||||||
import { GetMonitors } from '../common/uptimerobot';
|
import { GetMonitors } from "../common/uptimerobot";
|
||||||
import { formatDuration, formatNumber } from '../common/helper';
|
import { formatDuration, formatNumber } from "../common/helper";
|
||||||
import Link from './link';
|
import Link from "./link";
|
||||||
|
|
||||||
function UptimeRobot({ apikey }) {
|
function UptimeRobot({ apikey }) {
|
||||||
|
|
||||||
const status = {
|
const status = {
|
||||||
ok: '正常',
|
ok: "正常",
|
||||||
down: '无法访问',
|
down: "无法访问",
|
||||||
unknow: '未知'
|
unknow: "未知",
|
||||||
};
|
};
|
||||||
|
|
||||||
const { CountDays, ShowLink } = window.Config;
|
const { CountDays, ShowLink } = window.Config;
|
||||||
|
@ -20,48 +19,63 @@ function UptimeRobot({ apikey }) {
|
||||||
GetMonitors(apikey, CountDays).then(setMonitors);
|
GetMonitors(apikey, CountDays).then(setMonitors);
|
||||||
}, [apikey, CountDays]);
|
}, [apikey, CountDays]);
|
||||||
|
|
||||||
if (monitors) return monitors.map((site) => (
|
if (monitors)
|
||||||
<div key={site.id} className='site'>
|
return monitors.map((site) => (
|
||||||
<div className='meta'>
|
<div key={site.id} className="site">
|
||||||
<span className='name' dangerouslySetInnerHTML={{ __html: site.name }} />
|
<div className="meta">
|
||||||
{ShowLink && <Link className='link' to={site.url} text={site.name} />}
|
<span
|
||||||
<span className={'status ' + site.status}>{status[site.status]}</span>
|
className="name"
|
||||||
|
dangerouslySetInnerHTML={{ __html: site.name }}
|
||||||
|
/>
|
||||||
|
{ShowLink && <Link className="link" to={site.url} text={site.name} />}
|
||||||
|
<span className={"status " + site.status}>{status[site.status]}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='timeline'>
|
<div className="timeline">
|
||||||
{site.daily.map((data, index) => {
|
{site.daily.map((data, index) => {
|
||||||
let status = '';
|
let status = "";
|
||||||
let text = data.date.format('YYYY-MM-DD ');
|
let text = data.date.format("YYYY-MM-DD ");
|
||||||
if (data.uptime >= 100) {
|
if (data.uptime >= 100) {
|
||||||
status = 'ok';
|
status = "ok";
|
||||||
text += `可用率 ${formatNumber(data.uptime)}%`;
|
text += `可用率 ${formatNumber(data.uptime)}%`;
|
||||||
|
} else if (data.uptime <= 0 && data.down.times === 0) {
|
||||||
|
status = "none";
|
||||||
|
text += "无数据";
|
||||||
|
} else {
|
||||||
|
status = "down";
|
||||||
|
text += `故障 ${data.down.times} 次,累计 ${formatDuration(
|
||||||
|
data.down.duration
|
||||||
|
)},可用率 ${formatNumber(data.uptime)}%`;
|
||||||
}
|
}
|
||||||
else if (data.uptime <= 0 && data.down.times === 0) {
|
return <i key={index} className={status} data-tip={text} />;
|
||||||
status = 'none';
|
|
||||||
text += '无数据';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
status = 'down';
|
|
||||||
text += `故障 ${data.down.times} 次,累计 ${formatDuration(data.down.duration)},可用率 ${formatNumber(data.uptime)}%`;
|
|
||||||
}
|
|
||||||
return (<i key={index} className={status} data-tip={text} />)
|
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className='summary'>
|
<div className="summary">
|
||||||
<span>今天</span>
|
<span>今天</span>
|
||||||
<span>
|
<span>
|
||||||
{site.total.times
|
{site.total.times
|
||||||
? `最近 ${CountDays} 天故障 ${site.total.times} 次,累计 ${formatDuration(site.total.duration)},平均可用率 ${site.average}%`
|
? `最近 ${CountDays} 天故障 ${
|
||||||
|
site.total.times
|
||||||
|
} 次,累计 ${formatDuration(site.total.duration)},平均可用率 ${
|
||||||
|
site.average
|
||||||
|
}%`
|
||||||
: `最近 ${CountDays} 天可用率 ${site.average}%`}
|
: `最近 ${CountDays} 天可用率 ${site.average}%`}
|
||||||
</span>
|
</span>
|
||||||
<span>{site.daily[site.daily.length - 1].date.format('YYYY-MM-DD')}</span>
|
<span>
|
||||||
|
{site.daily[site.daily.length - 1].date.format("YYYY-MM-DD")}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ReactTooltip className='tooltip' place='top' type='dark' effect='solid' />
|
<ReactTooltip
|
||||||
|
className="tooltip"
|
||||||
|
place="top"
|
||||||
|
type="dark"
|
||||||
|
effect="solid"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
else
|
||||||
else return (
|
return (
|
||||||
<div className='site'>
|
<div className="site">
|
||||||
<div className='loading' />
|
<div className="loading" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue