aboutsummaryrefslogtreecommitdiff
path: root/src/App.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/App.jsx')
-rw-r--r--src/App.jsx205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/App.jsx b/src/App.jsx
new file mode 100644
index 0000000..7f1f9c3
--- /dev/null
+++ b/src/App.jsx
@@ -0,0 +1,205 @@
+import { useLocation, Routes, Route, Link } from "react-router-dom";
+import { useState, lazy, Suspense } from "react";
+import useFetch from "./useFetch";
+import { DateTime } from "luxon";
+import "./App.css";
+const Index = lazy(() => import("./pages/Index"));
+const Graph = lazy(() => import("./pages/Graph"));
+import { useEffect } from "react";
+
+const App = () => {
+ const url = localStorage.getItem("url") ?? "/data.json";
+
+ let routerLocation = useLocation();
+ useEffect(() => {
+ !window.goatcounter ??
+ window.goatcounter.count({
+ path: location.pathname + location.search + location.hash,
+ });
+ }, [routerLocation]);
+
+ const response = useFetch(url);
+
+ const [timeDifference, setTimeDifference] = useState(1);
+
+ return (
+ <div className="App">
+ <header>
+ <Link to="/">
+ <h1>2020-2021 RIT COVID Dashboard</h1>
+ </Link>
+ </header>
+ <Routes>
+ <Route
+ path="/totalstudents"
+ element={
+ <Suspense fallback={null}>
+ <Graph
+ name={"Total Student Cases"}
+ response={response}
+ dataKey={"total_students"}
+ timeDifference={timeDifference}
+ />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/totalstaff"
+ element={
+ <Suspense fallback={null}>
+ <Graph
+ name={"Total Staff Cases"}
+ response={response}
+ dataKey={"total_staff"}
+ timeDifference={timeDifference}
+ />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/newstudents"
+ element={
+ <Suspense fallback={null}>
+ <Graph
+ name={"New Student Cases"}
+ response={response}
+ dataKey={"new_students"}
+ timeDifference={timeDifference}
+ />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/newstaff"
+ element={
+ <Suspense fallback={null}>
+ <Graph
+ name={"New Staff Cases"}
+ response={response}
+ dataKey={"new_staff"}
+ timeDifference={timeDifference}
+ />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/quarantineoncampus"
+ element={
+ <Suspense fallback={null}>
+ <Graph name={"Quarantine On Campus"} response={response} dataKey={"quarantine_on_campus"} />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/quarantineoffcampus"
+ element={
+ <Suspense fallback={null}>
+ <Graph
+ name={"Quarantine Off Campus"}
+ response={response}
+ dataKey={"quarantine_off_campus"}
+ />
+ </Suspense>
+ }
+ ></Route>
+
+ <Route
+ path="/isolationoncampus"
+ element={
+ <Suspense fallback={null}>
+ <Graph name={"Isolation On Campus"} response={response} dataKey={"isolation_on_campus"} />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/isolationoffcampus"
+ element={
+ <Suspense fallback={null}>
+ <Graph name={"Isolation Off Campus"} response={response} dataKey={"isolation_off_campus"} />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/tests"
+ element={
+ <Suspense fallback={null}>
+ <Graph name={"Tests Administered"} response={response} dataKey={"tests_administered"} />
+ </Suspense>
+ }
+ ></Route>
+ <Route
+ path="/beds"
+ element={
+ <Suspense fallback={null}>
+ <Graph name={"Quarantine/Isolation Bed Availability On-campus"} response={response} dataKey={"beds_available"} />
+ </Suspense>
+ }
+ ></Route>
+
+ <Route
+ exact
+ path="/"
+ element={
+ <Suspense fallback={null}>
+ <Index response={response} timeDifference={timeDifference} />
+ </Suspense>
+ }
+ />
+ </Routes>
+ <footer>
+ <p>
+ By Galen Guyer. Source available on{" "}
+ <a className="BlueLink" href="https://github.com/galenguyer/rit-covid-dashboard">
+ GitHub
+ </a>{" "}
+ (
+ <a className="BlueLink" href="https://github.com/galenguyer/rit-covid-dashboard/issues">
+ Report Issue
+ </a>
+ )
+ </p>
+ <p>
+ <a className="BlueLink" href="https://galenguyer.com/projects/ritcoviddashboard">
+ API Documentation
+ </a>
+ </p>
+ </footer>
+ <script data-goatcounter="https://rcd.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
+ </div>
+ );
+};
+
+const Updated = (props) => {
+ const { loading, lastUpdate, priorUpdate, timeDifference } = props;
+ if (loading) {
+ return <div></div>;
+ }
+
+ return (
+ <div className="Updated">
+ <div className="Latest">
+ Last Updated:{" "}
+ {lastUpdate.toLocaleString({
+ weekday: "long",
+ month: "long",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+ </div>
+ <div className="Prior">
+ Prior Update:{" "}
+ {priorUpdate.toLocaleString({
+ weekday: "long",
+ month: "long",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit",
+ })}{" "}
+ ({timeDifference == 1 ? "one weekday ago" : timeDifference == 5 ? "one week ago" : "two weeks ago"})
+ </div>
+ </div>
+ );
+};
+
+export default App;