Skip to content

Commit

Permalink
venue map v1
Browse files Browse the repository at this point in the history
  • Loading branch information
lassejaco committed Nov 10, 2024
1 parent 8177039 commit 115c109
Show file tree
Hide file tree
Showing 14 changed files with 678 additions and 58 deletions.
5 changes: 5 additions & 0 deletions devcon-app/precache.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const pages = [
precacheHtml: true,
// precacheJson: true,
},
{
route: '/event',
precacheHtml: true,
// precacheJson: true,
},
// {
// route: '/side-events',
// precacheHtml: true,
Expand Down
3 changes: 3 additions & 0 deletions devcon-app/src/assets/icons/dc-7/event-fill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions devcon-app/src/assets/icons/dc-7/event.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added devcon-app/src/assets/images/dc-7/venue/qsncc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 9 additions & 7 deletions devcon-app/src/components/domain/app/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { PropsWithChildren, useState, useEffect, useRef, RefObject, ReactNode } from 'react'
import css from './app.module.scss'
import useGetElementHeight from 'hooks/useGetElementHeight'
import AppIcon from 'assets/icons/app-icons-1.svg'
import TilesIcon from 'assets/icons/dc-7/tiles.svg'
import TilesFillIcon from 'assets/icons/dc-7/tiles-fill.svg'
Expand All @@ -23,6 +22,8 @@ import { useRecoilState } from 'recoil'
import ChevronRightIcon from 'assets/icons/chevron_right.svg'
import { devaBotVisibleAtom, selectedSessionAtom, sessionIdAtom, useSeenNotifications } from 'pages/_app'
import { useAccountContext } from 'context/account-context'
import IconVenue from 'assets/icons/dc-7/event.svg'
import IconFilledVenue from 'assets/icons/dc-7/event-fill.svg'
import ArrowBackIcon from 'assets/icons/arrow_left.svg'
import { selectedSpeakerAtom } from 'pages/_app'

Expand Down Expand Up @@ -326,19 +327,20 @@ const navItems = (isLoggedIn: boolean, pathname: string) => [
href: '/speakers',
size: 18,
},
{
label: 'Event',
icon: pathname === '/event' ? IconFilledVenue : IconVenue,
href: '/event',
isActive: pathname.startsWith('/event'),
size: 18,
},
{
icon: pathname.startsWith('/account') ? UserFillIcon : UserIcon,
label: isLoggedIn ? 'Account' : 'Log In',
href: isLoggedIn ? '/account' : '/login',
isActive: pathname.startsWith('/account'),
size: 22,
},
// {
// icon: TicketIcon,
// label: 'Venue',
// href: '/venue',
// size: 18,
// },
]

