mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
feat: implement variant selector panel
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
@@ -2,15 +2,14 @@
|
||||
|
||||
import Price from 'components/price';
|
||||
import { CORE_VARIANT_ID_KEY, CORE_WAIVER } from 'lib/constants';
|
||||
import { Money, ProductVariant } from 'lib/shopify/types';
|
||||
import { CoreChargeOption, ProductVariant } from 'lib/shopify/types';
|
||||
import { cn, createUrl } from 'lib/utils';
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
||||
|
||||
type CoreChargeProps = {
|
||||
variants: ProductVariant[];
|
||||
defaultPrice: Money;
|
||||
};
|
||||
const CoreCharge = ({ variants, defaultPrice }: CoreChargeProps) => {
|
||||
const CoreCharge = ({ variants }: CoreChargeProps) => {
|
||||
const searchParams = useSearchParams();
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
@@ -24,35 +23,32 @@ const CoreCharge = ({ variants, defaultPrice }: CoreChargeProps) => {
|
||||
)
|
||||
);
|
||||
|
||||
const { coreCharge, waiverAvailable } = variant ?? {};
|
||||
const { coreCharge, waiverAvailable, coreVariantId } = variant ?? {};
|
||||
|
||||
const handleSelectCoreChargeOption = (action: 'add' | 'remove') => {
|
||||
if (action === 'add' && variant?.coreVariantId) {
|
||||
optionSearchParams.set(CORE_VARIANT_ID_KEY, variant.coreVariantId);
|
||||
} else if (action === 'remove') {
|
||||
optionSearchParams.set(CORE_VARIANT_ID_KEY, CORE_WAIVER);
|
||||
}
|
||||
const handleSelectCoreChargeOption = (coreVariantId: string) => {
|
||||
optionSearchParams.set(CORE_VARIANT_ID_KEY, coreVariantId);
|
||||
|
||||
const newUrl = createUrl(pathname, optionSearchParams);
|
||||
router.replace(newUrl, { scroll: false });
|
||||
};
|
||||
|
||||
// if the selected variant has changed, and the core change variant id is not the same as the selected variant id
|
||||
// or if users have selected the core waiver but the selected variant does not have a waiver available
|
||||
// we remove the core charge from the url
|
||||
if (
|
||||
variant?.coreVariantId &&
|
||||
optionSearchParams.has(CORE_VARIANT_ID_KEY) &&
|
||||
(coreVariantIdSearchParam !== CORE_WAIVER || !variant.waiverAvailable) &&
|
||||
coreVariantIdSearchParam !== variant.coreVariantId
|
||||
) {
|
||||
optionSearchParams.delete(CORE_VARIANT_ID_KEY);
|
||||
const newUrl = createUrl(pathname, optionSearchParams);
|
||||
router.replace(newUrl, { scroll: false });
|
||||
}
|
||||
const coreChargeOptions = [
|
||||
waiverAvailable && {
|
||||
label: 'Core Waiver',
|
||||
value: CORE_WAIVER,
|
||||
price: { amount: 0, currencyCode: variant?.price.currencyCode }
|
||||
},
|
||||
coreVariantId &&
|
||||
coreCharge && {
|
||||
label: 'Core Charge',
|
||||
value: coreVariantId,
|
||||
price: coreCharge
|
||||
}
|
||||
].filter(Boolean) as CoreChargeOption[];
|
||||
|
||||
const selectedPayCoreCharge = coreVariantIdSearchParam === variant?.coreVariantId;
|
||||
const selectedCoreWaiver = coreVariantIdSearchParam === CORE_WAIVER;
|
||||
if (!optionSearchParams.has(CORE_VARIANT_ID_KEY) && coreChargeOptions.length > 0) {
|
||||
handleSelectCoreChargeOption((coreChargeOptions[0] as CoreChargeOption).value);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col text-xs lg:text-sm">
|
||||
@@ -63,38 +59,22 @@ const CoreCharge = ({ variants, defaultPrice }: CoreChargeProps) => {
|
||||
recycling. When you return the old part, you'll receive a refund of the core charge.
|
||||
</p>
|
||||
<ul className="flex min-h-16 flex-row space-x-4 pt-2">
|
||||
{waiverAvailable ? (
|
||||
<li className="flex w-32">
|
||||
{coreChargeOptions.map((option) => (
|
||||
<li className="flex w-32" key={option.value}>
|
||||
<button
|
||||
onClick={() => handleSelectCoreChargeOption('remove')}
|
||||
onClick={() => handleSelectCoreChargeOption(option.value)}
|
||||
className={cn(
|
||||
'flex w-full flex-col flex-wrap items-center justify-center space-y-2 rounded-md border p-2 text-center text-xs font-medium',
|
||||
{
|
||||
'ring-2 ring-secondary': selectedCoreWaiver
|
||||
'ring-2 ring-secondary': coreVariantIdSearchParam === option.value
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>Core Waiver</span>
|
||||
<Price amount="0" currencyCode={defaultPrice.currencyCode} />
|
||||
<span>{option.label}</span>
|
||||
<Price {...option.price} />
|
||||
</button>
|
||||
</li>
|
||||
) : null}
|
||||
{coreCharge && variant?.coreVariantId ? (
|
||||
<li className="flex w-32">
|
||||
<button
|
||||
onClick={() => handleSelectCoreChargeOption('add')}
|
||||
className={cn(
|
||||
'flex w-full flex-col flex-wrap items-center justify-center space-y-2 rounded-md border p-2 text-center text-xs font-medium',
|
||||
{
|
||||
'ring-2 ring-secondary': selectedPayCoreCharge
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>Core Charge</span>
|
||||
<Price amount={coreCharge.amount} currencyCode={coreCharge.currencyCode} />
|
||||
</button>
|
||||
</li>
|
||||
) : null}
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
Reference in New Issue
Block a user