Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(unlock-app): Improve event handling consistency across components #15551

Merged
merged 5 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading