From 59c3f07bebcbb35a1e871cc5f201c658aa0ddbaf Mon Sep 17 00:00:00 2001 From: Chloe Date: Thu, 25 Apr 2024 14:14:20 +0700 Subject: [PATCH] feat: adding more information warranty, part number, sku, speciall offers Signed-off-by: Chloe --- app/product/[handle]/page.tsx | 6 +- components/cart/core-charge-badge.tsx | 2 - components/cart/modal.tsx | 2 +- components/core-charge.tsx | 43 +++++++------- components/product/gallery.tsx | 46 ++++++++------- components/product/price-with-core-charge.tsx | 49 +++++++--------- components/product/product-description.tsx | 15 ++++- components/product/special-offer.tsx | 27 +++++++++ components/product/variant-selector.tsx | 4 +- components/product/warranty-selector.tsx | 57 +++++++++++++++++++ components/product/warranty.tsx | 30 ++++++++++ lib/shopify/fragments/product.ts | 5 ++ lib/shopify/index.ts | 6 +- lib/shopify/types.ts | 8 ++- 14 files changed, 215 insertions(+), 85 deletions(-) create mode 100644 components/product/special-offer.tsx create mode 100644 components/product/warranty-selector.tsx create mode 100644 components/product/warranty.tsx diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 423a559f2..4adbfa0e3 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -84,8 +84,8 @@ export default async function ProductPage({ params }: { params: { handle: string />
-
-
+
+
@@ -100,7 +100,7 @@ export default async function ProductPage({ params }: { params: { handle: string
-
+
diff --git a/components/cart/core-charge-badge.tsx b/components/cart/core-charge-badge.tsx index f977d9fe7..eaf29364c 100644 --- a/components/cart/core-charge-badge.tsx +++ b/components/cart/core-charge-badge.tsx @@ -11,12 +11,10 @@ type CoreChargeBadgeProps = { const CoreChargeBadge = ({ variants, selectedOptions }: CoreChargeBadgeProps) => { const selectedOptionsMap = new Map(selectedOptions.map((option) => [option.name, option.value])); - console.log({ selectedOptionsMap, variants }); const variant = variants.find((variant: ProductVariant) => variant.selectedOptions.every((option) => option.value === selectedOptionsMap.get(option.name)) ); - console.log({ variant }); return ; }; diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx index 1f6cdad5c..29a8e43b3 100644 --- a/components/cart/modal.tsx +++ b/components/cart/modal.tsx @@ -183,7 +183,7 @@ export default function CartModal({ cart }: { cart: Cart | undefined }) {
Proceed to Checkout diff --git a/components/core-charge.tsx b/components/core-charge.tsx index 55346fb91..73ab23632 100644 --- a/components/core-charge.tsx +++ b/components/core-charge.tsx @@ -11,35 +11,36 @@ type CoreChargeProps = { const CoreCharge = ({ variant, sm = false }: CoreChargeProps) => { if (!variant || !variant.coreCharge?.amount || variant.waiverAvailable) return null; - const originalPrice = String(Number(variant.price.amount) - Number(variant.coreCharge.amount)); - const coreChargeDisplay = ( ); + const originalPrice = String(Number(variant.price.amount) - Number(variant.coreCharge.amount)); + return (
- - + + {sm ? coreChargeDisplay : <>Core Charge: {coreChargeDisplay}} - {sm ? null : ( - -

- The core charge of {coreChargeDisplay} 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, making - the final price of the part{' '} - -

-
- )} + +

+ The core charge of {coreChargeDisplay} 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, making the + final price of the part + +

+
); }; diff --git a/components/product/gallery.tsx b/components/product/gallery.tsx index 0b03557a5..a9f19cf4a 100644 --- a/components/product/gallery.tsx +++ b/components/product/gallery.tsx @@ -39,29 +39,33 @@ export function Gallery({ images }: { images: { src: string; altText: string }[] priority={true} /> )} - {images.length > 1 ? ( -
-
- - - -
- - - + <> +
+
+ + + +
+ + + +
-
+

+ Representative Image +

+ ) : null}
diff --git a/components/product/price-with-core-charge.tsx b/components/product/price-with-core-charge.tsx index 0d177ce4e..a689f66a9 100644 --- a/components/product/price-with-core-charge.tsx +++ b/components/product/price-with-core-charge.tsx @@ -1,10 +1,7 @@ 'use client'; -import { InformationCircleIcon } from '@heroicons/react/24/outline'; -import { Checkbox } from 'components/checkbox'; import CoreCharge from 'components/core-charge'; import Price from 'components/price'; -import Tooltip from 'components/tooltip'; import { Money, ProductVariant } from 'lib/shopify/types'; import { useSearchParams } from 'next/navigation'; @@ -20,32 +17,28 @@ const PriceWithCoreCharge = ({ variants, defaultPrice }: PriceWithCoreChargeProp (option) => option.value === searchParams.get(option.name.toLowerCase()) ) ); - console.log({ variant }); + + const price = variant?.price.amount || defaultPrice.amount; + return ( -
- - - {variant?.coreCharge?.amount && variant.waiverAvailable ? ( -
- - - Select this if you do not have a core to return -
- ) : null} -
+ <> +
+ {variant && ( +
+ {variant.sku && SKU: {variant.sku}} + {variant.barcode && Part Number: {variant.barcode}} +
+ )} +
+
+ + +
+ ); }; diff --git a/components/product/product-description.tsx b/components/product/product-description.tsx index 0faec0d43..d30c5c239 100644 --- a/components/product/product-description.tsx +++ b/components/product/product-description.tsx @@ -3,13 +3,15 @@ import Prose from 'components/prose'; import { Product } from 'lib/shopify/types'; import { Suspense } from 'react'; import PriceWithCoreCharge from './price-with-core-charge'; +import SpecialOffer from './special-offer'; import { VariantSelector } from './variant-selector'; +import Warranty from './warranty'; export function ProductDescription({ product }: { product: Product }) { return ( <> -
-

{product.title}

+
+

{product.title}

) : null} +
+ +
+ +
+ +
); } diff --git a/components/product/special-offer.tsx b/components/product/special-offer.tsx new file mode 100644 index 000000000..2ce75a3ef --- /dev/null +++ b/components/product/special-offer.tsx @@ -0,0 +1,27 @@ +import { CurrencyDollarIcon, ShieldCheckIcon, UsersIcon } from '@heroicons/react/24/outline'; +import { TruckIcon } from '@heroicons/react/24/solid'; + +const SpecialOffer = () => { + return ( + <> +
Special Offers
+
+

+ Flat Rate Shipping (Commercial Address) +

+

+ Up to 5 Years Unlimited Miles + Warranty +

+

+ Excellent Customer Support +

+

+ No Core Charge for 30 days +

+
+ + ); +}; + +export default SpecialOffer; diff --git a/components/product/variant-selector.tsx b/components/product/variant-selector.tsx index 88feaf424..4ffaca313 100644 --- a/components/product/variant-selector.tsx +++ b/components/product/variant-selector.tsx @@ -39,8 +39,8 @@ export function VariantSelector({ })); return options.map((option) => ( -
-
{option.name}
+
+
{option.name}
{option.values.map((value) => { const optionNameLowerCase = option.name.toLowerCase(); diff --git a/components/product/warranty-selector.tsx b/components/product/warranty-selector.tsx new file mode 100644 index 000000000..87302a200 --- /dev/null +++ b/components/product/warranty-selector.tsx @@ -0,0 +1,57 @@ +'use client'; + +import Price from 'components/price'; +import { cn } from 'lib/utils'; +import { ReactNode, useState } from 'react'; + +const options = ['Included', 'Premium Labor', '+1 Year'] as const; +type Option = (typeof options)[number]; + +const plans: Array<{ + key: Option; + template: ReactNode; + price: number; +}> = [ + { + template: ( + <> + Included + 3-Year Warranty + + ), + price: 0, + key: 'Included' + }, + { + template: Premium Labor, + price: 150, + key: 'Premium Labor' + }, + { + template: +1 Year, + price: 100, + key: '+1 Year' + } +]; +const WarrantySelector = () => { + const [selectedOptions, setSelectedOptions] = useState