Continue Migration, almost done

This commit is contained in:
Daniele Pancottini
2022-12-20 19:15:40 +01:00
parent 15faacc7de
commit e5ebf60e83
11 changed files with 290 additions and 196 deletions

View File

@@ -7,83 +7,89 @@ import {
Text,
Stack,
Link,
} from '@chakra-ui/react';
import NextLink from "next/link"
import { Product } from '@commerce/types';
} from '@chakra-ui/react'
import NextLink from 'next/link'
import { Product } from '@commerce/types'
import style from './ProductCardRoomStyle.module.css';
import style from './ProductCardRoomStyle.module.css'
export default function ProductCardRoom(props: {
product: Product.Product,
product: Product.Product
decade: string
}) {
let historicDescription = props.product.metafields
.filter(meta => meta.key == 'descrizione_storica')
.map(meta => meta.value);
let technicalDescription = props.product.metafields
.filter(meta => meta.key == 'descrizione_tecnica')
.map(meta => meta.value);
let nationOrigin = props.product.metafields
.filter(meta => meta.key == 'nazionalit_')
.map(meta => meta.value);
let historicDescription =
props.product.metafields!.custom.descrizione_storica.value
let technicalDescription =
props.product.metafields!.custom.descrizione_tecnica.value
let nationOrigin = props.product.metafields!.custom.nazionalit_.value
return (
<Flex w="full" alignItems="center" justifyContent="center" direction={'row'}>
<Flex
w="full"
alignItems="center"
justifyContent="center"
direction={'row'}
>
<Box
maxW={'445px'}
w={'full'}
boxShadow={'2xl'}
rounded={'md'}
overflow={'hidden'}
className={style.cardBody}>
className={style.cardBody}
>
<Image
className={style.flagIcon}
src={'http://purecatamphetamine.github.io/country-flag-icons/3x2/' + nationOrigin + '.svg'}
alt={`Picture of Flag`}
rounded={'lg'}
className={style.flagIcon}
src={
'http://purecatamphetamine.github.io/country-flag-icons/3x2/' +
nationOrigin +
'.svg'
}
alt={`Picture of Flag`}
rounded={'lg'}
/>
<Image
className={style.decadeIcon}
src={'/assets/polygons/colorized/' + props.decade + '.svg'}
alt={`Picture of Decade`}
className={style.decadeIcon}
src={'/assets/polygons/colorized/' + props.decade + '.svg'}
alt={`Picture of Decade`}
/>
<Box
className={style.imageContainer}
w={'full'}
height={'220px'}
>
<NextLink href={'/product/' + props.product.slug} passHref>
<Link style={{textDecoration: 'none', height: 'inherit'}}>
<Image
src={
props.product.images[0].url
}
objectFit={'cover'}
margin={'auto'}
height={'inherit'}
/>
</Link>
</NextLink>
<Box className={style.imageContainer} w={'full'} height={'220px'}>
<NextLink href={'/product/' + props.product.slug} passHref>
<Link style={{ textDecoration: 'none', height: 'inherit' }}>
<Image
src={props.product.images[0].url}
objectFit={'cover'}
margin={'auto'}
height={'inherit'}
/>
</Link>
</NextLink>
</Box>
<Box
p={5}
className={style.captionContainer}>
<Box p={5} className={style.captionContainer}>
<Stack align={'center'}>
<Heading fontSize={'2xl'} textAlign={'center'} fontFamily={'body'} fontWeight={500}>
{props.product.name}
</Heading>
<Heading
fontSize={'2xl'}
textAlign={'center'}
fontFamily={'body'}
fontWeight={500}
>
{props.product.name}
</Heading>
</Stack>
<Stack mt={6} align={'center'}>
<Divider borderColor={'blackAlpha.600'} />
{historicDescription.pop()?.split('\n').map((line, index) => (
<Text key={index} padding={0} color={'gray.500'} fontSize={'sm'} align={'center'}>
{historicDescription.split('\n').map((line, index) => (
<Text
key={index}
padding={0}
color={'gray.500'}
fontSize={'sm'}
align={'center'}
>
{line}
</Text>
))}
@@ -93,8 +99,7 @@ export default function ProductCardRoom(props: {
</Text>
</Stack>
</Box>
</Box>
</Flex>
);
}
)
}

View File

@@ -3,15 +3,15 @@ import { useAddItem } from '@framework/cart'
import { FC, useEffect, useState } from 'react'
import { ProductOptions } from '@components/product'
import type { Product } from '@commerce/types/product'
import { Button, Text, Rating, Collapse, useUI } from '@components/ui'
import { Button, Rating, Collapse, Text, useUI } from '@components/ui'
import {
getProductVariant,
selectDefaultOptionFromProduct,
SelectedOptions,
} from '../helpers'
import ErrorMessage from '@components/ui/ErrorMessage'
import { ProductCustomFields } from '../ProductCustomFields'
import { ProductMetafields } from '../ProductMetafields'
import { Box, Stack, Text as ChakraText } from '@chakra-ui/react'
import productDetailsMetafields from '../../../static_data/productDetailsMetafields.json'
interface ProductSidebarProps {
product: Product
@@ -20,9 +20,8 @@ interface ProductSidebarProps {
const ProductSidebar: FC<ProductSidebarProps> = ({ product, className }) => {
const addItem = useAddItem()
const { openSidebar, setSidebarView } = useUI()
const { openSidebar } = useUI()
const [loading, setLoading] = useState(false)
const [error, setError] = useState<null | Error>(null)
const [selectedOptions, setSelectedOptions] = useState<SelectedOptions>({})
useEffect(() => {
@@ -32,27 +31,20 @@ const ProductSidebar: FC<ProductSidebarProps> = ({ product, className }) => {
const variant = getProductVariant(product, selectedOptions)
const addToCart = async () => {
setLoading(true)
setError(null)
try {
await addItem({
productId: String(product.id),
variantId: String(variant ? variant.id : product.variants[0]?.id),
})
setSidebarView('CART_VIEW')
openSidebar()
setLoading(false)
} catch (err) {
setLoading(false)
if (err instanceof Error) {
console.error(err)
setError({
...err,
message: 'Could not add item to cart. Please try again.',
})
}
}
}
console.log(product.metafields!.custom)
return (
<div className={className}>
<ProductOptions
@@ -60,22 +52,31 @@ const ProductSidebar: FC<ProductSidebarProps> = ({ product, className }) => {
selectedOptions={selectedOptions}
setSelectedOptions={setSelectedOptions}
/>
<Text
className="pb-4 break-words w-full max-w-xl"
html={product.descriptionHtml || product.description}
/>
{product.metafields?.reviews?.rating && (
<div className="flex flex-row justify-between items-center">
<Rating value={product.metafields.reviews.rating.value} />
<div className="text-accent-6 pr-1 font-medium text-sm">
{product.metafields.reviews.count?.value ?? 0} reviews
</div>
</div>
)}
{/* Product Description With Metafields */}
<div>
{error && <ErrorMessage error={error} className="my-5" />}
<Box>
<Stack>
{productDetailsMetafields.metafields[0].names.map((meta) => (
<Box key={meta.key}>
<ChakraText
as={'span'}
textTransform={'uppercase'}
fontWeight={'bold'}
>
{meta.name}:{' '}
</ChakraText>
<ChakraText as={'span'}>
{product.metafields.custom
.filter((o) => o.key == meta.key)
.map((o) => o.value)}
</ChakraText>
</Box>
))}
</Stack>
</Box>
<div style={{ marginTop: 20 }}>
{process.env.COMMERCE_CART_ENABLED && (
<Button
aria-label="Add to Cart"
@@ -91,33 +92,6 @@ const ProductSidebar: FC<ProductSidebarProps> = ({ product, className }) => {
</Button>
)}
</div>
<div className="mt-6">
<Collapse title="Care">
This is a limited edition production run. Printing starts when the
drop ends.
</Collapse>
<Collapse title="Details">
This is a limited edition production run. Printing starts when the
drop ends. Reminder: Bad Boys For Life. Shipping may take 10+ days due
to COVID-19.
</Collapse>
{product.customFields && product.customFields?.length > 0 && (
<Collapse title="Specifications">
<ProductCustomFields customFields={product.customFields} />
</Collapse>
)}
{product.metafields?.my_fields && (
<Collapse title="Specifications">
<ProductMetafields
metafields={product.metafields}
namespace="my_fields"
/>
</Collapse>
)}
</div>
</div>
)
}

View File

@@ -1,7 +1,7 @@
import cn from 'clsx'
import Image from 'next/image'
import s from './ProductView.module.css'
import { FC } from 'react'
import { FC, useState } from 'react'
import type { Product } from '@commerce/types/product'
import usePrice from '@framework/product/use-price'
import { WishlistButton } from '@components/wishlist'
@@ -10,6 +10,10 @@ import { Container, Text } from '@components/ui'
import { SEO } from '@components/common'
import ProductSidebar from '../ProductSidebar'
import ProductTag from '../ProductTag'
import ProductModel from '../ProductModel/ProductModel'
import Lightbox from 'yet-another-react-lightbox'
import 'yet-another-react-lightbox/styles.css'
interface ProductViewProps {
product: Product
relatedProducts: Product[]
@@ -22,6 +26,18 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
currencyCode: product.price.currencyCode!,
})
const model3dPath = product.media
.map((media) => {
return media.sources
.filter((source) => source.format == 'glb')
.map((source) => source.url)
.slice(0)
})
.pop()
?.pop()
const [isLightboxOpen, setLightboxOpen] = useState(false)
return (
<>
<Container className="max-w-none w-full" clean>
@@ -37,6 +53,7 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
{product.images.map((image, i) => (
<div key={image.url} className={s.imageContainer}>
<Image
id={'product-image-' + i}
className={s.img}
src={image.url!}
alt={image.alt || 'Product Image'}
@@ -44,10 +61,28 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
height={600}
priority={i === 0}
quality="85"
style={{ cursor: 'pointer' }}
onClick={() => setLightboxOpen(true)}
/>
</div>
))}
{model3dPath != undefined ? (
<div key={'model3d'} className={s.imageContainer}>
<ProductModel modelPath={model3dPath}></ProductModel>
</div>
) : (
<></>
)}
</ProductSlider>
<Lightbox
open={isLightboxOpen}
close={() => setLightboxOpen(false)}
slides={product.images.map((image) => {
return {
src: image.url,
}
})}
/>
</div>
{process.env.COMMERCE_WISHLIST_ENABLED && (
<WishlistButton