Start migration

This commit is contained in:
Daniele Pancottini
2022-12-20 17:30:36 +01:00
parent 6d783eae35
commit b1fb0bc138
125 changed files with 3819 additions and 161 deletions

View 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

View File

@@ -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>
</>
)

View File

@@ -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
View 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

View File

@@ -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>
</>
)
}