"更新 uptime-status 为 jj-status,增加新依赖和功能

- 重命名项目从 uptime-status 到 jj-status。
- 添加 react-simple-typewriter 依赖,引入打字机效果。
- 更新相关配置文件和代码,适应新依赖和特性。
- 增加博客链接和云助手导航,移除旧的 Homepage 和 GitHub 导航。
- 引入每日一言(hitokoto)功能。
- 调整样式变量和组件
pull/55/head
GongJinZheng 2024-08-15 16:14:34 +08:00
parent bb67f7f2a7
commit 3fad902619
8 changed files with 149 additions and 80 deletions

23
package-lock.json generated
View File

@ -1,11 +1,11 @@
{
"name": "uptime-status",
"name": "jj-status",
"version": "2.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "uptime-status",
"name": "jj-status",
"version": "2.0.0",
"license": "MIT",
"dependencies": {
@ -14,6 +14,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1",
"react-simple-typewriter": "^5.0.1",
"react-tooltip": "^4.2.21",
"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": {
"version": "4.2.21",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
@ -25752,6 +25765,12 @@
"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": {
"version": "4.2.21",
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",

View File

@ -1,5 +1,5 @@
{
"name": "uptime-status",
"name": "jj-status",
"version": "2.0.0",
"license": "MIT",
"scripts": {
@ -12,6 +12,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1",
"react-simple-typewriter": "^5.0.1",
"react-tooltip": "^4.2.21",
"sass": "^1.53.0"
},

View File

@ -1,15 +1,12 @@
window.Config = {
// 显示标题
SiteName: 'Public Status',
SiteName: '站点检测',
// UptimeRobot Api Keys
// 支持 Monitor-Specific 和 Read-Only
ApiKeys: [
'm784488775-dd1ad84b209c05f8e185c33e',
'm784490063-7b5da437e7f1e0d67613714d',
'm784497419-de55aa09902ccb3ab22d548a',
'm784496436-71a4bf7b1e3bdf7756be131b',
'ur2648744-49ccec99d7a4ea70c9e441f3'
],
// 日志天数
@ -21,16 +18,17 @@ window.Config = {
// 导航栏菜单
Navi: [
{
text: 'Homepage',
url: 'https://status.org.cn/'
text: 'Blog',
url: 'https://wzue.cn/'
},
{
text: '云助手',
url: 'https://mz.wzue.cn/'
},
{
text: 'GitHub',
url: 'https://github.com/yb/uptime-status'
},
{
text: 'Blog',
url: 'https://abo.xyz/'
url: 'https://github.com/9075512'
},
],
};

View File

@ -9,6 +9,7 @@
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<title>Uptime Status</title>
<script src="./config.js"></script>
<!-- 本例不能添加链接内容,放在此处只是因为此接口比较方便,也许能够解决大部分的需求-->
</head>
<body>
<div id="app"></div>

View File

@ -27,7 +27,7 @@ a {
}
#header {
background-color: #121a26;
background-color: $primary-color;
padding: 30px 0 60px 0;
color: $primary-color;
width: 100%;
@ -39,6 +39,7 @@ a {
.logo {
font-size: 20px;
font-weight: bold;
color: #ffffff;
}
.navi {
font-size: 14px;
@ -48,7 +49,7 @@ a {
transition: color ease 150ms;
}
a:hover {
color: $primary-color;
// color: $primary-color;
}
}
}
@ -170,4 +171,9 @@ a {
font-weight: bold;
color: $primary-color;
}
.hitokoto{
font-weight: bold;
color: $primary-color;
cursor: pointer;
}
}

6
src/common/hitokoto.js Normal file
View File

@ -0,0 +1,6 @@
import axios from 'axios';
export async function GetHitokoto() {
const response = await axios.get('https://v1.hitokoto.cn');
return response;
}

View File

@ -1,30 +1,54 @@
import { useMemo } from 'react';
import Link from './link';
import Header from './header';
import UptimeRobot from './uptimerobot';
import Package from '../../package.json';
import { useMemo } from "react";
import Link from "./link";
import Header from "./header";
import UptimeRobot from "./uptimerobot";
import Package from "../../package.json";
import { GetHitokoto } from "../common/hitokoto";
import { useEffect, useState } from "react";
import { Typewriter } from 'react-simple-typewriter'
function App() {
const apikeys = useMemo(() => {
const { ApiKeys } = window.Config;
if (Array.isArray(ApiKeys)) return ApiKeys;
if (typeof ApiKeys === 'string') return [ApiKeys];
if (typeof ApiKeys === "string") return [ApiKeys];
return [];
}, []);
const [hitokoto, setHitokoto] = useState(['结局是什么,我们自己决定!']);
function getText() {
GetHitokoto().then(({ data }) => {
setHitokoto([...hitokoto,data.hitokoto]);
});
}
useEffect(() => {
getText();
}, []);
return (
<>
<Header />
<div className='container'>
<div id='uptime'>
<div className="container">
<div id="uptime">
{apikeys.map((key) => (
<UptimeRobot key={key} apikey={key} />
))}
</div>
<div id='footer'>
<p>基于 <Link to='https://uptimerobot.com/' text='UptimeRobot' /> 接口制作检测频率 5 分钟</p>
<p>&copy; 2020 <Link to='https://status.org.cn/' text='STATUS.ORG.CN' />, Version {Package.version}</p>
<div id="footer">
<p className="hitokoto">
<Typewriter cursor="true" delaySpeed="6000" cursorStyle="⚡" words={hitokoto} onDelay={getText}/>
</p>
<p>
基于 <Link to="https://uptimerobot.com/" text="UptimeRobot" />{" "}
接口制作检测频率 5 分钟
</p>
<p>
&copy; 2020{" "}
<Link to="https://status.wzue.cn/" text="STATUS.WZUE.CN" />, Version{" "}
{Package.version}
</p>
</div>
</div>
</>

View File

@ -1,15 +1,14 @@
import ReactTooltip from 'react-tooltip';
import { useEffect, useState } from 'react';
import { GetMonitors } from '../common/uptimerobot';
import { formatDuration, formatNumber } from '../common/helper';
import Link from './link';
import ReactTooltip from "react-tooltip";
import { useEffect, useState } from "react";
import { GetMonitors } from "../common/uptimerobot";
import { formatDuration, formatNumber } from "../common/helper";
import Link from "./link";
function UptimeRobot({ apikey }) {
const status = {
ok: '正常',
down: '无法访问',
unknow: '未知'
ok: "正常",
down: "无法访问",
unknow: "未知",
};
const { CountDays, ShowLink } = window.Config;
@ -20,50 +19,65 @@ function UptimeRobot({ apikey }) {
GetMonitors(apikey, CountDays).then(setMonitors);
}, [apikey, CountDays]);
if (monitors) return monitors.map((site) => (
<div key={site.id} className='site'>
<div className='meta'>
<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>
if (monitors)
return monitors.map((site) => (
<div key={site.id} className="site">
<div className="meta">
<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 className="timeline">
{site.daily.map((data, index) => {
let status = "";
let text = data.date.format("YYYY-MM-DD ");
if (data.uptime >= 100) {
status = "ok";
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)}%`;
}
return <i key={index} className={status} data-tip={text} />;
})}
</div>
<div className="summary">
<span>今天</span>
<span>
{site.total.times
? `最近 ${CountDays} 天故障 ${
site.total.times
} 累计 ${formatDuration(site.total.duration)}平均可用率 ${
site.average
}%`
: `最近 ${CountDays} 天可用率 ${site.average}%`}
</span>
<span>
{site.daily[site.daily.length - 1].date.format("YYYY-MM-DD")}
</span>
</div>
<ReactTooltip
className="tooltip"
place="top"
type="dark"
effect="solid"
/>
</div>
<div className='timeline'>
{site.daily.map((data, index) => {
let status = '';
let text = data.date.format('YYYY-MM-DD ');
if (data.uptime >= 100) {
status = 'ok';
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)}%`;
}
return (<i key={index} className={status} data-tip={text} />)
})}
));
else
return (
<div className="site">
<div className="loading" />
</div>
<div className='summary'>
<span>今天</span>
<span>
{site.total.times
? `最近 ${CountDays} 天故障 ${site.total.times} 次,累计 ${formatDuration(site.total.duration)},平均可用率 ${site.average}%`
: `最近 ${CountDays} 天可用率 ${site.average}%`}
</span>
<span>{site.daily[site.daily.length - 1].date.format('YYYY-MM-DD')}</span>
</div>
<ReactTooltip className='tooltip' place='top' type='dark' effect='solid' />
</div>
));
else return (
<div className='site'>
<div className='loading' />
</div>
);
);
}
export default UptimeRobot;