diff --git a/app/[locale]/globals.css b/app/[locale]/globals.css index 2d7943a69..c59a0eb76 100644 --- a/app/[locale]/globals.css +++ b/app/[locale]/globals.css @@ -153,11 +153,11 @@ body { } .glider-prev { - @apply !-top-10 !left-auto !right-12 text-high-contrast !transition-transform !duration-100 hover:scale-110 hover:!text-high-contrast lg:!-top-10 lg:!right-16 2xl:!-top-12 2xl:!right-[100px]; + @apply !-top-10 !left-auto !right-12 text-high-contrast !transition-transform !duration-100 hover:scale-110 hover:!text-high-contrast lg:!-top-12 lg:!right-16 2xl:!right-[100px]; } .glider-next { - @apply !-top-10 !right-4 text-high-contrast !transition-transform !duration-100 hover:scale-110 hover:!text-high-contrast lg:!-top-10 lg:!right-8 2xl:!-top-12 2xl:!right-16; + @apply !-top-10 !right-4 text-high-contrast !transition-transform !duration-100 hover:scale-110 hover:!text-high-contrast lg:!-top-12 lg:!right-8 2xl:!right-16; } .pdp .glider-prev { diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx index 4cdfde43d..53c2e6fb8 100644 --- a/app/[locale]/page.tsx +++ b/app/[locale]/page.tsx @@ -1,14 +1,24 @@ import DynamicContentManager from 'components/layout/dynamic-content-manager/dynamic-content-manager'; import { homePageQuery } from 'lib/sanity/queries'; import { clientFetch } from 'lib/sanity/sanity.client'; +import { Metadata } from 'next'; +import { notFound } from 'next/navigation'; export const runtime = 'edge'; -export const metadata = { - description: 'High-performance ecommerce store built with Next.js, Vercel, Sanity and Storm.', - openGraph: { - type: 'website' - } -}; +export async function generateMetadata({ + params +}: { + params: { slug: string; locale: string }; +}): Promise<Metadata> { + const homePage = await clientFetch(homePageQuery, params); + + if (!homePage) return notFound(); + + return { + title: homePage.seo.title || homePage.title, + description: homePage.seo.description || homePage.description + }; +} interface HomePageParams { params: { diff --git a/components/layout/dynamic-content-manager/dynamic-content-manager.tsx b/components/layout/dynamic-content-manager/dynamic-content-manager.tsx index c674264e5..81dedaf88 100644 --- a/components/layout/dynamic-content-manager/dynamic-content-manager.tsx +++ b/components/layout/dynamic-content-manager/dynamic-content-manager.tsx @@ -1,13 +1,12 @@ 'use client'; -import { InfoCircledIcon } from '@radix-ui/react-icons'; - import BlurbSection from '@/components/modules/blurb-section/blurb-section'; import FilteredProductList from '@/components/modules/filtered-product-list/filtered-product-list'; import Hero from '@/components/modules/hero'; import ReusableSection from '@/components/modules/reusable-section/reusable-section'; import Slider from '@/components/modules/slider/slider'; import USPSection from '@/components/modules/usp-section/usp-section'; +import { InfoCircledIcon } from '@radix-ui/react-icons'; interface getContentComponentProps { _type: string; _key: number; @@ -19,13 +18,25 @@ const getContentComponent = ({ _type, _key, disabled, ...rest }: getContentCompo switch (_type) { case 'hero': - Component = Hero; + if (disabled !== true) { + Component = Hero; + } else { + return; + } break; case 'slider': - Component = Slider; + if (disabled !== true) { + Component = Slider; + } else { + return; + } break; case 'filteredProductList': - Component = FilteredProductList; + if (disabled !== true) { + Component = FilteredProductList; + } else { + return; + } break; case 'blurbSection': if (disabled !== true) { diff --git a/components/layout/footer/footer.tsx b/components/layout/footer/footer.tsx index 0362e1c66..e4722895a 100644 --- a/components/layout/footer/footer.tsx +++ b/components/layout/footer/footer.tsx @@ -21,7 +21,7 @@ export default async function Footer({ locale }: FooterProps) { <footer className="border-t border-ui-border bg-app"> <div className="mx-auto flex w-full flex-col"> <div className="flex w-full items-center justify-between p-4 transition-colors duration-150 md:space-y-0 lg:px-8 lg:py-6 2xl:px-16 2xl:py-8"> - <Link className="flex flex-initial items-center font-bold md:mr-24" href="/"> + <Link href={`/${locale}`} className="flex flex-initial items-center font-bold md:mr-24"> <Logo /> </Link> <LocaleSwitcher /> diff --git a/components/layout/header/header.tsx b/components/layout/header/header.tsx index d5a9213ee..c4b6674e9 100644 --- a/components/layout/header/header.tsx +++ b/components/layout/header/header.tsx @@ -22,7 +22,7 @@ const Header = ({ locale }: HeaderProps) => { <div className="flex items-center"> <Link - href={`/`} + href={`/${locale}`} className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform cursor-pointer duration-100 ease-in-out md:relative md:left-0 md:top-0 md:translate-x-0 md:translate-y-0" aria-label="Logo" > diff --git a/components/modules/blurb-section/blurb-section.tsx b/components/modules/blurb-section/blurb-section.tsx index 1ed8ddc0d..23d2a50eb 100644 --- a/components/modules/blurb-section/blurb-section.tsx +++ b/components/modules/blurb-section/blurb-section.tsx @@ -1,7 +1,5 @@ -import dynamic from 'next/dynamic'; - -import { Carousel, CarouselItem } from 'components/modules/carousel/carousel'; -const Card = dynamic(() => import('components/ui/card')); +import { Carousel, CarouselItem } from '@/components/modules/carousel/carousel'; +import Card from '@/components/ui/card/card'; import Text from 'components/ui/text'; diff --git a/components/modules/filtered-product-list/filtered-product-list.tsx b/components/modules/filtered-product-list/filtered-product-list.tsx index 9b6340b98..597459b8b 100644 --- a/components/modules/filtered-product-list/filtered-product-list.tsx +++ b/components/modules/filtered-product-list/filtered-product-list.tsx @@ -1,14 +1,12 @@ -'use client' +'use client'; -import Text from 'components/ui/text' -import dynamic from 'next/dynamic' - -const ProductCard = dynamic(() => import('components/ui/product-card')) +import ProductCard from '@/components/ui/product-card/product-card'; +import Text from 'components/ui/text'; interface SliderProps { - products: any - title: string - itemsToShow: number + products: any; + title: string; + itemsToShow: number; } const FilteredProductList = ({ title, products, itemsToShow }: SliderProps) => { @@ -19,17 +17,17 @@ const FilteredProductList = ({ title, products, itemsToShow }: SliderProps) => { {title} </Text> ) : ( - <Text className="italic mb-4 lg:mb-6 2xl:mb-8" variant="sectionHeading"> + <Text className="mb-4 italic lg:mb-6 2xl:mb-8" variant="sectionHeading"> No title provided yet </Text> )} - <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"> + <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"> {products.slice(0, itemsToShow).map((product: any, index: number) => ( <ProductCard key={`${product.id}-${index}`} product={product} /> ))} </div> </div> - ) -} + ); +}; -export default FilteredProductList +export default FilteredProductList; diff --git a/components/modules/hero/hero.tsx b/components/modules/hero/hero.tsx index 9b5754230..3497269b6 100644 --- a/components/modules/hero/hero.tsx +++ b/components/modules/hero/hero.tsx @@ -1,8 +1,6 @@ -import dynamic from 'next/dynamic'; - +import SanityImage from '@/components/ui/sanity-image/sanity-image'; import Link from 'components/ui/link/link'; import Text from 'components/ui/text/text'; -const SanityImage = dynamic(() => import('components/ui/sanity-image')); interface HeroProps { variant: string; diff --git a/components/modules/slider/slider.tsx b/components/modules/slider/slider.tsx index 7bd810bb1..856380160 100644 --- a/components/modules/slider/slider.tsx +++ b/components/modules/slider/slider.tsx @@ -1,39 +1,36 @@ -import Text from 'components/ui/text' -import dynamic from 'next/dynamic' -import { useEffect, useState } from 'react' +'use client'; -import { Carousel, CarouselItem } from 'components/modules/carousel/carousel' +import Text from 'components/ui/text'; +import { useEffect, useState } from 'react'; -const ProductCard = dynamic(() => import('components/ui/product-card')) -const CategoryCard = dynamic(() => import('components/ui/category-card')) +import CategoryCard from '@/components/ui/category-card/category-card'; +import ProductCard from '@/components/ui/product-card/product-card'; +import { Carousel, CarouselItem } from 'components/modules/carousel/carousel'; interface SliderProps { - products: [] | any - title: string - categories: [] | any - sliderType: String + products: [] | any; + title: string; + categories: [] | any; + sliderType: String; } const Slider = ({ products, categories, title, sliderType }: SliderProps) => { - const [items, setItems] = useState([]) + const [items, setItems] = useState([]); useEffect(() => { - if (sliderType === 'products') setItems(products) - else if (sliderType === 'categories') setItems(categories) - }, []) + if (sliderType === 'products') setItems(products); + else if (sliderType === 'categories') setItems(categories); + }, []); return ( <div className="flex flex-col"> {title ? ( - <Text - className="mb-4 px-4 lg:px-8 lg:mb-6 2xl:px-16 2xl:mb-8" - variant="sectionHeading" - > + <Text className="mb-4 px-4 lg:mb-6 lg:px-8 2xl:mb-8 2xl:px-16" variant="sectionHeading"> {title} </Text> ) : ( <Text - className="italic mb-4 px-4 lg:px-8 lg:mb-6 2xl:px-16 2xl:mb-8" + className="mb-4 px-4 italic lg:mb-6 lg:px-8 2xl:mb-8 2xl:px-16" variant="sectionHeading" > No title provided yet @@ -48,7 +45,7 @@ const Slider = ({ products, categories, title, sliderType }: SliderProps) => { breakpoint: 1024, settings: { slidesToShow: 4.5 - }, + } }} > {items.map((item: any, index: number) => ( @@ -60,7 +57,7 @@ const Slider = ({ products, categories, title, sliderType }: SliderProps) => { </Carousel> )} </div> - ) -} + ); +}; -export default Slider +export default Slider; diff --git a/components/product/product-view.tsx b/components/product/product-view.tsx index 07176bead..70b981e6b 100644 --- a/components/product/product-view.tsx +++ b/components/product/product-view.tsx @@ -6,9 +6,9 @@ import Text from 'components/ui/text/text'; import { Product } from 'lib/storm/types/product'; import { cn } from 'lib/utils'; import { useTranslations } from 'next-intl'; -import dynamic from 'next/dynamic'; +import { Suspense } from 'react'; +import ProductCard from '../ui/product-card/product-card'; import Price from './price'; -const ProductCard = dynamic(() => import('components/ui/product-card')); interface ProductViewProps { product: Product; relatedProducts: Product[]; @@ -81,31 +81,33 @@ export default function ProductView({ product, relatedProducts }: ProductViewPro </div> {relatedProducts.length > 0 && ( - <section className="my-16 flex flex-col lg:my-24"> - <Text className="px-4 lg:px-8 2xl:px-16" variant="sectionHeading"> - {t('related')} - </Text> + <Suspense> + <section className="my-16 flex flex-col lg:my-24"> + <Text className="px-4 lg:px-8 2xl:px-16" variant="sectionHeading"> + {t('related')} + </Text> - <Carousel - gliderClasses={'px-4 lg:px-8 2xl:px-16'} - hasArrows={true} - hasDots={true} - slidesToShow={2.2} - slidesToScroll={1} - responsive={{ - breakpoint: 1024, - settings: { - slidesToShow: 4.5 - } - }} - > - {relatedProducts.map((p) => ( - <CarouselItem key={`product-${p.path}`}> - <ProductCard product={p} /> - </CarouselItem> - ))} - </Carousel> - </section> + <Carousel + gliderClasses={'px-4 lg:px-8 2xl:px-16'} + hasArrows={true} + hasDots={true} + slidesToShow={2.2} + slidesToScroll={1} + responsive={{ + breakpoint: 1024, + settings: { + slidesToShow: 4.5 + } + }} + > + {relatedProducts.map((p) => ( + <CarouselItem key={`product-${p.path}`}> + <ProductCard product={p} /> + </CarouselItem> + ))} + </Carousel> + </section> + </Suspense> )} </div> ); diff --git a/components/ui/product-card/product-card.tsx b/components/ui/product-card/product-card.tsx index f3aeeb57e..2184dd4d8 100644 --- a/components/ui/product-card/product-card.tsx +++ b/components/ui/product-card/product-card.tsx @@ -1,15 +1,12 @@ 'use client'; +import SanityImage from '@/components/ui/sanity-image/sanity-image'; import Price from 'components/product/price'; import Text from 'components/ui/text'; import type { Product } from 'lib/storm/types/product'; import { cn } from 'lib/utils'; -import dynamic from 'next/dynamic'; import Link from 'next/link'; import { FC } from 'react'; - -const SanityImage = dynamic(() => import('components/ui/sanity-image')); - interface Props { className?: string; product: Product;