mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
Start migration
This commit is contained in:
380
site/pages/[region]/[decade]/[start].tsx
Normal file
380
site/pages/[region]/[decade]/[start].tsx
Normal file
@@ -0,0 +1,380 @@
|
||||
import { Layout } from '@components/common'
|
||||
import commerce from '@lib/api/commerce'
|
||||
import {
|
||||
GetStaticPathsContext,
|
||||
GetStaticPropsContext,
|
||||
InferGetStaticPropsType,
|
||||
} from 'next'
|
||||
import { Viewer } from 'photo-sphere-viewer'
|
||||
import { GyroscopePlugin } from 'photo-sphere-viewer/dist/plugins/gyroscope'
|
||||
import { MarkersPlugin } from 'photo-sphere-viewer/dist/plugins/markers'
|
||||
import { GalleryPlugin } from 'photo-sphere-viewer/dist/plugins/gallery'
|
||||
import 'photo-sphere-viewer/dist/plugins/markers.css'
|
||||
import 'photo-sphere-viewer/dist/plugins/gallery.css'
|
||||
import { StereoPlugin } from 'photo-sphere-viewer/dist/plugins/stereo'
|
||||
import { VirtualTourPlugin } from 'photo-sphere-viewer/dist/plugins/virtual-tour'
|
||||
import { VisibleRangePlugin } from 'photo-sphere-viewer/dist/plugins/visible-range'
|
||||
import { RefObject, useEffect, useRef, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import RegionsDataJson from '../../../static_data/navBarMenuData.json'
|
||||
import MarkerCardModal from '@components/common/Room/MarkerCardModal/MarkerCardModal'
|
||||
import { useDisclosure } from '@chakra-ui/react'
|
||||
|
||||
import decadesManifest from '../../../static_data/decadesManifest.json'
|
||||
import {
|
||||
MarkerData,
|
||||
MarkerJson,
|
||||
} from '@components/common/Room/RoomTypes/RoomTypes'
|
||||
import { getNodes, getRecursiveMarkers } from 'workers/DecadeWorker'
|
||||
import screenfull from 'screenfull'
|
||||
import { Stream } from 'stream'
|
||||
|
||||
export async function getStaticPaths({ locales }: GetStaticPathsContext) {
|
||||
const decadesPaths = RegionsDataJson.regions
|
||||
.filter((region) => region.enabled)
|
||||
.flatMap((region) => {
|
||||
let regionDecadesPath = new Array<string>()
|
||||
for (let key in decadesManifest) {
|
||||
if (decadesManifest[key as keyof typeof decadesManifest].enabled) {
|
||||
Array.from(Array(7).keys()).forEach((nodeId: number) =>
|
||||
regionDecadesPath.push(region.href + '/' + key + '/' + nodeId)
|
||||
)
|
||||
}
|
||||
}
|
||||
return regionDecadesPath
|
||||
})
|
||||
|
||||
return {
|
||||
paths: locales
|
||||
? locales.reduce<string[]>((arr, locale) => {
|
||||
// Add a decade path for every locale
|
||||
decadesPaths.forEach((path: any) => {
|
||||
arr.push(`/${locale}${path}`)
|
||||
})
|
||||
return arr
|
||||
}, [])
|
||||
: decadesPaths,
|
||||
fallback: 'blocking',
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticProps({
|
||||
params,
|
||||
locale,
|
||||
locales,
|
||||
preview,
|
||||
}: GetStaticPropsContext<{ region: string; decade: string; start: string }>) {
|
||||
const config = { locale, locales }
|
||||
let products = new Array()
|
||||
let decadeManifest = (
|
||||
await import(
|
||||
`../../../static_data/regions/${params?.region}/${params?.decade}/manifest.json`
|
||||
)
|
||||
).rooms
|
||||
let region = params?.region
|
||||
let decade = params?.decade
|
||||
let startNode = params?.start
|
||||
|
||||
//sunrise sunset api to retreive Rome rise/set times
|
||||
const sunriseSunsetAPI =
|
||||
'https://api.sunrise-sunset.org/json?lat=41.9027835&lng=12.4963655'
|
||||
const [sunriseTime, sunsetTime] = await fetch(sunriseSunsetAPI)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw Error(response.statusText)
|
||||
}
|
||||
return response.json()
|
||||
})
|
||||
.then((data) => data.results)
|
||||
.then((data) => [
|
||||
parseInt(data.sunrise.split(':')[0]),
|
||||
parseInt(data.sunset.split(':')[0]),
|
||||
])
|
||||
.catch((error) => [7, 7])
|
||||
|
||||
const time =
|
||||
new Date().getUTCHours() >= sunsetTime + 12 ||
|
||||
new Date().getUTCHours() <= sunriseTime
|
||||
? 'night'
|
||||
: 'day'
|
||||
|
||||
for (const roomMeta of decadeManifest) {
|
||||
let roomMarkers
|
||||
|
||||
try {
|
||||
roomMarkers = await import(
|
||||
`../../../static_data/regions/abruzzo/${decade}/${time}/${
|
||||
roomMeta.filename.split('.')[0]
|
||||
}.json`
|
||||
)
|
||||
} catch (e) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (const productMarker of roomMarkers.markers.filter(
|
||||
(marker: MarkerJson) => marker.markerType == 'product'
|
||||
)) {
|
||||
if (
|
||||
products.find(({ product }) =>
|
||||
product.slug?.includes(productMarker.markerSource)
|
||||
)
|
||||
)
|
||||
continue
|
||||
|
||||
const productPromise = commerce.getProduct({
|
||||
variables: { slug: productMarker.markerSource },
|
||||
config,
|
||||
preview,
|
||||
})
|
||||
|
||||
products.push(await productPromise)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(products)
|
||||
|
||||
if (!products) {
|
||||
throw new Error(`Products associated with markers not found`)
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
products,
|
||||
decadeManifest,
|
||||
region,
|
||||
decade,
|
||||
startNode,
|
||||
time,
|
||||
},
|
||||
revalidate: 200,
|
||||
}
|
||||
}
|
||||
|
||||
export default function RoomPage({
|
||||
products,
|
||||
decadeManifest,
|
||||
region,
|
||||
decade,
|
||||
startNode,
|
||||
time,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
const {
|
||||
isOpen: isOpenModal,
|
||||
onOpen: onOpenModal,
|
||||
onClose: onCloseModal,
|
||||
} = useDisclosure()
|
||||
const [currentMarkerInModal, setCurrentMarkerInModal] = useState<MarkerData>()
|
||||
const [recursiveMarkers] = useState<any>(
|
||||
getRecursiveMarkers(decade!, decadeManifest, time)
|
||||
)
|
||||
const [virtualTourNodes] = useState<Array<any>>(
|
||||
getNodes(products, decadeManifest, region!, decade!, time)
|
||||
)
|
||||
|
||||
const [audioPlayer, setAudioPlayer] = useState<HTMLAudioElement>()
|
||||
const [isAudioInBackground, setIsAudioInBackground] = useState<boolean>(false)
|
||||
const [isNodeChanged, setIsNodeChanged] = useState<boolean>(false)
|
||||
|
||||
const router = useRouter()
|
||||
const audioPlayerRef = useRef<HTMLAudioElement | undefined>(audioPlayer)
|
||||
|
||||
let navbarArray = new Array(
|
||||
'autorotate',
|
||||
'zoom',
|
||||
'move',
|
||||
'markers',
|
||||
'markersList',
|
||||
'gallery',
|
||||
'stereo',
|
||||
'gyroscope',
|
||||
'fullscreen'
|
||||
)
|
||||
|
||||
navbarArray = navbarArray.concat(
|
||||
recursiveMarkers.map((recursiveMarker: any) => {
|
||||
return {
|
||||
id: recursiveMarker.name,
|
||||
content: recursiveMarker.name,
|
||||
title: recursiveMarker.name,
|
||||
className: 'custom-button',
|
||||
visible: false,
|
||||
onClick: (viewer: any) => {
|
||||
changeToRecursiveRoom(recursiveMarker, viewer)
|
||||
},
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const changeToRecursiveRoom = (recursiveMarker: any, viewer: any) => {
|
||||
const virtualTour = viewer.getPlugin(VirtualTourPlugin)
|
||||
const destNode = virtualTourNodes.find(
|
||||
(node: any) => node.name === recursiveMarker.name
|
||||
)
|
||||
virtualTour.setCurrentNode(destNode.id)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const shperePlayerInstance = new Viewer({
|
||||
container: 'roomViewer',
|
||||
plugins: [
|
||||
[
|
||||
VisibleRangePlugin,
|
||||
{
|
||||
longitudeRange: [null],
|
||||
latitudeRange: [-Math.PI / 2, Math.PI / 4], //Restrict range so you can't see the top of the pano
|
||||
},
|
||||
],
|
||||
[GyroscopePlugin, StereoPlugin],
|
||||
MarkersPlugin,
|
||||
[
|
||||
GalleryPlugin,
|
||||
{
|
||||
thumbnailSize: { width: 100, height: 100 },
|
||||
},
|
||||
],
|
||||
[
|
||||
VirtualTourPlugin,
|
||||
{
|
||||
positionMode: VirtualTourPlugin.MODE_3D,
|
||||
renderMode: VirtualTourPlugin.MODE_MARKERS,
|
||||
nodes: virtualTourNodes,
|
||||
startNodeId: startNode,
|
||||
},
|
||||
],
|
||||
],
|
||||
touchmoveTwoFingers: true,
|
||||
mousewheelCtrlKey: true,
|
||||
navbar: navbarArray,
|
||||
})
|
||||
|
||||
const markersPlugin = shperePlayerInstance.getPlugin(MarkersPlugin)
|
||||
const virtualTourPlugin = shperePlayerInstance.getPlugin(VirtualTourPlugin)
|
||||
|
||||
markersPlugin?.on('select-marker', (e, marker) => {
|
||||
if (marker.id.includes('tour-link')) {
|
||||
return
|
||||
}
|
||||
|
||||
if (screenfull.isEnabled) {
|
||||
screenfull.exit()
|
||||
}
|
||||
|
||||
if (marker.data.markerType === 'room') {
|
||||
virtualTourPlugin?.setCurrentNode(
|
||||
decadeManifest.find(
|
||||
(room: any) =>
|
||||
room.name === marker.data.markerPayload.resourceSource
|
||||
).id
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
setCurrentMarkerInModal(marker.data)
|
||||
onOpenModal()
|
||||
})
|
||||
|
||||
virtualTourPlugin?.on('node-changed', (e, nodeId, data) => {
|
||||
setIsNodeChanged(true)
|
||||
recursiveMarkers.forEach((recursive: any) =>
|
||||
shperePlayerInstance.navbar.getButton(recursive.name).hide()
|
||||
)
|
||||
const originNode = virtualTourNodes.find(
|
||||
(node: any) => node.id === nodeId
|
||||
)
|
||||
const originRoom = recursiveMarkers.find((recursive: any) =>
|
||||
originNode.panorama.includes(recursive.panorama)
|
||||
)
|
||||
if (originRoom != undefined) {
|
||||
shperePlayerInstance.navbar.getButton(originRoom.name).show()
|
||||
}
|
||||
})
|
||||
|
||||
router.events.on('routeChangeStart', () => {
|
||||
if (audioPlayerRef.current && !audioPlayerRef.current?.paused) {
|
||||
audioPlayerRef.current!.pause()
|
||||
audioPlayerRef.current!.src = ''
|
||||
}
|
||||
})
|
||||
|
||||
// unmount component instructions
|
||||
return () => {
|
||||
shperePlayerInstance.destroy()
|
||||
router.events.off('routeChangeStart', () => {
|
||||
if (audioPlayerRef.current && !audioPlayerRef.current?.paused) {
|
||||
audioPlayerRef.current!.pause()
|
||||
audioPlayerRef.current!.src = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (isAudioInBackground === true) {
|
||||
setTimeout(() => {
|
||||
audioPlayer!.play()
|
||||
}, 500)
|
||||
setTimeout(() => {
|
||||
audioPlayer?.pause()
|
||||
setIsAudioInBackground(false)
|
||||
}, audioPlayer!.duration - audioPlayer!.currentTime)
|
||||
}
|
||||
}, [isAudioInBackground])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
currentMarkerInModal != undefined &&
|
||||
currentMarkerInModal.markerType === 'video' &&
|
||||
!audioPlayer?.paused
|
||||
) {
|
||||
audioPlayer?.pause()
|
||||
}
|
||||
}, [currentMarkerInModal])
|
||||
|
||||
const onAudioPlay = (player: HTMLAudioElement) => {
|
||||
if (!audioPlayer?.paused) {
|
||||
audioPlayer?.pause()
|
||||
}
|
||||
setAudioPlayer(player)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
audioPlayerRef.current = audioPlayer
|
||||
}, [audioPlayer])
|
||||
|
||||
useEffect(() => {
|
||||
if (isNodeChanged && !audioPlayer?.paused) {
|
||||
audioPlayer?.pause()
|
||||
setIsNodeChanged(false)
|
||||
}
|
||||
}, [isNodeChanged])
|
||||
|
||||
return (
|
||||
<>
|
||||
{currentMarkerInModal != undefined ? (
|
||||
currentMarkerInModal.markerType === 'audio' ? (
|
||||
<MarkerCardModal
|
||||
decade={decade!}
|
||||
marker={currentMarkerInModal}
|
||||
onModalClose={onCloseModal}
|
||||
isOpen={isOpenModal}
|
||||
onAudioPlayerPause={() => setIsAudioInBackground(true)}
|
||||
onAudioPlayerPlay={onAudioPlay}
|
||||
/>
|
||||
) : (
|
||||
<MarkerCardModal
|
||||
decade={decade!}
|
||||
marker={currentMarkerInModal}
|
||||
onModalClose={onCloseModal}
|
||||
isOpen={isOpenModal}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<div style={{ height: '90vh' }} id="roomViewer" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
RoomPage.Layout = Layout
|
@@ -6,6 +6,7 @@ import { FC, ReactNode, useEffect } from 'react'
|
||||
import type { AppProps } from 'next/app'
|
||||
import { Head } from '@components/common'
|
||||
import { ManagedUIContext } from '@components/ui/context'
|
||||
import { ChakraProvider } from '@chakra-ui/react'
|
||||
|
||||
const Noop: FC<{ children?: ReactNode }> = ({ children }) => <>{children}</>
|
||||
|
||||
@@ -20,9 +21,11 @@ export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
<>
|
||||
<Head />
|
||||
<ManagedUIContext>
|
||||
<Layout pageProps={pageProps}>
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
<ChakraProvider>
|
||||
<Layout pageProps={pageProps}>
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
</ChakraProvider>
|
||||
</ManagedUIContext>
|
||||
</>
|
||||
)
|
||||
|
@@ -4,7 +4,12 @@ class MyDocument extends Document {
|
||||
render() {
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<Head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/photo-sphere-viewer@4/dist/photo-sphere-viewer.min.css"
|
||||
/>
|
||||
</Head>
|
||||
<body className="loading">
|
||||
<Main />
|
||||
<NextScript />
|
||||
|
18
site/pages/about.tsx
Normal file
18
site/pages/about.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Divider, Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react'
|
||||
import { Layout } from '@components/common'
|
||||
import AboutSlider from '@components/common/About/AboutSlider'
|
||||
|
||||
import { Text } from '@components/ui'
|
||||
|
||||
export default function About() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-8 sm:mx-auto py-20 flex flex-col items-center justify-center fit">
|
||||
<AboutSlider></AboutSlider>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
About.Layout = Layout
|
@@ -1,89 +1,85 @@
|
||||
import commerce from '@lib/api/commerce'
|
||||
import { Layout } from '@components/common'
|
||||
import { ProductCard } from '@components/product'
|
||||
import { Grid, Marquee, Hero } from '@components/ui'
|
||||
// import HomeAllProductsGrid from '@components/common/HomeAllProductsGrid'
|
||||
import type { GetStaticPropsContext, InferGetStaticPropsType } from 'next'
|
||||
import ImageMapper from 'react-img-mapper'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useDisclosure } from '@chakra-ui/react'
|
||||
import PolygonModal from '@components/common/HomePage/PolygonModal/PolygonModal'
|
||||
|
||||
export async function getStaticProps({
|
||||
preview,
|
||||
locale,
|
||||
locales,
|
||||
}: GetStaticPropsContext) {
|
||||
const config = { locale, locales }
|
||||
const productsPromise = commerce.getAllProducts({
|
||||
variables: { first: 6 },
|
||||
config,
|
||||
preview,
|
||||
// Saleor provider only
|
||||
...({ featured: true } as any),
|
||||
})
|
||||
const pagesPromise = commerce.getAllPages({ config, preview })
|
||||
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
|
||||
const { products } = await productsPromise
|
||||
const { pages } = await pagesPromise
|
||||
const { categories, brands } = await siteInfoPromise
|
||||
export default function Home() {
|
||||
|
||||
return {
|
||||
props: {
|
||||
products,
|
||||
categories,
|
||||
brands,
|
||||
pages,
|
||||
},
|
||||
revalidate: 60,
|
||||
const imagePath = "homepageBackgroundImage.png";
|
||||
const {locale} = useRouter();
|
||||
|
||||
const [mapContainerWidth, setMapContainerWidth] = useState<number | undefined>(600);
|
||||
const [innerWidth, setInnerWidth] = useState<number | undefined>(600);
|
||||
const [decadeClicked, setDecadeClicked] = useState<string>("12")
|
||||
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
|
||||
const mapDefinition = {
|
||||
name: "my-map",
|
||||
areas: [
|
||||
{
|
||||
id: '12',
|
||||
title: '2000',
|
||||
name: '2000',
|
||||
fillColor: '#eab54d4d',
|
||||
strokeColor: 'black',
|
||||
coords: [4653,1231,5039,1396,5204,1622,5218,2027,5039,2315,4709,2461,4276,2339,4068,2084,4040,1679,4177,1457,4337,1325],
|
||||
shape: "poly",
|
||||
//href: `/${locale}/abruzzo/12`,
|
||||
href: "#",
|
||||
},
|
||||
{
|
||||
id: '11',
|
||||
title: '1990',
|
||||
name: '1990',
|
||||
fillColor: '#eab54d4d',
|
||||
strokeColor: 'black',
|
||||
coords: [3904,974,475],
|
||||
shape: "circle",
|
||||
//href: `/${locale}/abruzzo/12`,
|
||||
href: "#",
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
title: '1980',
|
||||
name: '1980',
|
||||
fillColor: '#eab54d4d',
|
||||
strokeColor: 'black',
|
||||
coords: [3045,611,387],
|
||||
shape: "circle",
|
||||
//href: `/${locale}/abruzzo/12`,
|
||||
href: "#",
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default function Home({
|
||||
products,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
useEffect(() => {
|
||||
|
||||
// Handler to call on window resize
|
||||
function handleResize() {
|
||||
setInnerWidth(window.innerWidth);
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
handleResize();
|
||||
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMapContainerWidth(document.getElementById('mapContainer')?.clientWidth);
|
||||
}, [innerWidth]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid variant="filled">
|
||||
{products.slice(0, 3).map((product: any, i: number) => (
|
||||
<ProductCard
|
||||
key={product.id}
|
||||
product={product}
|
||||
imgProps={{
|
||||
width: i === 0 ? 1080 : 540,
|
||||
height: i === 0 ? 1080 : 540,
|
||||
priority: true,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
<Marquee variant="secondary">
|
||||
{products.slice(0, 3).map((product: any, i: number) => (
|
||||
<ProductCard key={product.id} product={product} variant="slim" />
|
||||
))}
|
||||
</Marquee>
|
||||
<Hero
|
||||
headline=" Dessert dragée halvah croissant."
|
||||
description="Cupcake ipsum dolor sit amet lemon drops pastry cotton candy. Sweet carrot cake macaroon bonbon croissant fruitcake jujubes macaroon oat cake. Soufflé bonbon caramels jelly beans. Tiramisu sweet roll cheesecake pie carrot cake. "
|
||||
/>
|
||||
<Grid layout="B" variant="filled">
|
||||
{products.slice(0, 3).map((product: any, i: number) => (
|
||||
<ProductCard
|
||||
key={product.id}
|
||||
product={product}
|
||||
imgProps={{
|
||||
width: i === 0 ? 1080 : 540,
|
||||
height: i === 0 ? 1080 : 540,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
<Marquee>
|
||||
{products.slice(3).map((product: any, i: number) => (
|
||||
<ProductCard key={product.id} product={product} variant="slim" />
|
||||
))}
|
||||
</Marquee>
|
||||
{/* <HomeAllProductsGrid
|
||||
newestProducts={products}
|
||||
categories={categories}
|
||||
brands={brands}
|
||||
/> */}
|
||||
<section id='mapContainer' className='w-full'>
|
||||
<div>
|
||||
<ImageMapper natural stayHighlighted onClick={area => { setDecadeClicked(area.id!); onOpen() }} parentWidth={mapContainerWidth} responsive={true} src={imagePath} map={mapDefinition}></ImageMapper>
|
||||
<PolygonModal key={decadeClicked} decade={decadeClicked} onModalClose={onClose} isOpen={isOpen} />
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user