diff --git a/.env.example b/.env.example index 6d645900..04c77094 100644 --- a/.env.example +++ b/.env.example @@ -16,3 +16,9 @@ NEXT_PUBLIC_DEMO_PROMO_ID= NEXT_PUBLIC_DEMO_NODE_ID= NEXT_PUBLIC_DEFAULT_CURRENCY_CODE= NEXT_PUBLIC_STRIPE_ACCOUNT_ID= +NEXT_PUBLIC_ENABLE_RATING= +NEXT_PUBLIC_ALGOLIA_AVG_RATING_FIELD=ep_average_rating +NEXT_PUBLIC_ALGOLIA_REVIEW_COUNT_FIELD=ep_number_of_reviews +NEXT_PUBLIC_ENABLE_YOTPO= +NEXT_PUBLIC_YOTPO_APP_KEY= +NEXT_PUBLIC_DISABLE_IMAGE_OPTIMIZATION= diff --git a/README.md b/README.md index 2c7a3a4e..00ac336e 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,19 @@ Add `NEXT_PUBLIC_STRIPE_ACCOUNT_ID` and `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` val - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY - Please contact Elastic Path Customer Service team to get the publishable key. +### Setup Yotpo (Ratings and Reviews) + +Add `NEXT_PUBLIC_ENABLE_YOTPO` and `NEXT_PUBLIC_YOTPO_APP_KEY` value in your environment file. + +- NEXT_PUBLIC_ENABLE_YOTPO + - Default value is false (even if you don't provide any value). To enable this integration you need to provide value as `true` +- NEXT_PUBLIC_YOTPO_APP_KEY + - You need to register with Yotpo, there are free trials available. Once you register, go to Settings and then you will able to see App Key. Copy app key from Yotpo and provide value here. Screenshot given below. + +### Disable Image Optimization + +By default image optimization is enabled. If you want to disable that then add value as `true` for this property in the environment variable `NEXT_PUBLIC_DISABLE_IMAGE_OPTIMIZATION`. + ### Setup Algolia index > :tired_face: We recognise manually configuring Algolia in this way is a pain. We are working on tools to streamline this process. @@ -131,6 +144,8 @@ ep_extensions_products_specifications.on-sale ep_extensions_products_specifications.color ``` +For ratings filter, you need to add rating field as filter. If you are using default field value of `NEXT_PUBLIC_ALGOLIA_AVG_RATING_FIELD` as `ep_average_rating` then you need to select that. + In order to use faceting add the attribute name to the list of attributes in Facets and Facet display sections of Algolia dashboard in Configuration menu. Use default settings. @@ -145,6 +160,16 @@ my_catalog_index_price_desc Follow ["Creating a replica"](https://www.algolia.com/doc/guides/managing-results/refine-results/sorting/how-to/sort-by-attribute/#using-the-dashboard) in the Algolia docs to set both of these up based on the main index created previously by the integrations hub Aloglia integration. Make sure to create a **standard** replica. +##### Configuring rating and review + +Add `NEXT_PUBLIC_ENABLE_RATING`, `NEXT_PUBLIC_ALGOLIA_AVG_RATING_FIELD` and `NEXT_PUBLIC_ALGOLIA_REVIEW_COUNT_FIELD` value in your environment file. + +- NEXT_PUBLIC_ENABLE_RATING + - Default value is false (even if you don't provide any value). To enable this integration you need to provide value as `true`. Once you enable this then you will be able to see ratings and review on search pages and also as filter. +- NEXT_PUBLIC_ALGOLIA_AVG_RATING_FIELD + - Default value is `ep_average_rating`, if you want to use any other field then change this value. This field is responsible for showing filter and also stars as part of ratings on search pages. + - Default value is `ep_number_of_reviews`, if you want to use any other field then change this value. This field is responsible for showing number of reviews in search pages. + #### Finally Make sure you add the three required Algolia environment variables to your `.env.local` file for local dev and your production environment. diff --git a/next.config.js b/next.config.js index 625559c7..61b2b378 100644 --- a/next.config.js +++ b/next.config.js @@ -6,8 +6,8 @@ const nextConfig = { images: { domains: ["files-eu.epusercontent.com"], + unoptimized: process.env.NEXT_PUBLIC_DISABLE_IMAGE_OPTIMIZATION == "true", }, - experimental: { images: { allowFutureImage: true } }, i18n: { locales: ["en"], defaultLocale: "en", diff --git a/package.json b/package.json index 2e66e5ee..ed1c64f1 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@moltin/sdk": "^18.1.0", "@stripe/react-stripe-js": "^1.11.0", "@stripe/stripe-js": "^1.38.1", + "@types/react-star-ratings": "^2.3.0", "@types/react-stripe-elements": "^6.0.6", "algoliasearch": "^4.14.2", "braintree-web": "^3.87.0", @@ -40,10 +41,11 @@ "react": "^18.2.0", "react-device-detect": "^2.2.2", "react-dom": "^18.2.0", - "sass": "^1.55.0", "react-instantsearch-hooks-server": "6.38.1", "react-instantsearch-hooks-web": "6.38.1", + "react-star-ratings": "^2.3.0", "rxjs": "^7.5.7", + "sass": "^1.55.0", "yup": "^1.0.0-beta.7", "zlib": "^1.0.5" }, @@ -71,7 +73,7 @@ "typescript": "4.7.4" }, "resolutions": { - "@types/react": "17.0.2", - "@types/react-dom": "17.0.2" + "@types/react": "18.0.33", + "@types/react-dom": "18.0.11" } } diff --git a/src/components/featured-products/FeaturedProducts.tsx b/src/components/featured-products/FeaturedProducts.tsx index 1a94337a..f9c75f6b 100644 --- a/src/components/featured-products/FeaturedProducts.tsx +++ b/src/components/featured-products/FeaturedProducts.tsx @@ -7,6 +7,7 @@ import { connectProductsWithMainImages } from "../../lib/product-util"; import { ArrowForwardIcon, ViewOffIcon } from "@chakra-ui/icons"; import { globalBaseWidth } from "../../styles/theme"; import { ChakraNextImage } from "../ChakraNextImage"; +import { Ratings } from "../reviews/yotpo/Reviews"; interface IFeaturedProductsBaseProps { title: string; @@ -104,7 +105,7 @@ const FeaturedProducts = (props: IFeaturedProductsProps): JSX.Element => { p={4} flex={{ base: "100%", md: "50%", lg: "25%" }} key={product.id} - href="/category" + href={`/products/${product.id}`} > {product.main_image?.link.href ? ( @@ -135,6 +136,7 @@ const FeaturedProducts = (props: IFeaturedProductsProps): JSX.Element => { {product.attributes.name} + {product.meta.display_price?.without_tax.formatted} diff --git a/src/components/product/ProductSummary.tsx b/src/components/product/ProductSummary.tsx index 6696ce06..88ec6545 100644 --- a/src/components/product/ProductSummary.tsx +++ b/src/components/product/ProductSummary.tsx @@ -2,6 +2,7 @@ import { Box, Heading, Flex } from "@chakra-ui/react"; import type { ProductResponse } from "@moltin/sdk"; import { useContext } from "react"; import { changingSkuStyle, ProductContext } from "../../lib/product-util"; +import { Ratings } from "../reviews/yotpo/Reviews"; import Price from "./Price"; import StrikePrice from "./StrikePrice"; @@ -25,6 +26,7 @@ const ProductSummary = ({ product }: IProductSummary): JSX.Element => { > {attributes.name} + {display_price && ( { + useEffect(() => { + if (yotpoEnv.enable && typeof window.yotpo !== "undefined") { + window.yotpo.refreshWidgets(); + } + }, [product.id]); + + const { + id, + attributes, + meta: { display_price }, + } = product; + + return yotpoEnv.enable ? ( + +