-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import localFont from "next/font/local"; | ||
import { useEffect, useState } from "react"; | ||
import React from "react"; | ||
|
||
const latoFont = localFont({ | ||
src: "../../../public/fonts/lato.woff2", | ||
display: "swap", | ||
variable: "--font-lato", | ||
}); | ||
|
||
function padTime(num: number): string { | ||
return num.toString().padStart(2, "0"); | ||
} | ||
|
||
function TVClock() { | ||
const [time, setTime] = useState({ | ||
hours: 0, | ||
minutes: 0, | ||
seconds: 0, | ||
}); | ||
|
||
useEffect(() => { | ||
const updateClock = setInterval(() => { | ||
const date = new Date( | ||
new Date().toLocaleString("en-US", { | ||
timeZone: "America/Los_Angeles", | ||
}) | ||
); | ||
setTime({ | ||
hours: date.getHours(), | ||
minutes: date.getMinutes(), | ||
seconds: date.getSeconds(), | ||
}); | ||
}, 100); | ||
return () => { | ||
clearInterval(updateClock); | ||
}; | ||
}, []); | ||
|
||
return ( | ||
<div className="grid place-items-center text-center mx-5"> | ||
<div className="grid grid-flow-col gap-4 md:gap-12 text-center md:auto-cols-max"> | ||
<div> | ||
<span className="font-bold text-xl sm:text-2xl md:text-4xl lg:text-7xl text-dc-teal mr-1 font-mono"> | ||
{padTime(time.hours)} | ||
</span> | ||
<span className={latoFont.className}>hours</span> | ||
</div> | ||
<div> | ||
<span className="font-bold text-xl sm:text-2xl md:text-4xl lg:text-7xl text-dc-yellow mr-1 font-mono "> | ||
{padTime(time.minutes)} | ||
</span> | ||
<span className={latoFont.className}>minutes</span> | ||
</div> | ||
<div> | ||
<span className="font-bold text-xl sm:text-2xl md:text-4xl lg:text-7xl text-dc-red mr-1 font-mono"> | ||
{padTime(time.seconds)} | ||
</span> | ||
<span className={latoFont.className}>seconds</span> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default TVClock; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import TVEvents from "./TVEvents"; | ||
import React from "react"; | ||
|
||
function TV({ events }: { events: EventData[] }) { | ||
return <TVEvents events={events} />; | ||
} | ||
|
||
export default TV; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { eventTime } from "@/lib/utils/dates"; | ||
import React from "react"; | ||
|
||
function TVEventCell({ event }: { event: EventData }) { | ||
return ( | ||
<div className="my-3 ml-2 mr-3"> | ||
<div className="items-center h-min-36 table"> | ||
<div | ||
className={`table-cell px-2 h-full w-3 bg-[${event.color}] rounded-md`} | ||
/> | ||
<div className="ml-5"> | ||
<div className="w-full table-cell"> | ||
<h1 className="text-3xl font-bold text-left break-words"> | ||
{event.title} | ||
</h1> | ||
|
||
<p className="text-lg">{event.speakers}</p> | ||
|
||
<p className="text-xl text-gray-400">{event.location}</p> | ||
<div | ||
className={`rounded-full h-3 w-3 inline-flex mr-2 bg-[${event.color}]`} | ||
/> | ||
<p className="text-base inline-flex">{event.category}</p> | ||
<p className="text-xl text-dc-yellow font-bold"> | ||
{`${eventTime(new Date(event.begin), false)} - ${eventTime( | ||
new Date(event.end) | ||
)}`} | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default TVEventCell; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import { useEffect, useState } from "react"; | ||
import { useRouter } from "next/router"; | ||
import TVClock from "../clock/TVClock"; | ||
import TVEventCell from "./TVEventCell"; | ||
import localFont from "next/font/local"; | ||
import Theme from "@/lib/utils/theme"; | ||
import { dateGroupTitle, eventDay } from "@/lib/utils/dates"; | ||
import React from "react"; | ||
|
||
const dcFont = localFont({ | ||
src: "../../../public/fonts/lato.woff2", | ||
display: "swap", | ||
variable: "--font-freeway", | ||
}); | ||
|
||
function TVEvents({ events }: { events: EventData[] }) { | ||
const [filteredEvents, setFilteredEvents] = useState< | ||
Map<string, EventData[]> | ||
>(new Map()); | ||
|
||
const theme = new Theme(); | ||
const router = useRouter(); | ||
const { l, t, debug } = router.query; | ||
|
||
useEffect(() => { | ||
const groupedDates = ( | ||
displayEvents: EventData[] | ||
): Map<string, EventData[]> => | ||
displayEvents | ||
.sort((a, b) => a.beginTimestampSeconds - b.beginTimestampSeconds) | ||
.reduce((group, e) => { | ||
const day = eventDay(new Date(e.begin)); | ||
const groups = group.get(day) ?? []; | ||
groups.push(e); | ||
group.set(day, groups); | ||
return group; | ||
}, new Map<string, EventData[]>()); | ||
|
||
const filterEvents = () => { | ||
const filterTag = Number(l) || 46166; | ||
|
||
return groupedDates( | ||
events.filter((e) => { | ||
if (!e.tags.map((t) => t.id).includes(filterTag)) { | ||
return false; | ||
} | ||
|
||
const future = new Date(); | ||
// eslint-disable-next-line no-constant-binary-expression | ||
const hoursToAdd = Number(t ?? 6) ?? 6; | ||
future.setHours(future.getHours() + hoursToAdd); | ||
|
||
const now = new Date(); | ||
|
||
const begin = new Date(e.begin).getTime(); | ||
|
||
if (begin >= now.getTime() && begin <= future.getTime()) { | ||
return true; | ||
} | ||
|
||
return debug ? true : false; | ||
}) | ||
); | ||
}; | ||
|
||
setFilteredEvents(filterEvents()); | ||
|
||
const pageScroll = () => { | ||
window.scrollBy({ | ||
top: 45, | ||
left: 0, | ||
behavior: "smooth", | ||
}); | ||
}; | ||
|
||
const scrollPageInt = setInterval(() => { | ||
setFilteredEvents(filterEvents()); | ||
const scroll = setInterval(() => { | ||
pageScroll(); | ||
}, 900); | ||
setTimeout(() => { | ||
window.scrollTo({ top: 0, behavior: "smooth" }); | ||
clearInterval(scroll); | ||
}, 70000); | ||
}, 70100); | ||
return () => { | ||
clearInterval(scrollPageInt); | ||
}; | ||
}, [events, l, t]); | ||
|
||
console.log(filteredEvents); | ||
return ( | ||
<div className="flex justify-end mb-2 mr-14 ml-5"> | ||
<div className="flex-initial w-full mr-2"> | ||
{Array.from(filteredEvents).map(([day, dayEvents]) => ( | ||
<div key={day}> | ||
<div className="date-events"> | ||
<div | ||
className={`border-4 border-white bg-${theme.nextColor} rounded-b-lg`} | ||
> | ||
<p className="text-gray-light text-4xl p-2 ml-1"> | ||
{dateGroupTitle(day)} | ||
</p> | ||
</div> | ||
{dayEvents | ||
.sort( | ||
(a, b) => a.beginTimestampSeconds - b.beginTimestampSeconds | ||
) | ||
.map((event) => ( | ||
<div className="event" key={event.id} aria-hidden="true"> | ||
<TVEventCell event={event} /> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
<div className="flex-initial ml-5 mt-4"> | ||
<div className="sticky top-36 z-100"> | ||
<p | ||
className={`text-center text-9xl mb-10 font-bold ${dcFont.className}`} | ||
> | ||
NFO Node | ||
</p> | ||
<p className="text-xl">Current time:</p> | ||
<TVClock /> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default TVEvents; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import Head from "next/head"; | ||
import TV from "../../components/tv/TV"; | ||
import useSWR from "swr"; | ||
import Loading from "@/components/misc/Loading"; | ||
import Error from "@/components/misc/Error"; | ||
import React from "react"; | ||
import { fetcher, toEventsData } from "@/lib/utils/misc"; | ||
|
||
export default function TVPage() { | ||
const { data, error, isLoading } = useSWR<HTEvent[], Error>( | ||
"/ht/events.json", | ||
fetcher | ||
); | ||
|
||
const { data: tags, isLoading: tagsIsLoading } = useSWR<HTTag[], Error>( | ||
"/ht/tags.json", | ||
fetcher | ||
); | ||
|
||
if (isLoading || tagsIsLoading) { | ||
return <Loading />; | ||
} | ||
|
||
if (data === undefined || error !== undefined) { | ||
return <Error />; | ||
} | ||
|
||
const events = toEventsData(data, tags ?? []); | ||
|
||
return ( | ||
<div> | ||
<Head> | ||
<title>Info Booth</title> | ||
<meta name="description" content="Info Booth" /> | ||
<meta | ||
name="viewport" | ||
content="width=device-width, initial-scale=1, maximum-scale=1" | ||
/> | ||
<link rel="icon" href="/favicon.ico" /> | ||
</Head> | ||
|
||
<main className="mb-20"> | ||
<TV events={events} /> | ||
</main> | ||
</div> | ||
); | ||
} |