Skip to content

Commit

Permalink
added runsheet to site
Browse files Browse the repository at this point in the history
  • Loading branch information
amykapernick committed Mar 5, 2024
1 parent 262e9cd commit efb7b97
Show file tree
Hide file tree
Showing 12 changed files with 390 additions and 4 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@clerk/nextjs": "^4.29.7",
"@sentry/nextjs": "^7.100.1",
"calendar-link": "^2.6.0",
"date-fns": "^3.3.1",
"fathom-client": "^3.6.0",
"next": "^14.1.0",
"notion-to-md": "^3.1.1",
Expand All @@ -48,4 +49,4 @@
"react-router-dom": "^6.22.0",
"showdown": "^2.1.0"
}
}
}
18 changes: 18 additions & 0 deletions src/app/runsheet/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { SignOutButton } from "@clerk/nextjs";
import FetchData from "@components/parts/fetchRunsheet";

export default async function Runsheet ()
{


return (
<>
<h2 id="runsheet">Runsheets</h2>
<p>You can print these off for easy reference.</p>
<FetchData />
<span className="signout">
<SignOutButton>Log Out</SignOutButton>
</span>
</>
)
}
4 changes: 2 additions & 2 deletions src/components/parts/details/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import FrameTop from '@img/frame_top.png'
import Image from 'next/image'
import Monogram from '@img/monogram.svg'
import Map from '@img/map.png'
import { ics, CalendarEvent } from 'calendar-link'
import { ics, CalendarEvent, google } from 'calendar-link'

import styles from './styles.module.css'

Expand All @@ -17,7 +17,7 @@ const Content = ({ data, children }: { data: string, children: any }) =>
location: process.env.NEXT_PUBLIC_EVENT_LOCATION as string,
}

const calendarButtons = `<span class=${ styles.buttons }><a filename="event.ics" download href="${ ics(event) }" target="_blank">Add to Calendar</a></span>`
const calendarButtons = `<span class=${ styles.buttons }><a filename="event.ics" download href="${ ics(event) }" target="_blank">Add to Calendar</a></span><span class=${ styles.buttons }><a filename="event.ics" download href="${ google(event) }" target="_blank">Google Calendar</a></span>`

const pageContent = new Converter().makeHtml(data)
const sections = pageContent.replace('{{calendar_links}}', calendarButtons).replace('{{map}}', `<img src=${ Map.src } alt="Linked Map to Location" />`).replaceAll('<a href="', '<a target="_blank" href="').split('<hr />\n')
Expand Down
59 changes: 59 additions & 0 deletions src/components/parts/fetchRunsheet/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Client } from '@notionhq/client'
import { currentUser } from '@clerk/nextjs';
import type { NotionGuest } from "@ts/people";
import type { User } from "@clerk/nextjs/server";
import { TrackEvent } from "@parts/fathom";
import GuestRunsheets from "@parts/guestRunsheets";
import { NotionRunsheetEvent, NotionStakeholder } from '@ts/runsheet';

const FetchData = async () =>
{
const { emailAddresses } = await currentUser() as User;
const notion = new Client({
auth: process.env.NOTION_API_KEY
})
const data = await notion.databases.query({
database_id: process.env.GUEST_DB ?? '',
filter: {
property: 'GokD',
email: {
equals: emailAddresses[0].emailAddress.toLowerCase()
}
}
})
const guest = data.results?.[0] as unknown as NotionGuest
const runsheetEvents: any = await notion.databases.query({
database_id: process.env.RUNSHEET_DB ?? '',
filter: {
property: 'Guests',
rollup: {
any: {
relation: {
contains: guest.id
}
}
}
}
})
const stakeholders = await notion.databases.query({
database_id: process.env.STAKEHOLDER_DB ?? '',
filter: {
property: 'Invitations',
relation: {
contains: guest.id
}
}
})

return (
<>
{emailAddresses[0].emailAddress.toLowerCase() && <TrackEvent name="Signed In" />}
<GuestRunsheets
runsheetEvents={runsheetEvents?.results as any as NotionRunsheetEvent[]}
stakeholders={stakeholders?.results as any as NotionStakeholder[]}
/>
</>
)
}

export default FetchData
1 change: 0 additions & 1 deletion src/components/parts/footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Image from 'next/image'
import FooterImage from '@img/footer_image.jpg'
import styles from './styles.module.css'
// import FrameBottom from '@img/frame_bottom.svg'
import FrameBottom from '@img/frame_bottom.png'

const Footer = () =>
Expand Down
44 changes: 44 additions & 0 deletions src/components/parts/guestRunsheets/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { NotionRunsheetEvent, RunsheetEvent, NotionStakeholder } from "@ts/runsheet"
import Runsheet from "@parts/runsheet"
import { parseISO } from "date-fns"

