aboutsummaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-04-13 19:10:44 -0400
committerGalen Guyer <galen@galenguyer.com>2022-04-13 19:44:24 -0400
commit264e571b0ca34d24f4997c5864a43d4f475e14dc (patch)
tree3ddfb30dbd97dc5c5c3da91a8e1cba4916348190 /src/pages
parent290e1694efacc8bfea62b78538cb9d40003f62f6 (diff)
full version 2 re-write
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/Graph.css4
-rw-r--r--src/pages/Graph.jsx96
-rw-r--r--src/pages/Index.css22
-rw-r--r--src/pages/Index.jsx66
4 files changed, 188 insertions, 0 deletions
diff --git a/src/pages/Graph.css b/src/pages/Graph.css
new file mode 100644
index 0000000..c28c8bd
--- /dev/null
+++ b/src/pages/Graph.css
@@ -0,0 +1,4 @@
+.Title {
+ font-size: 2.0em;
+ margin-top: 24px;
+}
diff --git a/src/pages/Graph.jsx b/src/pages/Graph.jsx
new file mode 100644
index 0000000..6754905
--- /dev/null
+++ b/src/pages/Graph.jsx
@@ -0,0 +1,96 @@
+import { DateTime } from "luxon";
+import {
+ BarChart,
+ Bar,
+ LineChart,
+ Line,
+ CartesianGrid,
+ XAxis,
+ YAxis,
+ Tooltip,
+ ReferenceLine,
+ ResponsiveContainer,
+ Label,
+} from "recharts";
+import GoatCounter from "../components/GoatCounter";
+import "./Graph.css";
+
+const Graph = (props) => {
+ const { name, response, dataKey, timeDifference } = props;
+ const { data, loading, error } = response;
+
+ if (loading) {
+ return <div></div>;
+ }
+
+ const eventStyle = { fill: "#767676" };
+
+ const parsed = data.map((d) => {
+ return {
+ date: DateTime.fromSQL(d["last_updated"], { zone: "UTC" }).setZone(DateTime.local().zoneName).toSeconds(),
+ value: d[dataKey],
+ };
+ });
+
+ return (
+ <div>
+ <div className="Title">{name}</div>
+ <LineChart
+ style={{ marginLeft: "auto", marginRight: "auto" }}
+ width={window.innerWidth > 600 ? 750 : window.innerWidth * 0.9}
+ height={500}
+ margin={{ top: 15, right: 30, left: 0, bottom: 5 }}
+ data={parsed}
+ >
+ <Line type="monotone" dataKey="value" stroke="#CD8508" dot={false} />
+ <ReferenceLine
+ x={1644594525}
+ label={{ value: "Visitor Policy adjusted", angle: -90, style: eventStyle, position: "left" }}
+ />
+ <ReferenceLine
+ x={1647550274}
+ label={{ value: "Mask Mandate dropped", angle: -90, style: eventStyle, position: "left" }}
+ />
+ {}
+ <CartesianGrid strokeDasharray="3 3" />
+ <XAxis
+ dataKey="date"
+ type="number"
+ tickCount={14}
+ domain={["dataMin", "dataMax"]}
+ tick={<CustomizedAxisTick />}
+ height={90}
+ />
+ <YAxis dataKey="value" type="number"></YAxis>
+ <Tooltip content={CustomTooltip} />
+ </LineChart>
+ <GoatCounter />
+ </div>
+ );
+};
+
+const CustomizedAxisTick = ({ x, y, payload }) => {
+ return (
+ <g transform={`translate(${x},${y})`}>
+ <text className="Graph-Label" x={0} y={0} dy={16} textAnchor="end" fill="#666" transform="rotate(-40)">
+ {DateTime.fromSeconds(payload.value).toLocaleString()}
+ </text>
+ </g>
+ );
+};
+
+const CustomTooltip = ({ active, payload, label }) => {
+ if (active) {
+ return (
+ <div className="custom-tooltip bg-white border-orange-300 border-2 rounded-lg p-2">
+ <p className="label">
+ {DateTime.fromSeconds(label).toLocaleString({ weekday: "long", month: "long", day: "2-digit" })}
+ </p>
+ <p className="desc">{payload[0].value}</p>
+ </div>
+ );
+ }
+ return null;
+};
+
+export default Graph;
diff --git a/src/pages/Index.css b/src/pages/Index.css
new file mode 100644
index 0000000..5476eb1
--- /dev/null
+++ b/src/pages/Index.css
@@ -0,0 +1,22 @@
+.Message {
+ margin-top: 24px;
+ font-size: 1.4em;
+}
+
+@media screen and (max-width: 600px) {
+ .Message {
+ display: none;
+ }
+}
+
+.Section .Title {
+ text-align: center;
+ font-size: 1.6em;
+ flex-basis: 100%;
+ margin-top: 48px;
+}
+
+.Cards {
+ display: flex;
+ justify-content: center;
+}
diff --git a/src/pages/Index.jsx b/src/pages/Index.jsx
new file mode 100644
index 0000000..3beb6fd
--- /dev/null
+++ b/src/pages/Index.jsx
@@ -0,0 +1,66 @@
+import Card from "../components/Card";
+import GoatCounter from "../components/GoatCounter";
+import "./Index.css";
+
+const Index = (props) => {
+ const response = props.response;
+ if (response.loading) {
+ return <div>Loading...</div>;
+ }
+
+ const data = response.data;
+
+ const latest = data[data.length - 1];
+ const prior = data[data.length - (1 + props.timeDifference)];
+
+ return (
+ <div>
+ <div>
+ <div className="Message">
+ This dashboard has been refreshed for the new semester. Historical data from the 2020-2021 school
+ year is available at <a href="//2020.ritcoviddashboard.com">2020.ritcoviddashboard.com</a>. Data
+ from the Fall 2021 semester is available at{" "}
+ <a href="//2021.ritcoviddashboard.com">2021.ritcoviddashboard.com</a>.
+ </div>
+ </div>
+ <div className="Section" id="total">
+ <div className="Title">Total Positive Cases Since January 10 (First Day of Classes)</div>
+ <div className="Cards">
+ <Card
+ name="Students"
+ link="/totalstudents"
+ latest={latest["total_students"]}
+ diff={latest["total_students"] - prior["total_students"]}
+ />
+ <Card
+ name="Staff"
+ link="/totalstaff"
+ latest={latest["total_staff"]}
+ diff={latest["total_staff"] - prior["total_staff"]}
+ />
+ </div>
+ </div>
+
+ <div className="Section" id="new">
+ <div className="Title">New Positive Cases From Past 14 Days</div>
+ <div className="Cards">
+ <Card
+ name="Students"
+ link="/newstudents"
+ latest={latest["new_students"]}
+ diff={latest["new_students"] - prior["new_students"]}
+ />
+ <Card
+ name="Staff"
+ link="/newstaff"
+ latest={latest["new_staff"]}
+ diff={latest["new_staff"] - prior["new_staff"]}
+ />
+ </div>
+ </div>
+ <GoatCounter />
+ </div>
+ );
+};
+
+export default Index;