Skip to content

Commit

Permalink
fix(unlock-app): Improve event handling consistency across components (
Browse files Browse the repository at this point in the history
…#15551)

* improve event collection drawer

* clean up

* add event date formatter util

* consume util

* type corrections
  • Loading branch information
0xTxbi authored Feb 24, 2025
1 parent 620f743 commit 9762cd3
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 120 deletions.
69 changes: 16 additions & 53 deletions unlock-app/src/components/content/event/EventDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Icon,
minifyAddress,
} from '@unlock-protocol/ui'
import { getEventDate, getEventEndDate, getEventUrl } from './utils'
import { getEventUrl } from './utils'
import { useEventOrganizer } from '~/hooks/useEventOrganizer'
import { useEventOrganizers } from '~/hooks/useEventOrganizers'
import dayjs from 'dayjs'
Expand All @@ -22,6 +22,7 @@ import { useEventVerifiers } from '~/hooks/useEventVerifiers'
import { EventDefaultLayout } from './Layout/EventDefaultLayout'
import { EventBannerlessLayout } from './Layout/EventBannerlessLayout'
import { EventsLayout } from './Layout/constants'
import { formatEventDates } from '~/utils/formatEventDates'

interface EventDetailsProps {
event: Event
Expand All @@ -44,7 +45,7 @@ export const EventDetails = ({
}: EventDetailsProps) => {
const router = useRouter()

// Check if the user is one of the lock manager
// Check if the user is one of the lock managers
const { data: isOrganizer } = useEventOrganizer({
checkoutConfig,
})
Expand All @@ -54,9 +55,7 @@ export const EventDetails = ({
{ initialData: eventProp }
)

const eventUrl = getEventUrl({
event,
})
const eventUrl = getEventUrl({ event })

const { data: organizers } = useEventOrganizers({
checkoutConfig,
Expand All @@ -75,58 +74,22 @@ export const EventDetails = ({
)
}

const eventDate = getEventDate(event.ticket) // Full date + time of event
const eventEndDate = getEventEndDate(event.ticket)
// Format the event dates and get boolean flags
const {
startDate,
startTime,
endDate,
endTime,
eventDate,
eventEndDate,
hasDate,
hasLocation,
} = formatEventDates(event.ticket, language())

const hasPassed = eventEndDate
? dayjs().isAfter(eventEndDate)
: dayjs().isAfter(eventDate)

const isSameDay = dayjs(eventDate).isSame(eventEndDate, 'day')

const startDate = eventDate
? eventDate.toLocaleDateString(undefined, {
timeZone: event.ticket.event_timezone,
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
})
: null

const startTime =
eventDate && event.ticket.event_start_time
? eventDate.toLocaleTimeString(language(), {
timeZone: event.ticket.event_timezone,
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short',
})
: undefined

const endDate =
eventEndDate && eventEndDate && !isSameDay
? eventEndDate.toLocaleDateString(undefined, {
timeZone: event.ticket.event_timezone,
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
})
: null

const endTime =
eventDate && event.ticket.event_end_time && eventEndDate && isSameDay
? eventEndDate.toLocaleTimeString(language(), {
timeZone: event.ticket.event_timezone,
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short',
})
: null

const hasLocation = (event.ticket.event_address || '')?.length > 0
const hasDate = startDate || startTime || endDate || endTime

const coverImage = event.ticket.event_cover_image

const layoutProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react'
import { Event, PaywallConfigType } from '@unlock-protocol/core'
import AddToCalendarButton from '../AddToCalendarButton'
import TweetItButton from '../TweetItButton'
Expand All @@ -21,7 +20,7 @@ type EventBannerlessProps = {
config: PaywallConfigType
}
hasLocation: boolean
hasDate: string | null
hasDate: boolean
organizers: string[] | undefined
startDate: string | null
endDate: string | null
Expand Down Expand Up @@ -51,7 +50,7 @@ export const EventBannerlessLayout = ({
<section className="flex justify-between flex-col">
<div className="flex p-1 bg-white sm:p-2 sm:w-96 sm:h-96 sm:rounded-3xl rounded-xl border">
<img
// @ts-expect-error propery 'title' does not exist on type 'Event'
// @ts-expect-error property 'title' does not exist on type 'Event'
alt={event.title}
className="object-cover w-full m-auto aspect-1 sm:rounded-2xl rounded-lg"
src={event.image}
Expand Down Expand Up @@ -100,7 +99,7 @@ export const EventBannerlessLayout = ({
{hasDate && (
<EventDetail label="Date" icon={CalendarIcon}>
<div
// @ts-expect-error propery 'background_color' does not exist on type 'Event'
// @ts-expect-error property 'background_color' does not exist on type 'Event'
style={{ color: `#${event.background_color}` }}
className="flex flex-col text-lg font-normal text-brand-dark"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import { useState } from 'react'
import { CoverImageDrawer } from '../CoverImageDrawer'
import { Event, PaywallConfigType } from '@unlock-protocol/core'
import AddToCalendarButton from '../AddToCalendarButton'
Expand All @@ -22,7 +22,7 @@ type EventDefaultLayoutProps = {
config: PaywallConfigType
}
hasLocation: boolean
hasDate: string | null
hasDate: boolean
coverImage: string
refetch: () => void
organizers: string[] | undefined
Expand Down Expand Up @@ -75,7 +75,7 @@ export const EventDefaultLayout = ({
<section className="flex justify-between flex-col sm:flex-row">
<div className="flex p-1 bg-white sm:p-2 sm:w-48 sm:h-48 sm:rounded-3xl rounded-xl border">
<img
// @ts-expect-error protperty 'title' does not exist on type 'Event'
// @ts-expect-error property 'title' does not exist on type 'Event'
alt={event.title}
className="object-cover w-full m-auto aspect-1 sm:rounded-2xl rounded-lg"
src={event.image}
Expand Down Expand Up @@ -110,7 +110,7 @@ export const EventDefaultLayout = ({
{hasDate && (
<EventDetail label="Date" icon={CalendarIcon}>
<div
// @ts-expect-error protperty 'background_color' does not exist on type 'Event'
// @ts-expect-error property 'background_color' does not exist on type 'Event'
style={{ color: `#${event.background_color}` }}
className="flex flex-col text-lg font-normal text-brand-dark"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react'
import { Event } from './EventsCollectionDetailContent'
import ReactMarkdown from 'react-markdown'
import { Button, Drawer, Placeholder } from '@unlock-protocol/ui'
import { AiOutlineCalendar as CalendarIcon } from 'react-icons/ai'
Expand All @@ -9,35 +8,51 @@ import { useEventOrganizers } from '~/hooks/useEventOrganizers'
import Hosts from '../event/Hosts'
import { EventDetail } from '../event/EventDetail'
import { EventLocation } from '../event/EventLocation'
import dayjs from 'dayjs'
import AddToCalendarButton from '../event/AddToCalendarButton'
import { FaExternalLinkAlt } from 'react-icons/fa'
import Link from 'next/link'
import PastEvent from '../event/Layout/PastEvent'
import RemoveFromCollectionButton from './RemoveFromCollectionButton'
import { getEventAttributes } from '~/utils/eventCollections'
import { useEventOrganizer } from '~/hooks/useEventOrganizer'
import { TbSettings } from 'react-icons/tb'
import { useEvent } from '~/hooks/useEvent'
import { toFormData } from '~/components/interface/locks/metadata/utils'
import { Event } from '@unlock-protocol/core'
import { getEventUrl } from '../event/utils'
import { formatEventDates } from '~/utils/formatEventDates'

interface EventDetailDrawerProps {
collectionSlug: string | undefined
isOpen: boolean
setIsOpen: (isOpen: boolean) => void
event: Event | null
selectedEvent: any
isManager: boolean
}

export const EventDetailDrawer: React.FC<EventDetailDrawerProps> = ({
collectionSlug,
isOpen,
setIsOpen,
event,
selectedEvent,
isManager,
}) => {
const { data: checkoutConfig, isPending: isCheckoutConfigPending } =
useCheckoutConfig({
id: event?.checkoutConfigId,
id: selectedEvent?.checkoutConfigId,
})
const { data: eventDetails } = useEvent({
slug: selectedEvent?.slug,
})

// transform the event details into an event object
const event = toFormData({
...eventDetails!,
slug: selectedEvent?.slug,
}) as Event

const eventUrl = getEventUrl({
event,
})

const { data: isEventOrganizer } = useEventOrganizer({
checkoutConfig: checkoutConfig!,
Expand All @@ -49,46 +64,18 @@ export const EventDetailDrawer: React.FC<EventDetailDrawerProps> = ({

if (!event) return null

const { name, data } = event
const { image, description } = data
const { name, image, description } = event

// Format the event dates and get boolean flags
const {
startDate: eventStartDate,
startTime: eventStartTime,
endDate: eventEndDate,
startDate,
startTime,
endDate,
endTime,
timezone,
address,
} = getEventAttributes(event)

const parsedEvent = {
...event.data,
slug: event.slug!,
ticket: {
event_start_date: eventStartDate,
event_end_date: eventEndDate,
event_start_time: eventStartTime,
event_end_time: endTime,
event_timezone: timezone,
event_address: address,
},
}

const eventDate = dayjs.tz(`${eventStartDate} ${eventStartTime}`, timezone)
const eventEndDateObj = dayjs.tz(`${eventEndDate} ${endTime}`, timezone)

const hasPassed = dayjs().isAfter(eventEndDateObj)

const isSameDay = eventDate.isSame(eventEndDateObj, 'day')

const startDate = eventDate.format('dddd, MMMM D, YYYY')

const endDate = !isSameDay
? eventEndDateObj.format('dddd, MMMM D, YYYY')
: null

const hasLocation = address?.length > 0
const hasDate = startDate || endDate
hasDate,
hasLocation,
hasPassed,
} = formatEventDates(event.ticket)

// close drawer when the event is removed
const handleEventRemove = () => {
Expand Down Expand Up @@ -131,11 +118,8 @@ export const EventDetailDrawer: React.FC<EventDetailDrawerProps> = ({
/>

<div className="flex items-center justify-end gap-0 mt-auto md:gap-2">
<AddToCalendarButton
event={parsedEvent}
eventUrl={event.eventUrl}
/>
<Link href={event.eventUrl} target="_blank">
<AddToCalendarButton event={event} eventUrl={eventUrl} />
<Link href={eventUrl} target="_blank">
<Button variant="borderless-primary">
<FaExternalLinkAlt size={20} width={1} className="mr-2" />
</Button>
Expand All @@ -155,19 +139,22 @@ export const EventDetailDrawer: React.FC<EventDetailDrawerProps> = ({
{/* Date */}
{hasDate && (
<EventDetail compact label="Date" icon={CalendarIcon}>
<div
style={{ color: `#${event.background_color}` }}
className="flex flex-col text-sm font-normal text-brand-dark"
>
{startDate && endDate && (
<span>{dayjs(startDate).format('dddd D MMM YYYY')}</span>
<div className="flex flex-col text-sm font-normal text-brand-dark">
<span>{startDate}</span>
{startTime && <span>{startTime}</span>}
{endDate && (
<>
<span>to</span>
<span>{endDate}</span>
</>
)}
{endTime && <span>{endTime}</span>}
</div>
</EventDetail>
)}

{/* Location */}
{hasLocation && <EventLocation event={event.data} compact />}
{hasLocation && <EventLocation event={event} compact />}

{isCheckoutConfigPending ? (
<Placeholder.Root>
Expand All @@ -181,8 +168,7 @@ export const EventDetailDrawer: React.FC<EventDetailDrawerProps> = ({
/>
) : (
<PastEvent
// @ts-ignore
event={parsedEvent!}
event={eventDetails!}
checkoutConfig={checkoutConfig!}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
import { FaGithub, FaGlobe, FaXTwitter, FaYoutube } from 'react-icons/fa6'
import { SiFarcaster as FarcasterIcon } from 'react-icons/si'
import AddEventsToCollectionDrawer from './AddEventsToCollectionDawer'
import { EventDetailDrawer } from './EventDetailDrawer'
import { Metadata } from '@unlock-protocol/core'
import CopyUrlButton from '../event/CopyUrlButton'
import TweetItButton from '../event/TweetItButton'
Expand All @@ -28,6 +27,7 @@ import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
import { useConnectModal } from '~/hooks/useConnectModal'
import { useAuthenticate } from '~/hooks/useAuthenticate'
import { EventDetailDrawer } from './EventDetailDrawer'

dayjs.extend(utc)
dayjs.extend(timezone)
Expand Down Expand Up @@ -353,7 +353,7 @@ export default function EventsCollectionDetailContent({
collectionSlug={eventCollection?.slug}
isOpen={isEventDetailDrawerOpen}
setIsOpen={setIsEventDetailDrawerOpen}
event={selectedEvent}
selectedEvent={selectedEvent}
isManager={isManager}
/>
)}
Expand Down
Loading

0 comments on commit 9762cd3

Please sign in to comment.