type GuestRunsheetsProps = {
runsheetEvents: NotionRunsheetEvent[]
stakeholders: NotionStakeholder[]
}

const GuestRunsheets = (props: GuestRunsheetsProps) =>
{
const { runsheetEvents = [], stakeholders = [] } = props
const events: Record<string, RunsheetEvent> = {}

runsheetEvents.forEach(event =>
{
console.log({ ...event })

events[event.id] = {
name: event.properties.Name.title[0].plain_text,
tags: event.properties.Tags.multi_select.map(tag => tag.name),
start: parseISO(event.properties.Date.date.start),
end: event.properties.Date.date.end ? parseISO(event.properties.Date.date.end) : null,
notes: event.properties.Notes.rich_text.map(note => note.plain_text).join('\n')
}
})

return (
<>
{stakeholders?.map(({ id, properties }) => (
<Runsheet
key={id}
stakeholder={{
name: properties?.Title?.rich_text[0]?.plain_text || properties.Name.title[0].plain_text,
events: properties.Runsheet.relation.map((event: { id: string }) => events[event.id]).sort((a, b) => a.start.getTime() - b.start.getTime())
}}
/>
))}
</>
)
}

export default GuestRunsheets

87 changes: 87 additions & 0 deletions src/components/parts/runsheet/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { RunsheetEvent, Stakeholder } from "@ts/runsheet"
import styles from './styles.module.css'
import { format } from "date-fns"
import Calendar from '@img/icons/calendar.svg'
import { ics } from "calendar-link"

type RunsheetProps = {
stakeholder: Stakeholder
}

const Runsheet = (props: RunsheetProps) =>
{
const { stakeholder } = props
const days: Record<string, RunsheetEvent[]> = {}
let eventsCount = 0

stakeholder.events.forEach(event =>
{
const day = format(event.start, 'EEEE, dd MMM')
if (!days[day]) days[day] = []
days[day].push(event)
})

return (
<article className={styles.runsheet} data-name={stakeholder.name}>
<h3 className={styles.person}>{stakeholder.name}</h3>
{Object.entries(days).map(([day, events]) =>
{
let newPage = false
eventsCount += (events.length + 3)

if (eventsCount > 18)
{
newPage = true
eventsCount = 0
}

return (
<section key={day} data-page={newPage}>
<span className={styles.person_name}>{stakeholder.name}</span>
<h4 className={styles.day}>{day}</h4>
<table className={styles.timetable}>
<thead>
<tr>
<th>Start</th>
<th>End</th>
<th>Description</th>
<th>Notes</th>
<th className="no-print">Calendar</th>
</tr>
</thead>
<tbody>
{events.map((event: RunsheetEvent) => (
<tr key={event.name}>
<td>{format(event.start, 'h:mm aaa')}</td>
<td>{event?.end && format(event.end, 'hh:mm aaa')}</td>
<td>{event.name}</td>
<td><small>{event?.notes}</small></td>
<td className="no-print">
<a
download={`${ event.name }.ics`}
href={ics({
title: event.name,
start: event.start.toISOString(),
end: event.end?.toISOString() ?? event.start.toISOString(),
description: ""
})}
target="_blank"
className={styles.calendar}
>
<Calendar />
<span className="sr-only">Add to Calendar</span>
</a>
</td>
</tr>
))}
</tbody>
</table>
</section>
)
})}
</article>
)
}

export default Runsheet

55 changes: 55 additions & 0 deletions src/components/parts/runsheet/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.runsheet {
max-width: 800px;
margin: 0 auto;
text-transform: none;
}

.person, .person_name {
text-align: left;
font-family: $font_script;
font-size: 4em;
color: $green;
line-height: 1;
margin-bottom: -0.5em;
font-weight: 600;
}

.person_name {
display: none;
}

.calendar {
display: block;
text-align: center;

& svg {
height: 1.2em;
width: auto;
}
}

.day {
font-size: 2em;
margin-bottom: 0.5em;
}

.timetable {
text-align: left;
width: 100%;

& thead {
font-family: $font_headings;
background: $green;
color: $white;
}

& td, & th {
padding: 0.7em;
}

& tr {
&:nth-child(2n) {
background: $green_light;
}
}
}
4 changes: 4 additions & 0 deletions src/styles/global/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ body {
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}

@media print {
@import './print';
}
31 changes: 31 additions & 0 deletions src/styles/global/print.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@page {
size: A5;
}

body > *:not(article[class*="runsheet"]) {
display: none;
}

article[class*="runsheet"] {
font-size: 12px;

& h3 {
margin-top: 0;
page-break-before: always;
display: none;
}

& section {
page-break-inside: avoid;

&:first-of-type, &[data-page="true"] {
& span[class*="person_name"] {
display: block;
}
}
}

& .no-print {
display: none;
}
}
Loading

0 comments on commit efb7b97

Please sign in to comment.