Skip to content

Commit

Permalink
Merge branch 'main' into update-docs-nav
Browse files Browse the repository at this point in the history
  • Loading branch information
joshbermanssw committed Sep 13, 2024
2 parents 9f37869 + 3311dab commit 7f48670
Show file tree
Hide file tree
Showing 11 changed files with 985 additions and 795 deletions.
7 changes: 3 additions & 4 deletions components/DocumentationNavigation/DocsNavigationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,9 @@ const NavLevel = ({
level === 0
);

const selected = path == slug || (slug == '/docs' && path == '/docs/');
console.log(categoryData.items);
console.log(router.asPath);
const childSelected = hasNestedSlug(categoryData.items, router.asPath);
const selected = path == slug || (slug == '/docs' && path == "/docs/")
const childSelected = hasNestedSlug(categoryData.items, router.asPath)


React.useEffect(() => {
if (
Expand Down
52 changes: 0 additions & 52 deletions components/blocks/Events.template.ts

This file was deleted.

142 changes: 142 additions & 0 deletions components/blocks/Events.template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import type { Template } from 'tinacms'
import { NumberField, NumberFieldPlugin, NumberInput, TextField, wrapFieldsWithMeta } from 'tinacms'
import React from 'react'

const formatTimezoneOption = (value, prefix = "+") => {
return { value: value, label: `GMT ${prefix}${Math.floor(value)}:${value % 1 ? "3" : "0"}0` }
}

const positiveTimezoneList = Array.from(Array(29).keys()).map(value => formatTimezoneOption(value / 2)).reverse()
const negativeTimezoneList = Array.from(Array(24).keys()).map(value =>
{
const tempOption = formatTimezoneOption((value / 2) + 0.5, '-')
return {value: tempOption.value * -1, label: tempOption.label}
})

const timeFormat = Intl.DateTimeFormat('en-US', {
year: "numeric",
month: "short",
day: "numeric",
timeZone: "UTC"
});

const timezoneValidation = (value, data) => {
if (value > 23 || value < 0) {
return "The time should be between 0 (00:00) and 23 (23:00)"
}
if (value && value % 1 != 0) {
return "Only whole numbers should be used."
}
}

export const eventsTemplate: Template = {
label: 'Events',
name: 'events',
ui: {
previewSrc: '/img/blocks/events.png',
},
fields: [
{ name: 'title', label: 'Title', type: 'string' },
{
name: 'cardItems',
label: 'Card Items',
type: 'object',
list: true,
ui: {
itemProps: (item) => ({
key: item.id,
label: item.headline,
}),
},
// https://tina.io/docs/reference/toolkit/fields/date/#datetimepickerprops and https://tina.io/docs/reference/toolkit/fields/number/
// @ts-ignore: type error as utc, options and step fields aren't formally recognised but valid as per docs (linked above)
fields: [
{ name: 'headline', label: 'Headline', type: 'string' },
{
name: 'startDate',
label: 'Start Date',
type: 'datetime',
description:
'Enter date in the timezone of the event.',
ui: {
utc: true,
format: (value, name, field) => value && timeFormat.format(new Date(Date.parse(value)))
},
},
{
name: 'startTime',
label: 'Start Time',
type: 'number',
description:
"Enter start time in the timezone of the event. (e.g. if the event starts at 9:00am, enter '9')",
ui: {
step: 1,
validate: timezoneValidation
},
},
{
name: 'endDate',
label: 'End Date',
type: 'datetime',
description:
'Note this field is not mandatory. Leave blank for a 1 day event. Enter date in the timezone of the event.',
ui: {
utc: true,
format: (value, name, field) => value && timeFormat.format(new Date(Date.parse(value)))
},
},
{
//Note the below is just a UI aspect for clarity on how a new event can be specified
name: 'endTime',
label: 'End Time',
type: 'string',
description:
'This is locked to midnight on the end date of the event.',
ui: {
format: (value) => "11:59pm",
component: (props) => {
return <div className="mb-4 relative">
<div className="z-50 absolute cursor-not-allowed w-full h-full top-0 left-0"/>
<div className="opacity-50">
{TextField(props)}
</div>
</div>
}
},
},
{
name: 'timezone',
label: 'Timezone',
type: 'number',
description:
'Please select the timezone the event is being held in. GMT and UTC are analagous.',
ui: {
parse: (value) => Number(value),
component: 'select',
options: [
...positiveTimezoneList,
...negativeTimezoneList
]
}
},
{ name: 'location', label: 'Location', type: 'string' },
{ name: 'image', label: 'Image', type: 'image' },
{ name: 'link', label: 'URL', type: 'string' },
{
name: 'markerLAT',
label: 'Marker Latitude',
type: 'number',
description:
'Note this field corresponds to the Latitude position of the marker on the globe.',
},
{
name: 'markerLONG',
label: 'Marker Longitude',
type: 'number',
description:
'Note this field corresponds to the Longitude position of the marker on the globe.',
},
],
},
],
}
86 changes: 32 additions & 54 deletions components/blocks/Events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,66 +21,39 @@ const Card = ({ cardItem, onHover }) => {
}
}

const calculateDaysUntilEvent = (date) => {
const eventDate = new Date(date)
const currentDate = new Date()
eventDate.setHours(0, 0, 0, 0)
currentDate.setHours(0, 0, 0, 0)

const timeDifference = eventDate.getTime() - currentDate.getTime()
const daysDifference = Math.ceil(timeDifference / (1000 * 60 * 60 * 24))
return daysDifference
}

const isDateInRange = (startDate, endDate) => {
const start = new Date(startDate)
const end = new Date(endDate)
const current = new Date()
start.setHours(0, 0, 0, 0)
end.setHours(0, 0, 0, 0)
current.setHours(0, 0, 0, 0)

return current >= start && current <= end
}

const formatStartDate = (date) => {
const d = new Date(date)
return `${d.getDate()}${getOrdinalSuffix(d.getDate())} ${format(d, 'MMM')}`
}

const formatDateRange = (start, end) => {
const startDate = new Date(start)
const endDate = new Date(end)
if (startDate.getMonth() === endDate.getMonth()) {
return `${startDate.getDate()}${getOrdinalSuffix(
startDate.getDate()
)} - ${endDate.getDate()}${getOrdinalSuffix(endDate.getDate())} ${format(
endDate,
'MMM'
)}`
}
return `${startDate.getDate()}${getOrdinalSuffix(
startDate.getDate()
)} ${format(startDate, 'MMM')} - ${endDate.getDate()}${getOrdinalSuffix(
endDate.getDate()
)} ${format(endDate, 'MMM')}`
const dateFormat = (start, end?): string => {
//Gets the start date in the event time, which is "UTC" from how it's stored
const startDay = `${new Date(start).getUTCDate() + getOrdinalSuffix(new Date(start).getUTCDate())}`
const startMonth = format(new Date(start), 'MMM')
//Gets the end date in the event time, which is "UTC" from how it's stored
const endDateAndHyphen = end ? ` - ${new Date(end).getUTCDate() + getOrdinalSuffix(new Date(end).getUTCDate())}` : ''
const endMonth = end ? format(new Date(end), 'MMM') : ''
//Formats the dates into a single string
return `${startDay} ${startMonth == endMonth ? '' : startMonth}${endDateAndHyphen} ${endMonth ?? startMonth}`
}

const displayDate = () => {
if (cardItem.startDate && cardItem.endDate) {
return formatDateRange(cardItem.startDate, cardItem.endDate)
} else if (cardItem.startDate) {
return formatStartDate(cardItem.startDate)
if (cardItem.startDate) {
return dateFormat(cardItem.startDate, cardItem.endDate)
}
return ''
}

const daysUntilEvent = calculateDaysUntilEvent(cardItem.startDate)
const isPastEvent = daysUntilEvent < 0
//Gets the accurate start date-time in UTC, by applying the offset and event start time.
//Note that getting UTC minutes is actually getting the time in the event timezone, based on how the values are being stored.
const startDateUTC = new Date(Date.parse(cardItem.startDate))
startDateUTC.setUTCMinutes(startDateUTC.getUTCMinutes() + (cardItem.timezone * -60) + ((cardItem.startTime) * 60))
//Gets the provided end date at midnight in UTC, or for one day events the start date is re-used.
const endDateUTC = new Date(Date.parse(cardItem.endDate ?? cardItem.startDate))
endDateUTC.setUTCMinutes(endDateUTC.getUTCMinutes() + (cardItem.timezone * -60) + (24 * 60))
//Calculate the hours until the event/event end by subtracting start and end dates (in UTC) against the current local time (in UTC).
const hoursUntilEvent = Math.ceil((startDateUTC.getTime() - (new Date()).getTime()) / 36e5)
const hoursUntilEventEnd = Math.ceil((endDateUTC.getTime() - (new Date()).getTime()) / 36e5)

const isLiveOrPastEvent = hoursUntilEvent < 0
const isLiveEvent =
cardItem.startDate &&
cardItem.endDate &&
isDateInRange(cardItem.startDate, cardItem.endDate)
hoursUntilEvent <= 0 &&
hoursUntilEventEnd > 0

return (
<div
Expand Down Expand Up @@ -108,11 +81,16 @@ const Card = ({ cardItem, onHover }) => {
<p className="mr-2">{displayDate()}</p>
{isLiveEvent ? (
<span className="bg-teal-100 px-2 rounded text-sm text-teal-700 shadow-lg opacity-60">LIVE</span>
) : isPastEvent ? (
) : isLiveOrPastEvent ? (
<span className="bg-slate-200 px-2 rounded text-sm text-gray-700 shadow-lg opacity-60">DONE</span>
) : (
<span className="bg-teal-100 px-2 rounded text-sm text-teal-700 shadow-lg opacity-60">
{daysUntilEvent} DAY{daysUntilEvent > 1 ? 'S' : ''} TO GO
{
hoursUntilEvent >= 24 ?
`${Math.floor(hoursUntilEvent / 24)} DAY${hoursUntilEvent >= 48 ? 'S' : ''} TO GO`
:
`${hoursUntilEvent} HOUR${hoursUntilEvent > 1 ? 'S' : ''} TO GO`
}
</span>
)}
</div>
Expand Down
Loading

0 comments on commit 7f48670

Please sign in to comment.