export const useWindowWidth = () => {
Expand Down
35 changes: 35 additions & 0 deletions devcon-app/src/components/domain/app/dc7/event/event.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.panzoom {
overflow: hidden;
position: relative;
height: min(60vh, 600px);
width: 100%;
cursor: grab;

.image {
user-select: none;
width: 100%;
height: 100%;
max-height: 100%;
max-width: 100%;
position: relative;
overflow: hidden;


img {
object-fit: contain;
width: 100%;
max-height: 100%;
}
}
}

.panzoom-cover {
@extend .panzoom;
cursor: auto;

.image {
img {
object-fit: cover !important;
}
}
}
232 changes: 232 additions & 0 deletions devcon-app/src/components/domain/app/dc7/event/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import React from 'react'
import cn from 'classnames'
import ListIcon from 'assets/icons/list.svg'
import TimelineIcon from 'assets/icons/timeline.svg'
import VenueMap from 'assets/images/dc-7/venue/venue-map.png'
import VenueLogo from 'assets/images/dc-7/venue/qsncc.png'
import Image from 'next/image'
import css from './event.module.scss'
import { usePanzoom, PanzoomControls } from './panzoom'
import { StandalonePrompt } from 'lib/components/ai/standalone-prompt'
import { useRecoilState } from 'recoil'
import { devaBotVisibleAtom } from 'pages/_app'
import { Link } from 'components/common/link'

// import Panzoom, { PanZoom } from 'panzoom'

export const cardClass =
'flex flex-col lg:border lg:border-solid lg:border-[#E4E6EB] rounded-3xl relative lg:bg-[#fbfbfb]'

// const Switch = () => {
// return (
// <div className="flex justify-evenly bg-[#EFEBFF] gap-1.5 rounded-lg p-1 mt-2 shrink-0 mb-2 self-center text-sm">
// <div
// className={cn(
// 'flex justify-center items-center self-center grow rounded-md gap-2 px-2 text-[#A897FF] hover:bg-white hover:shadow-md cursor-pointer p-0.5 transition-all duration-300 select-none',
// {
// 'bg-white shadow-md !text-[#7D52F4]': !timelineView,
// }
// )}
// onClick={() => setTimelineView(false)}
// >
// <ListIcon
// className="transition-all duration-300"
// style={!timelineView ? { fill: '#7D52F4', fontSize: '14px' } : { fill: '#A897FF', fontSize: '14px' }}
// />
// Floor Map
// </div>
// <div
// className={cn(
// 'flex justify-center items-center rounded-md gap-2 text-[#A897FF] px-2 hover:bg-white hover:shadow-md cursor-pointer p-0.5 transition-all duration-300 select-none',
// {
// 'bg-white shadow-md !text-[#7D52F4]': timelineView,
// }
// )}
// onClick={() => {
// setTimelineView(true)

// // if (Object.keys(sessionFilter.day).length === 0) {
// // setSessionFilter({
// // ...sessionFilter,
// // day: { 'Nov 12': true },
// // })
// // }
// }}
// >
// <TimelineIcon
// className="transition-all duration-300"
// style={timelineView ? { fill: '#7D52F4', fontSize: '14px' } : { fill: '#A497FF', fontSize: '14px' }}
// />
// Timeline View
// </div>
// </div>
// )
// }

const List = (props: any) => {
console.log(props)

return (
<div className="px-4 ">
<p className="mb-4 pt-4 font-semibold">Floors & Rooms</p>

<div className="mb-4">
{/* <p className="text-xs text-gray-500 mb-2">STAGES</p> */}
{props.floors.map((floor: any) => {
let floorName = floor

if (floor === 'G') floorName = 'G — Ground Floor'
if (floor === '1') floorName = 'L1 — First Floor'
if (floor === '2') floorName = 'L2 — Second Floor'

const rooms = props.rooms
.filter((room: any) => room.info === floor)
.sort((a: any, b: any) => {
if (a.name === 'Main Stage') return -1
if (b.name === 'Main Stage') return 1

if (a.name.toLowerCase().startsWith('stage')) {
if (b.name.toLowerCase().startsWith('stage')) {
return a.name.localeCompare(b.name)
}
return -1
}

if (b.name.toLowerCase().startsWith('stage')) return 1

if (a.name.toLowerCase().startsWith('breakout')) {
if (b.name.toLowerCase().startsWith('breakout')) {
return a.name.localeCompare(b.name)
}
return 1
}

if (b.name.toLowerCase().startsWith('breakout')) return -1

return a.name.localeCompare(b.name)
})

return (
<div className="flex flex-col" key={floor}>
<div
key={floor}
className="flex items-center text-sm border border-solid border-[#E1E4EA] p-2 bg-white rounded-xl mb-2"
>
{/* <div className="w-3 h-3 rounded-full bg-[#7D52F4] ml-1 mr-3" /> */}
<span className="font-semibold ml-1">{floorName}</span>
</div>

{rooms.map((room: any) => {
const getColor = (roomName: string) => {
const name = roomName.toLowerCase()
if (name.startsWith('classroom')) return '#14B8A6' // teal
if (name.includes('decompression') || name.includes('music stage')) return '#22C55E' // green
if (name.startsWith('stage') || name === 'main stage') return '#7D52F4' // purple
if (name.startsWith('breakout')) return '#EF4444' // red
return '#7D52F4' // default purple
}

console.log(room.name)

let roomName = room.name

if (roomName === 'Main Stage') {
roomName += ' — Masks'
}

if (roomName === 'Stage 1') {
roomName += ' — Fans'
}

if (roomName === 'Stage 2') {
roomName += ' — Lanterns'
}

if (roomName === 'Stage 3') {
roomName += ' — Fabrics'
}

if (roomName === 'Stage 4') {
roomName += ' — Leaf'
}

if (roomName === 'Stage 5') {
roomName += ' — Hats'
}

if (roomName === 'Stage 6') {
roomName += ' — Kites'
}

if (roomName === 'Keynote') return null

return (
<Link
to={`/schedule?room=${room.name}`}
key={room.name}
className="flex ml-4 items-center justify-between text-sm border border-solid border-[#E1E4EA] p-2 bg-white rounded-xl mb-2 group hover:bg-[#F5F7F9] cursor-pointer"
>
<div className="flex items-center">
<div
className="w-3 h-3 rounded-full ml-1 mr-3"
style={{ backgroundColor: getColor(room.name) }}
/>
<span>{roomName}</span>
</div>
<div className="opacity-0 text-sm text-gray-500 group-hover:opacity-100 transition-all duration-300">
Click to view sessions in this room
</div>
</Link>
)
})}
</div>
)
})}
</div>
</div>
)
}

export const Venue = (props: any) => {
const pz = usePanzoom()
const [_, setDevaBotVisible] = useRecoilState(devaBotVisibleAtom)

return (
<>
<div className={cn(cardClass, 'my-4')}>
<div className={cn(css['panzoom'], 'border-t border-solid border-[#E1E4EA] border-b')}>
<div className={css['image']} id="image-container">
<Image src={VenueMap} alt="venue map" className="object-contain h-full py-8" id="venue-image" />
</div>
<PanzoomControls pz={pz} />
<div className="absolute bottom-2 left-4 lg:bottom-3 lg:left-4 flex flex-col z-[1] text-xs">
<div className="text-[#7D52F4]">QSNCC</div>
<div className="text-[#A897FF]">Venue Map</div>
</div>

<div className="absolute bottom-2 right-4 lg:bottom-3 lg:right-4 flex flex-col z-[1] text-xs">
<div className="text-[#7D52F4]">Zoom/drag for a closer view</div>
</div>
</div>
</div>
<div className={cn(cardClass, 'my-4')}>
<List floors={props.floors} rooms={props.rooms} />

<p className="text-sm font-semibold border-top pt-4 mb-4 mx-4">Ask Devai</p>

<StandalonePrompt className="mx-4" onClick={() => setDevaBotVisible('Tell me where I can go to take a nap')}>
<div className="truncate">Tell me where I can go to take a nap</div>
</StandalonePrompt>
<StandalonePrompt className="mt-2 mx-4" onClick={() => setDevaBotVisible('What can I do at the music stage?')}>
<div className="truncate">What can I do at the music stage?</div>
</StandalonePrompt>
<StandalonePrompt className="mt-2 mx-4" onClick={() => setDevaBotVisible('What is the decompression room?')}>
<div className="truncate">What is the decompression room?</div>
</StandalonePrompt>
<StandalonePrompt className="mt-2 mx-4 lg:mb-4" onClick={() => setDevaBotVisible('What are breakout rooms?')}>
<div className="truncate">What are breakout rooms?</div>
</StandalonePrompt>
</div>
</>
)
}
Loading

0 comments on commit 115c109

Please sign in to comment.