diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5660f81 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ \ No newline at end of file diff --git a/package.json b/package.json index 17699b6..519e36d 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@material-ui/core": "^3.5.1", + "clsx": "^1.0.4", "date-fns": "^2.7.0", "react": "^16.6.3", "react-dom": "^16.6.3", diff --git a/src/App.js b/src/App.js index 5f5ccfd..ba371f2 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,25 @@ -import React, { createContext } from "react"; +import React, { useState, useEffect } from "react"; import Header from "./Header.js"; import Table from "./Table"; import Map from "./Map"; -const App = () => ( +const App = () => { + let [now, setNow] = useState(new Date()); + window.setTime = setNow; + useEffect(() => { + let interval = setInterval(() => { + setNow(new Date()); + }, 10000); + return () => { + clearInterval(interval); + } + }, []); + return ( <>
- +
-); +)}; export default App; diff --git a/src/Table.js b/src/Table.js index 7f7fbd6..9adbe9e 100644 --- a/src/Table.js +++ b/src/Table.js @@ -1,7 +1,14 @@ -import React, { Fragment } from "react"; +import React, { + Fragment, + useState, + useLayoutEffect, + useMemo, + useEffect +} from "react"; import styles from "./Table.module.css"; import { events } from "./Stroll.js"; import { parse } from "date-fns"; +import clsx from "clsx"; /** * * @@ -14,9 +21,6 @@ function getTime(date) { hour12: true }); } -function range(size, startAt = 0) { - return [...Array(size).keys()].map(i => i + startAt); -} function ConvertEventObjToEvent({ time, title }) { let timeArray = time.split("-"); let start = parse( @@ -37,31 +41,77 @@ function ConvertEventObjToEvent({ time, title }) { endAsString: getTime(end) }; } -export default function() { - const timeRange = range(5, 5).map(a =>
{a}
); +function Event({ title, startAsString, endAsString}) { + const [showBackground, setShowBackground] = useState(true); + + useEffect(() => { + setTimeout(() => { + setShowBackground(true); + }, 0); + }, [title, startAsString, endAsString]); + useEffect(() => { + setTimeout(() => { + setShowBackground(false); + }, 300); + }, [title, startAsString, endAsString]); + if (!title || !startAsString || !endAsString) { + return ( +
+ ); + } + return ( +
+ {startAsString} - {endAsString} + {"\n"} + {title} +
+ ); +} +export default function({ now }) { const titleRow = ( <> -
Events
- {timeRange} +
Current Events
+
Upcoming
); - const eventRows = Object.entries(events).map(([item, eventObjs], index) => { - let eventsMaps = eventObjs - .map(ConvertEventObjToEvent) - .map(({ start, end, title, startAsString, endAsString }) => ( -
- {startAsString} - {endAsString}{"\n"}{title} -
- )); - while(eventsMaps.length < timeRange.length) { - eventsMaps = eventsMaps.concat([
]) - } + let sortedEvents = useMemo( + () => + Object.entries(events).map(([item, eventObjs]) => { + let sortedEventObjects = eventObjs + .map(ConvertEventObjToEvent) + .sort((a, b) => a.start - b.start); + return { item, sortedEventObjects }; + }), + [events] + ); + const eventRows = sortedEvents.map(({ item, sortedEventObjects }) => { + let eventsMaps = sortedEventObjects.reduce( + (accum, current) => { + if (!accum.current && now >= current.start && now <= current.end) { + accum.current = current; + return accum; + } + if (!accum.upcoming && current.end > now) { + accum.upcoming = current; + } + return accum; + }, + { current: null, upcoming: null } + ); + return ( -
#{index}
{item.replace(",", "\n").replace("\n ", "\n")}
- {eventsMaps} + {} + {}
); }); diff --git a/src/Table.module.css b/src/Table.module.css index 19b2354..c5c9b8a 100644 --- a/src/Table.module.css +++ b/src/Table.module.css @@ -41,14 +41,21 @@ } */ .eventContainer { display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr 1fr; row-gap: .8rem; font-size: .8em; white-space: pre-wrap; overflow-y: scroll; height: 42vh; - padding-top: .5em; + padding: .5em .5em; } .eventContainer > * { border-bottom: solid 1px #bdbdbd ; +} +.event { + background-color: #339966; +} +.event.white { + transition: background ease-out 2s; + background-color: inherit; } \ No newline at end of file diff --git a/src/TableOld.js b/src/TableOld.js index 7a82b67..323609f 100644 --- a/src/TableOld.js +++ b/src/TableOld.js @@ -9,6 +9,17 @@ import { TableRow } from "@material-ui/core"; import { events } from "./Stroll.js"; + +function Event({ start, end, title, startAsString, endAsString }) { + return ( + + {startAsString} - {endAsString} + {"\n"} + {title} + + ); +} + /** * * @@ -41,38 +52,51 @@ function ConvertEventObjToEvent({ time, title }) { endAsString: getTime(end) }; } -export default function() { +export default function({ now }) { let rows = Object.entries(events).map(([item, eventObjs], index) => { - let cells = [ - - {index + 1} - {item} - - ]; let eventsMaps = eventObjs .map(ConvertEventObjToEvent) - .map(({ start, end, title, startAsString, endAsString }) => ( - - {startAsString} - {endAsString} {title} - - )); - while(eventsMaps.length < 3) { - eventsMaps = eventsMaps.concat([]) - } - return {cells.concat(eventsMaps)}; + .sort((a, b) => a.start - b.start) + .reduce( + (accum, current) => { + if (!accum.current && now >= current.start && now <= current.end) { + accum.current = current; + } + if (!accum.upcoming && current.end > now) { + accum.upcoming = current; + } + return accum; + }, + { current: null, upcoming: null } + ); + return ( + + {item} + {eventsMaps.current ? ( + + ) : ( + + )} + {eventsMaps.upcoming ? ( + + ) : ( + + )} + + ); }); return ( -
- - - # - Place - 5:45-6:15 - 7:10-8:10 - 8:35-9:45 - - - {rows} -
+ + + + + Place + Current + Upcoming + + + {rows} +
+
); } diff --git a/yarn.lock b/yarn.lock index 1ace100..4df75bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2711,6 +2711,11 @@ clone-deep@^2.0.1: kind-of "^6.0.0" shallow-clone "^1.0.0" +clsx@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.0.4.tgz#0c0171f6d5cb2fe83848463c15fcc26b4df8c2ec" + integrity sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"