Browse Source

Adding the first couple tiles and getting an idea of how to lay out the page

Kirk Trombley 5 years ago
parent
commit
88d1c83a4f

+ 3 - 0
.gitignore

@@ -21,3 +21,6 @@
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
+
+
+.vscode/

+ 59 - 1
src/App.css

@@ -1,5 +1,63 @@
 .App {
+  min-height: 100vh;
   text-align: center;
-  background-color: #282c34;
+  background-color: #292929;
   color: white;
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+  align-items: center;
+  align-content: flex-start;
 }
+
+.tile {
+  background-color: #252525;
+  color: white;
+  height: 4em;
+  width: 15%;
+  margin: 2em;
+  padding-left: 0.5em;
+  padding-bottom: 0.5em;
+  display: flex;
+  flex-flow: column nowrap;
+  justify-content: flex-start;
+  align-items: flex-start;
+  border-style: solid;
+  border-width: 2px;
+  border-color: #666;
+  border-radius: 7px;
+  text-decoration: none;
+}
+
+.tile:hover {
+  background-color: #444;
+}
+
+.tile__title {
+  font-size: 120%;
+  font-weight: 1000;
+}
+
+.tile__status {
+  font-weight: 300;
+  font-size: 90%;
+  padding-left: 1em;
+}
+
+.tile__status--unknown {
+  color: #bb0;
+}
+
+.tile__status--ok {
+  color: #0b0;
+}
+
+.tile__status--bad, .tile__status--failed {
+  color: #b00;
+}
+
+.tile__data {
+  font-weight: 300;
+  font-size: 90%;
+  padding-left: 1em;
+}

+ 8 - 10
src/App.js

@@ -1,13 +1,11 @@
 import React from 'react';
 import './App.css';
-import StartPage from './components/StartPage';
+import Teamspeak from "./components/tiles/Teamspeak";
+import TerrAssumptions from './components/tiles/TerrAssumptions';
 
-function App() {
-  return (
-    <div className="App">
-      <StartPage/>
-    </div>
-  );
-}
-
-export default App;
+export default () => (
+  <div className="App">
+    <Teamspeak/>
+    <TerrAssumptions/>
+  </div>
+);

+ 0 - 3
src/components/StartPage.jsx

@@ -1,3 +0,0 @@
-import React from "react";
-
-export default () => <div>WIP</div>

+ 21 - 0
src/components/shared/StatusMessage.jsx

@@ -0,0 +1,21 @@
+import React from "react";
+
+export const UNKNOWN = 0;
+export const OK      = 1;
+export const BAD     = 2;
+export const FAILED  = 3;
+
+export const StatusMessage = ({ health }) => {
+  switch (health) {
+    case UNKNOWN:
+      return <span className="tile__status tile__status--unknown">Connecting...</span>
+    case OK:
+      return <span className="tile__status tile__status--ok">Service Healthy</span>
+    case BAD:
+      return <span className="tile__status tile__status--bad">Service Error</span>
+    case FAILED:
+      return <span className="tile__status tile__status--failed">Service Unreachable</span>
+    default:
+      return <span className="tile__status">Bad Status State</span>
+  }
+}

+ 21 - 0
src/components/tiles/Teamspeak.jsx

@@ -0,0 +1,21 @@
+import React, { useState } from "react";
+import useJsonHealthCheck from "../../hooks/useJsonHealthCheck";
+import { StatusMessage, UNKNOWN, OK, BAD, FAILED } from "../shared/StatusMessage";
+
+export default () => {
+  const [{ users, health }, setState] = useState({ users: null, health: UNKNOWN });
+  useJsonHealthCheck(
+    "https://kirkleon.ddns.net/teamspeak/api",
+    ({ users }) => setState({ users: users.length, health: OK }),
+    () => setState({ users: null, health: BAD }),
+    () => setState({ users: null, health: FAILED }),
+  );
+  
+  return (
+    <a className="tile" href="https://kirkleon.ddns.net/teamspeak/">
+      <span className="tile__title">Teamspeak Server</span>
+      <StatusMessage health={health} />
+      <span className="tile__data">{users === null ? "-" : `${users} users online`}</span>
+    </a>
+  );
+}

+ 20 - 0
src/components/tiles/TerrAssumptions.jsx

@@ -0,0 +1,20 @@
+import React, { useState } from "react";
+import useJsonHealthCheck from "../../hooks/useJsonHealthCheck";
+import { StatusMessage, UNKNOWN, OK, BAD, FAILED } from "../shared/StatusMessage";
+
+export default () => {
+  const [health, setHealth] = useState(UNKNOWN);
+  useJsonHealthCheck(
+    "https://kirkleon.ddns.net/terrassumptions/api",
+    () => setHealth(OK),
+    () => setHealth(BAD),
+    () => setHealth(FAILED),
+  );
+  
+  return (
+    <a className="tile" href="https://kirkleon.ddns.net/terrassumptions/">
+      <span className="tile__title">TerrAssumptions</span>
+      <StatusMessage health={health} />
+    </a>
+  );
+}

+ 29 - 0
src/hooks/useJsonHealthCheck.js

@@ -0,0 +1,29 @@
+import { useEffect, useCallback } from "react";
+
+export default (url, handleOk, handleFailed, handleError, ms=20000) => {
+  const callbackOk = useCallback(handleOk, []);
+  const callbackFailed = useCallback(handleFailed, []);
+  const callbackError = useCallback(handleError, []);
+  useEffect(() => {
+    const checkServer = async () => {
+      try {
+        const res = await fetch(url);
+        if (res.ok) {
+          const js = await res.json();
+          callbackOk(js);
+        } else {
+          callbackFailed();
+        }
+      }
+      catch (err) {
+        callbackError();
+      }
+    }
+
+    checkServer();
+
+    const interval = setInterval(checkServer, ms);
+
+    return () => clearInterval(interval);
+  }, [url, callbackOk, callbackFailed, callbackError, ms]);
+};