mirror of
https://github.com/vercel/commerce.git
synced 2025-06-02 06:26:58 +00:00
fix last bug
This commit is contained in:
parent
16b222a22e
commit
e938e0783d
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
|
import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/24/outline';
|
||||||
import { GridTileImage } from 'components/grid/tile';
|
import { GridTileImage } from 'components/grid/tile';
|
||||||
import { useProduct } from 'components/product/product-context';
|
import { useProduct, useUpdateURL } from 'components/product/product-context';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
|
||||||
export function Gallery({ images }: { images: { src: string; altText: string }[] }) {
|
export function Gallery({ images }: { images: { src: string; altText: string }[] }) {
|
||||||
const { state, updateImage } = useProduct();
|
const { state, updateImage } = useProduct();
|
||||||
|
const updateURL = useUpdateURL();
|
||||||
const imageIndex = state.image ? parseInt(state.image) : 0;
|
const imageIndex = state.image ? parseInt(state.image) : 0;
|
||||||
|
|
||||||
const nextImageIndex = imageIndex + 1 < images.length ? imageIndex + 1 : 0;
|
const nextImageIndex = imageIndex + 1 < images.length ? imageIndex + 1 : 0;
|
||||||
@ -33,7 +34,10 @@ export function Gallery({ images }: { images: { src: string; altText: string }[]
|
|||||||
<div className="absolute bottom-[15%] flex w-full justify-center">
|
<div className="absolute bottom-[15%] flex w-full justify-center">
|
||||||
<div className="mx-auto flex h-11 items-center rounded-full border border-white bg-neutral-50/80 text-neutral-500 backdrop-blur dark:border-black dark:bg-neutral-900/80">
|
<div className="mx-auto flex h-11 items-center rounded-full border border-white bg-neutral-50/80 text-neutral-500 backdrop-blur dark:border-black dark:bg-neutral-900/80">
|
||||||
<button
|
<button
|
||||||
formAction={() => updateImage(previousImageIndex.toString())}
|
formAction={() => {
|
||||||
|
const newState = updateImage(previousImageIndex.toString());
|
||||||
|
updateURL(newState);
|
||||||
|
}}
|
||||||
aria-label="Previous product image"
|
aria-label="Previous product image"
|
||||||
className={buttonClassName}
|
className={buttonClassName}
|
||||||
>
|
>
|
||||||
@ -41,7 +45,10 @@ export function Gallery({ images }: { images: { src: string; altText: string }[]
|
|||||||
</button>
|
</button>
|
||||||
<div className="mx-1 h-6 w-px bg-neutral-500"></div>
|
<div className="mx-1 h-6 w-px bg-neutral-500"></div>
|
||||||
<button
|
<button
|
||||||
formAction={() => updateImage(nextImageIndex.toString())}
|
formAction={() => {
|
||||||
|
const newState = updateImage(nextImageIndex.toString());
|
||||||
|
updateURL(newState);
|
||||||
|
}}
|
||||||
aria-label="Next product image"
|
aria-label="Next product image"
|
||||||
className={buttonClassName}
|
className={buttonClassName}
|
||||||
>
|
>
|
||||||
@ -60,7 +67,10 @@ export function Gallery({ images }: { images: { src: string; altText: string }[]
|
|||||||
return (
|
return (
|
||||||
<li key={image.src} className="h-20 w-20">
|
<li key={image.src} className="h-20 w-20">
|
||||||
<button
|
<button
|
||||||
formAction={() => updateImage(index.toString())}
|
formAction={() => {
|
||||||
|
const newState = updateImage(index.toString());
|
||||||
|
updateURL(newState);
|
||||||
|
}}
|
||||||
aria-label="Select product image"
|
aria-label="Select product image"
|
||||||
className="h-full w-full"
|
className="h-full w-full"
|
||||||
>
|
>
|
||||||
|
@ -11,14 +11,13 @@ type ProductState = {
|
|||||||
|
|
||||||
type ProductContextType = {
|
type ProductContextType = {
|
||||||
state: ProductState;
|
state: ProductState;
|
||||||
updateOption: (name: string, value: string) => void;
|
updateOption: (name: string, value: string) => ProductState;
|
||||||
updateImage: (index: string) => void;
|
updateImage: (index: string) => ProductState;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ProductContext = createContext<ProductContextType | undefined>(undefined);
|
const ProductContext = createContext<ProductContextType | undefined>(undefined);
|
||||||
|
|
||||||
export function ProductProvider({ children }: { children: React.ReactNode }) {
|
export function ProductProvider({ children }: { children: React.ReactNode }) {
|
||||||
const router = useRouter();
|
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
const getInitialState = () => {
|
const getInitialState = () => {
|
||||||
@ -38,17 +37,15 @@ export function ProductProvider({ children }: { children: React.ReactNode }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const updateOption = (name: string, value: string) => {
|
const updateOption = (name: string, value: string) => {
|
||||||
setOptimisticState({ [name]: value });
|
const newState = { [name]: value };
|
||||||
const newParams = new URLSearchParams(window.location.search);
|
setOptimisticState(newState);
|
||||||
newParams.set(name, value);
|
return { ...state, ...newState };
|
||||||
router.push(`?${newParams.toString()}`, { scroll: false });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateImage = (index: string) => {
|
const updateImage = (index: string) => {
|
||||||
setOptimisticState({ image: index });
|
const newState = { image: index };
|
||||||
const newParams = new URLSearchParams(window.location.search);
|
setOptimisticState(newState);
|
||||||
newParams.set('image', index);
|
return { ...state, ...newState };
|
||||||
router.push(`?${newParams.toString()}`, { scroll: false });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
@ -70,3 +67,15 @@ export function useProduct() {
|
|||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useUpdateURL() {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (state: ProductState) => {
|
||||||
|
const newParams = new URLSearchParams(window.location.search);
|
||||||
|
Object.entries(state).forEach(([key, value]) => {
|
||||||
|
newParams.set(key, value);
|
||||||
|
});
|
||||||
|
router.push(`?${newParams.toString()}`, { scroll: false });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useProduct } from 'components/product/product-context';
|
import { useProduct, useUpdateURL } from 'components/product/product-context';
|
||||||
import { ProductOption, ProductVariant } from 'lib/shopify/types';
|
import { ProductOption, ProductVariant } from 'lib/shopify/types';
|
||||||
|
|
||||||
type Combination = {
|
type Combination = {
|
||||||
@ -18,6 +18,7 @@ export function VariantSelector({
|
|||||||
variants: ProductVariant[];
|
variants: ProductVariant[];
|
||||||
}) {
|
}) {
|
||||||
const { state, updateOption } = useProduct();
|
const { state, updateOption } = useProduct();
|
||||||
|
const updateURL = useUpdateURL();
|
||||||
const hasNoOptionsOrJustOneOption =
|
const hasNoOptionsOrJustOneOption =
|
||||||
!options.length || (options.length === 1 && options[0]?.values.length === 1);
|
!options.length || (options.length === 1 && options[0]?.values.length === 1);
|
||||||
|
|
||||||
@ -62,7 +63,10 @@ export function VariantSelector({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
formAction={() => updateOption(optionNameLowerCase, value)}
|
formAction={() => {
|
||||||
|
const newState = updateOption(optionNameLowerCase, value);
|
||||||
|
updateURL(newState);
|
||||||
|
}}
|
||||||
key={value}
|
key={value}
|
||||||
aria-disabled={!isAvailableForSale}
|
aria-disabled={!isAvailableForSale}
|
||||||
disabled={!isAvailableForSale}
|
disabled={!isAvailableForSale}
|
||||||
|
@ -8,7 +8,6 @@ export function WelcomeToast() {
|
|||||||
// ignore if screen height is too small
|
// ignore if screen height is too small
|
||||||
if (window.innerHeight < 650) return;
|
if (window.innerHeight < 650) return;
|
||||||
if (!document.cookie.includes('welcome-toast=2')) {
|
if (!document.cookie.includes('welcome-toast=2')) {
|
||||||
console.log('Welcome to Next.js Commerce!');
|
|
||||||
toast('🛍️ Welcome to Next.js Commerce!', {
|
toast('🛍️ Welcome to Next.js Commerce!', {
|
||||||
id: 'welcome-toast',
|
id: 'welcome-toast',
|
||||||
duration: Infinity,
|
duration: Infinity,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user