From 4684d54ac3d79b84c3e7ea11c7331aa8cc55e22b Mon Sep 17 00:00:00 2001 From: Chloe Date: Tue, 21 May 2024 15:19:00 +0700 Subject: [PATCH] fix: create side dialog for content inside PDP Signed-off-by: Chloe --- app/search/[collection]/page.tsx | 6 +-- components/filters/index.tsx | 4 +- .../layout/search/filters/filters-list.tsx | 5 +- components/product/core-charge.tsx | 29 ++++++---- components/product/product-description.tsx | 9 ++-- components/product/vairant-details.tsx | 37 +++++++++++++ components/product/vairant-price.tsx | 31 ----------- components/product/warranty.tsx | 35 ++++++++++-- components/profile/popover.tsx | 10 ++-- components/side-dialog.tsx | 53 +++++++++++++++++++ 10 files changed, 156 insertions(+), 63 deletions(-) create mode 100644 components/product/vairant-details.tsx delete mode 100644 components/product/vairant-price.tsx create mode 100644 components/side-dialog.tsx diff --git a/app/search/[collection]/page.tsx b/app/search/[collection]/page.tsx index e93fef258..fde4ddf56 100644 --- a/app/search/[collection]/page.tsx +++ b/app/search/[collection]/page.tsx @@ -86,11 +86,11 @@ export default function CategorySearchPage(props: { return ( <>
- }> + } key={props.params.collection}>
- }> + } key={props.params.collection}>
@@ -98,7 +98,7 @@ export default function CategorySearchPage(props: {
- }> + } key={props.params.collection}> diff --git a/components/filters/index.tsx b/components/filters/index.tsx index 40bf6f52f..57f1e05f1 100644 --- a/components/filters/index.tsx +++ b/components/filters/index.tsx @@ -5,9 +5,9 @@ import FiltersList from './filters-list'; const YMMFiltersContainer = ({ children }: { children: ReactNode }) => { return (
-
+

Find Your Car Part -

+

{children}
); diff --git a/components/layout/search/filters/filters-list.tsx b/components/layout/search/filters/filters-list.tsx index e12a0a22c..ad4f45085 100644 --- a/components/layout/search/filters/filters-list.tsx +++ b/components/layout/search/filters/filters-list.tsx @@ -47,7 +47,10 @@ const Filters = ({ filters, defaultOpen = true }: { filters: Filter[]; defaultOp >
{label}
- +
{type === FilterType.PRICE_RANGE ? ( diff --git a/components/product/core-charge.tsx b/components/product/core-charge.tsx index adccc0a83..1d2199e34 100644 --- a/components/product/core-charge.tsx +++ b/components/product/core-charge.tsx @@ -2,11 +2,12 @@ import { ArrowPathRoundedSquareIcon } from '@heroicons/react/24/outline'; import Price from 'components/price'; +import SideDialog from 'components/side-dialog'; import { CORE_VARIANT_ID_KEY, CORE_WAIVER } from 'lib/constants'; import { CoreChargeOption, ProductVariant } from 'lib/shopify/types'; import { cn, createUrl } from 'lib/utils'; -import Link from 'next/link'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useState } from 'react'; type CoreChargeProps = { variants: ProductVariant[]; @@ -16,6 +17,7 @@ const CoreCharge = ({ variants }: CoreChargeProps) => { const pathname = usePathname(); const router = useRouter(); + const [isOpenDialog, setIsOpenDialog] = useState(false); const optionSearchParams = new URLSearchParams(searchParams); const coreVariantIdSearchParam = optionSearchParams.get(CORE_VARIANT_ID_KEY); @@ -52,6 +54,9 @@ const CoreCharge = ({ variants }: CoreChargeProps) => { handleSelectCoreChargeOption((coreChargeOptions[0] as CoreChargeOption).value); } + const openDialog = () => setIsOpenDialog(true); + const closeDialog = () => setIsOpenDialog(false); + return (
@@ -59,17 +64,21 @@ const CoreCharge = ({ variants }: CoreChargeProps) => { Core charge
- + + + +
+

+ The core charge is a refundable deposit that is added to the price of the part. This + charge ensures that the old, worn-out part is returned to the supplier for proper + disposal or recycling. When you return the old part, you'll receive a refund of + the core charge. +

+
+
- {/* - Plan is to move this to within the a modal tht opens when a user clicks on Understanding Core Charges and Returns -

- The core charge is a refundable deposit that is added to the price of the part. This charge - ensures that the old, worn-out part is returned to the supplier for proper disposal or - recycling. When you return the old part, you'll receive a refund of the core charge. -

*/}
    {coreChargeOptions.map((option) => (
  • diff --git a/components/product/product-description.tsx b/components/product/product-description.tsx index e22248464..1ec353d58 100644 --- a/components/product/product-description.tsx +++ b/components/product/product-description.tsx @@ -4,7 +4,7 @@ import { Product } from 'lib/shopify/types'; import { Suspense } from 'react'; import CoreCharge from './core-charge'; import SpecialOffer from './special-offer'; -import VariantPrice from './vairant-price'; +import VariantDetails from './vairant-details'; import { VariantSelector } from './variant-selector'; import Warranty from './warranty'; @@ -13,11 +13,8 @@ export function ProductDescription({ product }: { product: Product }) { <>

    {product.title}

    -
    -

    SKU: 123456

    -

    Condition: Used

    -
    - diff --git a/components/product/vairant-details.tsx b/components/product/vairant-details.tsx new file mode 100644 index 000000000..6687250b7 --- /dev/null +++ b/components/product/vairant-details.tsx @@ -0,0 +1,37 @@ +'use client'; + +import Price from 'components/price'; +import { Money, ProductVariant } from 'lib/shopify/types'; +import { useSearchParams } from 'next/navigation'; + +type VariantDetailsProps = { + variants: ProductVariant[]; + defaultPrice: Money; +}; + +const VariantDetails = ({ variants, defaultPrice }: VariantDetailsProps) => { + const searchParams = useSearchParams(); + const variant = variants.find((variant: ProductVariant) => + variant.selectedOptions.every( + (option) => option.value === searchParams.get(option.name.toLowerCase()) + ) + ); + + const price = variant?.price.amount || defaultPrice.amount; + + return ( + <> +
    +

    SKU: {variant?.sku || 'N/A'}

    +

    Condition: {variant?.condition || 'N/A'}

    +
    + + + ); +}; + +export default VariantDetails; diff --git a/components/product/vairant-price.tsx b/components/product/vairant-price.tsx deleted file mode 100644 index 74b5361a2..000000000 --- a/components/product/vairant-price.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client'; - -import Price from 'components/price'; -import { Money, ProductVariant } from 'lib/shopify/types'; -import { useSearchParams } from 'next/navigation'; - -type PriceWithCoreChargeProps = { - variants: ProductVariant[]; - defaultPrice: Money; -}; - -const VariantPrice = ({ variants, defaultPrice }: PriceWithCoreChargeProps) => { - const searchParams = useSearchParams(); - const variant = variants.find((variant: ProductVariant) => - variant.selectedOptions.every( - (option) => option.value === searchParams.get(option.name.toLowerCase()) - ) - ); - - const price = variant?.price.amount || defaultPrice.amount; - - return ( - - ); -}; - -export default VariantPrice; diff --git a/components/product/warranty.tsx b/components/product/warranty.tsx index c5f7b11e0..0c31269e7 100644 --- a/components/product/warranty.tsx +++ b/components/product/warranty.tsx @@ -1,8 +1,13 @@ +'use client'; + import { ShieldCheckIcon } from '@heroicons/react/24/outline'; -import Link from 'next/link'; +import SideDialog from 'components/side-dialog'; +import { useState } from 'react'; import WarrantySelector from './warranty-selector'; const Warranty = () => { + const [openingDialog, setOpeningDialog] = useState<'included' | 'terms-conditions' | null>(null); + return (
    @@ -11,14 +16,34 @@ const Warranty = () => { Warranty
    - + + setOpeningDialog(null)} + open={openingDialog === 'included'} + > +

    Warranty Included

    +
    - + + setOpeningDialog(null)} + open={openingDialog === 'terms-conditions'} + > +

    Terms & Conditions

    +
    diff --git a/components/profile/popover.tsx b/components/profile/popover.tsx index d92120d00..1bdf59525 100644 --- a/components/profile/popover.tsx +++ b/components/profile/popover.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Popover, Transition } from '@headlessui/react'; +import { Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react'; import { ArrowRightIcon } from '@heroicons/react/16/solid'; import { Menu } from 'lib/shopify/types'; import { Fragment } from 'react'; @@ -13,9 +13,9 @@ type ProfilePopoverProps = { const ProfilePopover = ({ menu }: ProfilePopoverProps) => { return ( - + - + { leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-1" > - +
    My Account {
) : null} - + ); diff --git a/components/side-dialog.tsx b/components/side-dialog.tsx new file mode 100644 index 000000000..e43eb2d46 --- /dev/null +++ b/components/side-dialog.tsx @@ -0,0 +1,53 @@ +'use client'; +import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'; +import { XMarkIcon } from '@heroicons/react/24/outline'; +import { Fragment } from 'react'; + +type SideDialogProps = { + title: string; + open: boolean; + onClose: () => void; + children: React.ReactNode; +}; + +const SideDialog = ({ title, children, open, onClose }: SideDialogProps) => { + return ( + + + + + + ); +}; + +export default SideDialog;