Skip to content

Commit

Permalink
feat(unlock-app): Event layouts (#13869)
Browse files Browse the repository at this point in the history
* Events layout

* Event layout

* Event layout

* Minor changes

* Minor changes

* Minor changes

* reafctored

* removed extra div

---------

Co-authored-by: Julien Genestoux <julien.genestoux@gmail.com>
  • Loading branch information
SVell and julien51 committed May 20, 2024
1 parent f9db1e9 commit cea98b4
Show file tree
Hide file tree
Showing 4 changed files with 332 additions and 123 deletions.
153 changes: 30 additions & 123 deletions unlock-app/src/components/content/event/EventDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BiQrScan as ScanIcon } from 'react-icons/bi'
import { MdAssignmentLate } from 'react-icons/md'
import { useEffect, useState } from 'react'
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { NextSeo } from 'next-seo'
import {
Expand All @@ -10,36 +9,27 @@ import {
Icon,
minifyAddress,
} from '@unlock-protocol/ui'
import AddToCalendarButton from './AddToCalendarButton'
import { TweetItButton } from './TweetItButton'
import { CastItButton } from './CastItButton'
import { CopyUrlButton } from './CopyUrlButton'
import { getEventDate, getEventEndDate, getEventUrl } from './utils'
import { useEventOrganizer } from '~/hooks/useEventOrganizer'
import { useEventOrganizers } from '~/hooks/useEventOrganizers'
import dayjs from 'dayjs'
import { AiOutlineCalendar as CalendarIcon } from 'react-icons/ai'
import {
Event,
PaywallConfigType,
formDataToMetadata,
} from '@unlock-protocol/core'
import { CoverImageDrawer } from './CoverImageDrawer'
import { EventDetail } from './EventDetail'
import { EventLocation } from './EventLocation'
import { RegistrationCard } from './Registration/RegistrationCard'
import { useEvent } from '~/hooks/useEvent'
import { SettingEmail } from '~/components/interface/locks/Settings/elements/SettingEmail'
import { storage } from '~/config/storage'
import { FaUsers } from 'react-icons/fa'
import { TbSettings } from 'react-icons/tb'
import { config } from '~/config/app'
import Hosts from './Hosts'
import removeMd from 'remove-markdown'
import { truncateString } from '~/utils/truncateString'
import { AttendeeCues } from './Registration/AttendeeCues'
import { useEventVerifiers } from '~/hooks/useEventVerifiers'
import ReactMarkdown from 'react-markdown'
import { EventDefaultLayout } from './Layout/EventDefaultLayout'
import { EventBannerlessLayout } from './Layout/EventBannerlessLayout'
import { EventsLayout } from './Layout/constants'

interface EventDetailsProps {
event: Event
Expand All @@ -60,7 +50,6 @@ export const EventDetails = ({
event: eventProp,
checkoutConfig,
}: EventDetailsProps) => {
const [image, setImage] = useState('')
const router = useRouter()

// Check if the user is one of the lock manager
Expand Down Expand Up @@ -163,6 +152,31 @@ export const EventDetails = ({

const coverImage = event.ticket.event_cover_image

const layoutProps = {
event,
checkoutConfig,
hasLocation,
hasDate,
startDate,
startTime,
endDate,
endTime,
eventUrl,
hasPassed,
organizers,
coverImage,
refetch,
}

const renderEventLayout = () => {
switch (event.layout) {
case EventsLayout.Bannerless:
return <EventBannerlessLayout {...layoutProps} />
default:
return <EventDefaultLayout {...layoutProps} />
}
}

return (
<div>
<NextSeo
Expand Down Expand Up @@ -264,115 +278,8 @@ export const EventDetails = ({
</>
)}
</div>

<div className="relative">
<div className="w-full hidden sm:block sm:overflow-hidden bg-slate-200 max-h-80 sm:rounded-3xl">
<img
className="object-cover w-full h-full"
src={coverImage || event.image}
alt="Cover image"
/>
</div>

<CoverImageDrawer
image={image}
setImage={setImage}
checkoutConfig={checkoutConfig}
event={event}
handleClose={() => {
refetch()
}}
/>

<div className="sm:absolute flex sm:flex-col w-full gap-6 px-4 sm:px-10 -bottom-12">
<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
alt={event.title}
className="object-cover w-full m-auto aspect-1 sm:rounded-2xl rounded-lg"
src={event.image}
/>
</div>
<ul className="flex items-center justify-center gap-0 mt-auto md:gap-2">
<li>
<AddToCalendarButton event={event} eventUrl={eventUrl} />
</li>
<li>
<TweetItButton event={event} eventUrl={eventUrl} />
</li>
<li>
<CastItButton event={event} eventUrl={eventUrl} />
</li>
<li>
<CopyUrlButton url={eventUrl} />
</li>
</ul>
</section>
</div>
</div>

<section className="grid items-start grid-cols-1 md:gap-4 md:grid-cols-3 md:mt-16 mt-8">
<div className="flex flex-col col-span-3 gap-4 md:col-span-2">
<h1 className="mt-4 text-3xl font-bold md:text-6xl">
{event.name}
</h1>
<section className="flex flex-col gap-4">
{organizers && organizers.length > 0 && (
<Hosts organizers={organizers} />
)}
<div className="grid grid-cols-1 gap-6 md:p-6 md:grid-cols-2 rounded-xl">
{hasDate && (
<EventDetail label="Date" icon={CalendarIcon}>
<div
style={{ color: `#${event.background_color}` }}
className="flex flex-col text-lg font-normal text-brand-dark"
>
{(startDate || endDate) && (
<span>
{startDate} {endDate && <>to {endDate}</>}
</span>
)}
{startTime && endTime && (
<span>
{startTime} {endTime && <>to {endTime}</>}
</span>
)}
</div>
</EventDetail>
)}
{hasLocation && <EventLocation event={event} />}
</div>
<div className="mt-10">
{event.description && (
<div className="mt-4 markdown">
{/* eslint-disable-next-line react/no-children-prop */}
<ReactMarkdown children={event.description} />
</div>
)}
</div>
</section>
</div>
<div className="flex flex-col gap-4">
{!hasPassed && (
<RegistrationCard
requiresApproval={event.requiresApproval}
checkoutConfig={checkoutConfig}
/>
)}
{hasPassed && (
<Card className="grid gap-4 mt-10 md:mt-0">
<p className="text-lg">
<MdAssignmentLate />
This event is over. It is not possible to register for it
anymore.
</p>
</Card>
)}
<AttendeeCues checkoutConfig={checkoutConfig} />
</div>
</section>
</div>

{renderEventLayout()}
<section className="flex flex-col">
{isOrganizer && (
<div className="grid gap-6 mt-12">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React from 'react'
import { Event, PaywallConfigType } from '@unlock-protocol/core'
import AddToCalendarButton from '../AddToCalendarButton'
import TweetItButton from '../TweetItButton'
import CastItButton from '../CastItButton'
import CopyUrlButton from '../CopyUrlButton'
import Hosts from '../Hosts'
import { EventDetail } from '../EventDetail'
import { EventLocation } from '../EventLocation'
import ReactMarkdown from 'react-markdown'
import { RegistrationCard } from '../Registration/RegistrationCard'
import { Card } from '@unlock-protocol/ui'
import { MdAssignmentLate } from 'react-icons/md'
import { AttendeeCues } from '../Registration/AttendeeCues'
import { AiOutlineCalendar as CalendarIcon } from 'react-icons/ai'

type EventBannerlessProps = {
event: Event
checkoutConfig: {
id?: string
config: PaywallConfigType
}
hasLocation: boolean
hasDate: string | null
organizers: string[] | undefined
startDate: string | null
endDate: string | null
startTime: string | undefined
endTime: string | null
eventUrl: string
hasPassed: boolean
}

export const EventBannerlessLayout = ({
event,
checkoutConfig,
hasLocation,
hasDate,
organizers,
startDate,
endDate,
startTime,
endTime,
eventUrl,
hasPassed,
}: EventBannerlessProps) => {
return (
<div className="md:flex md:flex-row-reverse md:gap-4 md:mt-16 mt-8">
<section className="flex flex-col gap-4">
<div className="flex justify-center w-full">
<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'
alt={event.title}
className="object-cover w-full m-auto aspect-1 sm:rounded-2xl rounded-lg"
src={event.image}
/>
</div>
</section>
</div>
<ul className="flex items-center justify-center gap-0 md:gap-2">
<li>
<AddToCalendarButton event={event} eventUrl={eventUrl} />
</li>
<li>
<TweetItButton event={event} eventUrl={eventUrl} />
</li>
<li>
<CastItButton event={event} eventUrl={eventUrl} />
</li>
<li>
<CopyUrlButton url={eventUrl} />
</li>
</ul>
{!hasPassed && (
<RegistrationCard
requiresApproval={event.requiresApproval}
checkoutConfig={checkoutConfig}
/>
)}
{hasPassed && (
<Card className="grid gap-4 mt-5 md:mt-0">
<p className="text-lg">
<MdAssignmentLate />
This event is over. It is not possible to register for it anymore.
</p>
</Card>
)}
<AttendeeCues checkoutConfig={checkoutConfig} />
</section>
<div className="flex flex-col col-span-3 gap-4 md:col-span-2">
<h1 className="mt-4 text-3xl font-bold md:text-6xl">{event.name}</h1>
<section className="flex flex-col gap-4">
{organizers && organizers.length > 0 && (
<Hosts organizers={organizers} />
)}
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 rounded-xl">
{hasDate && (
<EventDetail label="Date" icon={CalendarIcon}>
<div
// @ts-expect-error propery 'background_color' does not exist on type 'Event'
style={{ color: `#${event.background_color}` }}
className="flex flex-col text-lg font-normal text-brand-dark"
>
{(startDate || endDate) && (
<span>
{startDate} {endDate && <>to {endDate}</>}
</span>
)}
{startTime && endTime && (
<span>
{startTime} {endTime && <>to {endTime}</>}
</span>
)}
</div>
</EventDetail>
)}
{hasLocation && <EventLocation event={event} />}
</div>
<div>
{event.description && (
<div className="mt-4 markdown">
{/* eslint-disable-next-line react/no-children-prop */}
<ReactMarkdown children={event.description} />
</div>
)}
</div>
</section>
</div>
</div>
)
}

0 comments on commit cea98b4

Please sign in to comment.