better comparison + fixed navbar
This commit is contained in:
parent
9c601aa3be
commit
d764fd29e1
|
@ -2,13 +2,12 @@
|
|||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="03fafda4-e2c1-4602-a731-a2f96e84badd" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/src/components/CreateCruisePage.css" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/components/UptimeComparisonCard.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/components/UptimeLabelCard.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/App.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.css" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/CreateCruisePage.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/CreateCruisePage.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/HomePage.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/HomePage.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/UptimeCard.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/UptimeCard.css" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.tsx" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -37,16 +36,14 @@
|
|||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"list.type.of.created.stylesheet": "CSS",
|
||||
"ts.external.directory.path": "/home/nickorlow/programmming/personal/nws-site/node_modules/typescript/lib"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/src/components" />
|
||||
<property name="ts.external.directory.path" value="$PROJECT_DIR$/node_modules/typescript/lib" />
|
||||
</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$/src/static/images" />
|
||||
<recent name="$PROJECT_DIR$/src/components" />
|
||||
<recent name="$PROJECT_DIR$/src/static/images" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
|
|
|
@ -6,6 +6,8 @@ import React, {useEffect, useState} from "react";
|
|||
import {Incident, UptimeResponse} from "../nws-api/types";
|
||||
import {getIncidents, getUptime} from "../nws-api/calls";
|
||||
import "../App.css";
|
||||
import UptimeComparisonCard from "./UptimeComparisonCard";
|
||||
import UptimeLabelCard from "./UptimeLabelCard";
|
||||
|
||||
|
||||
export default function HomePage() {
|
||||
|
@ -30,7 +32,6 @@ export default function HomePage() {
|
|||
|
||||
return(
|
||||
<div className="App">
|
||||
|
||||
<div className={"w-100 row"}>
|
||||
<div className={"col-md-6 d-flex justify-content-center flex-column align-items-center"}>
|
||||
<img src={NWSLogo} alt="nws-logo" style={{width: "70%"}}/>
|
||||
|
@ -45,7 +46,10 @@ export default function HomePage() {
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={"w-100 mt-2 flex justify-content-center align-content-center text-center"}>
|
||||
<h3><i>Better uptime than GitHub Pages!</i></h3>
|
||||
<h4><a href={"https://youtu.be/WHdXWMFHuqA"} target="_blank" rel="noopener noreferrer">Watch the NWS Deployment Demo</a></h4>
|
||||
</div>
|
||||
<div style={{width: '75vw'}}>
|
||||
<hr/>
|
||||
</div>
|
||||
|
@ -53,10 +57,11 @@ export default function HomePage() {
|
|||
<div className={"text-left row"} style={{width: '75vw'}}>
|
||||
<h2>Compare us to our competitors</h2>
|
||||
<p>Last updated at {new Date(uptime.lastUpdated).toLocaleString()}</p>
|
||||
<div className={"col-12 row w-100 m-0"}>
|
||||
<div className={"col-12 row w-100 m-0 align-content-center d-flex justify-content-center pt-2"}>
|
||||
<UptimeLabelCard/>
|
||||
{uptime.competitors.sort((a,b)=>{return b.uptimeMonth === a.uptimeMonth ? (a.name === "NWS" ? -1000 : b.name.localeCompare(a.name)) : b.uptimeMonth - a.uptimeMonth}).map((e) => {
|
||||
return (
|
||||
<UptimeCard uptime={e} isService={false}/>
|
||||
<UptimeComparisonCard uptime={e} isService={false}/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
|
|
@ -26,3 +26,16 @@
|
|||
width: 500px;
|
||||
max-width: 100vw;
|
||||
}
|
||||
|
||||
.stat-perfect {
|
||||
font-weight: bold;
|
||||
color: #069D06
|
||||
}
|
||||
|
||||
.stat-middle {
|
||||
color: #877E1C
|
||||
}
|
||||
|
||||
.stat-bad {
|
||||
color: #921111
|
||||
}
|
||||
|
|
80
src/components/UptimeComparisonCard.tsx
Normal file
80
src/components/UptimeComparisonCard.tsx
Normal file
|
@ -0,0 +1,80 @@
|
|||
import {UptimeRecord} from "../nws-api/types";
|
||||
import React, {useState} from "react";
|
||||
import '../App.css';
|
||||
import "./UptimeCard.css"
|
||||
import Modal from "react-modal";
|
||||
|
||||
function getUptimeClass(uptime: number) {
|
||||
if(uptime === 100) {
|
||||
return "stat-perfect";
|
||||
}
|
||||
|
||||
if(uptime >= 95) {
|
||||
return "stat-middle";
|
||||
}
|
||||
|
||||
return "stat-bad";
|
||||
}
|
||||
|
||||
function getResponseTimeClass(respTime: number) {
|
||||
// https://www.littledata.io/average/server-response-time
|
||||
if(respTime < 205) {
|
||||
return "stat-perfect";
|
||||
}
|
||||
|
||||
if(respTime < 495) {
|
||||
return "stat-middle";
|
||||
}
|
||||
|
||||
return "stat-bad";
|
||||
}
|
||||
|
||||
export default function UptimeComparisonCard(props: {uptime: UptimeRecord, isService: boolean}) {
|
||||
const [isModalOpen, setModalOpen] = useState(false);
|
||||
return(
|
||||
<div className={"col-12 col-md-2 mb-2 p-0 m-0 text-center"}>
|
||||
<div style={{height: 25, margin: 0}}>
|
||||
<h4 className={"uptime-lnk"} onClick={()=>setModalOpen(true)}>{props.uptime.name}</h4>
|
||||
</div>
|
||||
<hr/>
|
||||
<p className={"fw-bold d-md-none"}>Uptime (Last Month)</p>
|
||||
<p className={getUptimeClass(props.uptime.uptimeMonth)}>{props.uptime.uptimeMonth}%</p>
|
||||
<hr/>
|
||||
<p className={"fw-bold d-md-none"}>Uptime ({new Date().getFullYear()} YTD)</p>
|
||||
<p className={getUptimeClass(props.uptime.uptimeYtd)}>{props.uptime.uptimeYtd}%</p>
|
||||
<hr/>
|
||||
<p className={"fw-bold d-md-none"}>Avg Response Time (24hr)</p>
|
||||
<p className={getResponseTimeClass(props.uptime.averageResponseTime)}>{props.uptime.averageResponseTime}ms</p>
|
||||
<hr/>
|
||||
<p className={"fw-bold d-md-none"}>Current Status</p>
|
||||
<div className={`p-1 d-flex justify-content-start w-100`}>
|
||||
<p className={`fw-bold severity-label w-100
|
||||
${props.uptime.isUp ? 'low' : (props.uptime.undergoingMaintenance ? 'med' : 'high')}-severity`}
|
||||
>
|
||||
{props.uptime.isUp ? 'Up' : (props.uptime.undergoingMaintenance ? 'Maintenance' : 'Down')}
|
||||
</p>
|
||||
</div>
|
||||
<Modal className={"uptime-modal"} isOpen={isModalOpen}>
|
||||
<div className={"mb-3"}>
|
||||
<h1 className={"mb-0"}>{props.uptime.name}</h1>
|
||||
{props.uptime.url && <p>(<a href={props.uptime.url}>{props.uptime.url}</a>)</p>}
|
||||
</div>
|
||||
<div className={"mb-3"}>
|
||||
<p>Monitoring since {props.uptime.monitorStart}</p>
|
||||
<p><b>{new Date().getFullYear()} Uptime (YTD):</b> {props.uptime.uptimeYtd}%</p>
|
||||
<p><b>Last Month Uptime:</b> {props.uptime.uptimeMonth}%</p>
|
||||
<p><b>All-Time Uptime:</b> {props.uptime.uptimeAllTime}%</p>
|
||||
<p><b>Average Response Time:</b> {props.uptime.averageResponseTime}ms</p>
|
||||
</div>
|
||||
{
|
||||
props.isService &&
|
||||
<div className={"mb-3"}>
|
||||
<i>Note that the uptime and performance of services hosted on NWS may be affected by factors not controlled by NWS such as bad bad optimization or buggy software.</i>
|
||||
</div>
|
||||
}
|
||||
<button className={"w-100"} onClick={()=>setModalOpen(false)}>Close</button>
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
24
src/components/UptimeLabelCard.tsx
Normal file
24
src/components/UptimeLabelCard.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import {UptimeRecord} from "../nws-api/types";
|
||||
import React, {useState} from "react";
|
||||
import '../App.css';
|
||||
import "./UptimeCard.css"
|
||||
import Modal from "react-modal";
|
||||
|
||||
export default function UptimeLabelCard() {
|
||||
|
||||
return(
|
||||
<div className={"col-2 p-0 d-none d-md-block mb-2 m-0 text-center"}>
|
||||
<div style={{height: 25, margin: 0}}>
|
||||
<p className={"fw-bold"}>Service Name</p>
|
||||
</div>
|
||||
<hr/>
|
||||
<p className={"fw-bold"}>Uptime (Last Month)</p>
|
||||
<hr/>
|
||||
<p className={"fw-bold"}>Uptime ({new Date().getFullYear()} YTD)</p>
|
||||
<hr/>
|
||||
<p className={"fw-bold"}>Avg Response Time (24hr)</p>
|
||||
<hr/>
|
||||
<p className={"fw-bold"}>Current Status</p>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -20,26 +20,39 @@ import VerifyPage from "./components/VerifyPage";
|
|||
import DashboardPage from "./components/DashboardPage";
|
||||
import CreateCruisePage from "./components/CreateCruisePage";
|
||||
import HomePage from "./components/HomePage";
|
||||
import NavbarCollapse from "react-bootstrap/NavbarCollapse";
|
||||
import NavbarOffcanvas from "react-bootstrap/NavbarOffcanvas";
|
||||
|
||||
function Layout (props: {children: any}) {
|
||||
return (
|
||||
<div>
|
||||
<Navbar sticky={"top"} style={{height: "8vh", backgroundColor: "#eee", paddingLeft: "5vw", paddingRight: "5vw", maxWidth:"100%"}} className={"row m-0"}>
|
||||
<div className={"col-10"}>
|
||||
<NavbarBrand>
|
||||
<img src={NWSLogo} alt="nws-logo" style={{width: 120}}/>
|
||||
</NavbarBrand>
|
||||
<NavLink className={"nav-lnk"} to={"/"}>
|
||||
Home
|
||||
</NavLink>
|
||||
<NavLink className={"nav-lnk"} to={"/status"}>
|
||||
Status
|
||||
</NavLink>
|
||||
<header className={"w-100 sticky-top"}>
|
||||
<div className={"w-100"}>
|
||||
<Navbar sticky={"top"} expand="lg" className={"row justify-content-center m-0 p-0"} style={{backgroundColor: "#eee"}}>
|
||||
<div className={"row w-100"}>
|
||||
<div className="row w-100 d-md-none d-sm-block">
|
||||
<div className={"col-9"}>
|
||||
<Navbar.Brand href="/">
|
||||
<img src={NWSLogo} width={150}/>
|
||||
</Navbar.Brand>
|
||||
</div>
|
||||
{/*<NavLink className={"nav-lnk"} to={"/blogs"}>*/}
|
||||
{/* Blog*/}
|
||||
{/*</NavLink>*/}
|
||||
<div className={"col-2 d-none d-md-block"}>
|
||||
<div className={"col-2 ml-3 d-flex align-content-center justify-content-center"}>
|
||||
<Navbar.Toggle className={"h-50 align-self-center"} aria-controls="basic-navbar-nav"/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"d-md-block d-none col-2"}>
|
||||
<Navbar.Brand href="/">
|
||||
<img src={NWSLogo} width={150}/>
|
||||
</Navbar.Brand>
|
||||
</div>
|
||||
<Navbar.Collapse id="basic-navbar-nav" className={"col-10"}>
|
||||
<Nav className="row w-100 ml-5">
|
||||
<div className="col-md-4 row">
|
||||
<NavLink className="col-sm-12 col-md-3 nav-lnk align-self-center" to={"/"}>Home</NavLink>
|
||||
<NavLink className="col-sm-12 col-md-3 nav-lnk align-self-center" to={"/status"}>Status</NavLink>
|
||||
</div>
|
||||
<div className="col-md-6"/>
|
||||
<div className={"col-md-2 d-md-block d-none"}>
|
||||
{ localStorage.getItem("session_key") === null &&
|
||||
(
|
||||
<NavLink className={"nav-lnk"} to={"/login"}>
|
||||
|
@ -62,7 +75,12 @@ function Layout (props: {children: any}) {
|
|||
)
|
||||
}
|
||||
</div>
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
</div>
|
||||
</Navbar>
|
||||
</div>
|
||||
</header>
|
||||
<div style={{minHeight: "92vh"}}>
|
||||
{props.children}
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue