mirror of
https://github.com/vercel/commerce.git
synced 2025-05-15 14:06:59 +00:00
Merge pull request #1 from BrocksiNet/feat/cart
feat: minicart sidebar and add to cart action
This commit is contained in:
commit
3cccd61aec
@ -2,12 +2,12 @@ import type { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
import { AddToCart } from 'components/cart/add-to-cart';
|
||||
import Grid from 'components/grid';
|
||||
import Footer from 'components/layout/footer';
|
||||
import ProductGridItems from 'components/layout/product-grid-items';
|
||||
import { AddToCart } from 'components/cart/add-to-cart';
|
||||
import { Gallery } from 'components/product/gallery';
|
||||
import { VariantSelector } from 'components/product/variant-selector';
|
||||
import ProductGridItems from 'components/layout/product-grid-items';
|
||||
import { Gallery } from 'components/product/gallery';
|
||||
import Prose from 'components/prose';
|
||||
import { HIDDEN_PRODUCT_TAG } from 'lib/constants';
|
||||
import { getProduct, getProductRecommendations } from 'lib/shopware';
|
||||
@ -104,7 +104,11 @@ export default async function ProductPage({ params }: { params: { handle: string
|
||||
<Prose className="mb-6 text-sm leading-tight" html={product.descriptionHtml} />
|
||||
) : null}
|
||||
|
||||
<AddToCart variants={product.variants} availableForSale={product.availableForSale} />
|
||||
<AddToCart
|
||||
product={product}
|
||||
variants={product.variants}
|
||||
availableForSale={product.availableForSale}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Suspense>
|
||||
|
@ -20,7 +20,7 @@ export async function Carousel() {
|
||||
<Link
|
||||
key={`${product.path}${i}`}
|
||||
href={`/product/${product.path}`}
|
||||
className="relative h-[30vh] w-1/2 flex-none md:w-1/3"
|
||||
className="relative mx-2 my-8 h-[30vh] w-1/2 flex-none md:w-1/3"
|
||||
>
|
||||
{product.featuredImage ? (
|
||||
<Image
|
||||
|
@ -1,31 +1,85 @@
|
||||
'use server';
|
||||
|
||||
import { addToCart, removeFromCart, updateCart } from 'lib/shopify';
|
||||
import { ApiClientError } from '@shopware/api-client';
|
||||
import { getApiClient } from 'lib/shopware/api';
|
||||
import { ExtendedCart, ExtendedLineItem } from 'lib/shopware/api-extended';
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
export const addItem = async (variantId: string | undefined): Promise<Error | undefined> => {
|
||||
const cartId = cookies().get('cartId')?.value;
|
||||
|
||||
if (!cartId || !variantId) {
|
||||
return new Error('Missing cartId or variantId');
|
||||
}
|
||||
export const fetchCart = async function (cartId?: string): Promise<ExtendedCart | undefined> {
|
||||
try {
|
||||
await addToCart(cartId, [{ merchandiseId: variantId, quantity: 1 }]);
|
||||
} catch (e) {
|
||||
return new Error('Error adding item', { cause: e });
|
||||
const apiClient = getApiClient(cartId);
|
||||
const cart = await apiClient.invoke('readCart get /checkout/cart?name', {});
|
||||
|
||||
return cart;
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
console.error('Details:', error.details);
|
||||
} else {
|
||||
console.error('==>', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const addItem = async (variantId: string | undefined): Promise<Error | undefined> => {
|
||||
const cartId = cookies().get('sw-context-token')?.value;
|
||||
|
||||
if (!variantId) {
|
||||
return new Error('Missing variantId');
|
||||
}
|
||||
|
||||
try {
|
||||
let quantity = 1;
|
||||
const apiClient = getApiClient(cartId);
|
||||
|
||||
// this part allows us to click multiple times on addToCart and increase the qty with that
|
||||
const cart = await fetchCart(cartId);
|
||||
const itemInCart = cart?.lineItems?.filter((item) => item.id === variantId) as
|
||||
| ExtendedLineItem
|
||||
| undefined;
|
||||
if (itemInCart && itemInCart.quantity) {
|
||||
quantity = itemInCart.quantity + 1;
|
||||
}
|
||||
|
||||
await apiClient.invoke('addLineItem post /checkout/cart/line-item', {
|
||||
items: [
|
||||
{
|
||||
id: variantId,
|
||||
quantity: quantity,
|
||||
referencedId: variantId,
|
||||
type: 'product'
|
||||
}
|
||||
]
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
console.error('Details:', error.details);
|
||||
} else {
|
||||
console.error('==>', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const removeItem = async (lineId: string): Promise<Error | undefined> => {
|
||||
const cartId = cookies().get('cartId')?.value;
|
||||
const cartId = cookies().get('sw-context-token')?.value;
|
||||
|
||||
if (!cartId) {
|
||||
return new Error('Missing cartId');
|
||||
}
|
||||
|
||||
try {
|
||||
await removeFromCart(cartId, [lineId]);
|
||||
} catch (e) {
|
||||
return new Error('Error removing item', { cause: e });
|
||||
const apiClient = getApiClient(cartId);
|
||||
await apiClient.invoke('deleteLineItem delete /checkout/cart/line-item?id[]={ids}', {
|
||||
ids: [lineId]
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
console.error('Details:', error.details);
|
||||
} else {
|
||||
console.error('==>', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -38,20 +92,29 @@ export const updateItemQuantity = async ({
|
||||
variantId: string;
|
||||
quantity: number;
|
||||
}): Promise<Error | undefined> => {
|
||||
const cartId = cookies().get('cartId')?.value;
|
||||
const cartId = cookies().get('sw-context-token')?.value;
|
||||
|
||||
if (!cartId) {
|
||||
return new Error('Missing cartId');
|
||||
}
|
||||
|
||||
try {
|
||||
await updateCart(cartId, [
|
||||
{
|
||||
id: lineId,
|
||||
merchandiseId: variantId,
|
||||
quantity
|
||||
}
|
||||
]);
|
||||
} catch (e) {
|
||||
return new Error('Error updating item quantity', { cause: e });
|
||||
const apiClient = getApiClient(cartId);
|
||||
await apiClient.invoke('updateLineItem patch /checkout/cart/line-item', {
|
||||
items: [
|
||||
{
|
||||
id: lineId,
|
||||
referencedId: variantId,
|
||||
quantity: quantity
|
||||
}
|
||||
]
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
console.error('Details:', error.details);
|
||||
} else {
|
||||
console.error('==>', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -6,16 +6,19 @@ import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useState, useTransition } from 'react';
|
||||
|
||||
import LoadingDots from 'components/loading-dots';
|
||||
import { Product } from 'lib/shopware/types';
|
||||
import { ProductVariant } from 'lib/shopware/types';
|
||||
|
||||
export function AddToCart({
|
||||
product,
|
||||
variants,
|
||||
availableForSale
|
||||
}: {
|
||||
variants: ProductVariant[];
|
||||
availableForSale: boolean;
|
||||
product: Product;
|
||||
}) {
|
||||
const [selectedVariantId, setSelectedVariantId] = useState(variants[0]?.id);
|
||||
const [selectedVariantId, setSelectedVariantId] = useState(product.id);
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
@ -30,7 +33,7 @@ export function AddToCart({
|
||||
if (variant) {
|
||||
setSelectedVariantId(variant.id);
|
||||
}
|
||||
}, [searchParams, variants, setSelectedVariantId]);
|
||||
}, [searchParams, variants, setSelectedVariantId, selectedVariantId]);
|
||||
|
||||
return (
|
||||
<button
|
||||
@ -42,7 +45,7 @@ export function AddToCart({
|
||||
const error = await addItem(selectedVariantId);
|
||||
|
||||
if (error) {
|
||||
alert(error);
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,37 @@
|
||||
import { getCart } from 'lib/shopware';
|
||||
import { fetchCart } from 'components/cart/actions';
|
||||
import { cookies } from 'next/headers';
|
||||
import CartModal from './modal';
|
||||
import { transformCart } from 'lib/shopware/transform';
|
||||
|
||||
export default async function Cart() {
|
||||
let resCart;
|
||||
const cartId = cookies().get('sw-context-token')?.value;
|
||||
let cartIdUpdated = true;
|
||||
const cart = await getCart();
|
||||
|
||||
if (cartId) {
|
||||
resCart = await fetchCart(cartId);
|
||||
}
|
||||
|
||||
let newToken;
|
||||
if (!cartId && !resCart) {
|
||||
resCart = await fetchCart();
|
||||
if (resCart?.token) {
|
||||
newToken = resCart?.token;
|
||||
}
|
||||
}
|
||||
|
||||
let cart;
|
||||
if (resCart) {
|
||||
cart = transformCart(resCart);
|
||||
}
|
||||
|
||||
if (!cart) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cartId !== cart.id) {
|
||||
let cartIdUpdated = false;
|
||||
if (cartId !== newToken) {
|
||||
cartIdUpdated = true;
|
||||
}
|
||||
|
||||
return <CartModal cart={cart} cartIdUpdated={cartIdUpdated} />;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ type MerchandiseSearchParams = {
|
||||
};
|
||||
|
||||
export default function CartModal({ cart, cartIdUpdated }: { cart: Cart; cartIdUpdated: boolean }) {
|
||||
const [, setCookie] = useCookies(['cartId']);
|
||||
const [, setCookie] = useCookies(['sw-context-token']);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const quantityRef = useRef(cart.totalQuantity);
|
||||
const openCart = () => setIsOpen(true);
|
||||
@ -29,7 +29,7 @@ export default function CartModal({ cart, cartIdUpdated }: { cart: Cart; cartIdU
|
||||
|
||||
useEffect(() => {
|
||||
if (cartIdUpdated) {
|
||||
setCookie('cartId', cart.id, {
|
||||
setCookie('sw-context-token', cart.id, {
|
||||
path: '/',
|
||||
sameSite: 'strict',
|
||||
secure: process.env.NODE_ENV === 'production'
|
||||
@ -49,7 +49,7 @@ export default function CartModal({ cart, cartIdUpdated }: { cart: Cart; cartIdU
|
||||
// Always update the quantity reference
|
||||
quantityRef.current = cart.totalQuantity;
|
||||
}
|
||||
}, [isOpen, cart.totalQuantity, quantityRef]);
|
||||
}, [isOpen, cart, quantityRef]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -121,16 +121,19 @@ export default function CartModal({ cart, cartIdUpdated }: { cart: Cart; cartIdU
|
||||
onClick={closeCart}
|
||||
>
|
||||
<div className="relative h-16 w-16 cursor-pointer overflow-hidden bg-white">
|
||||
<Image
|
||||
className="h-full w-full object-cover"
|
||||
width={64}
|
||||
height={64}
|
||||
alt={
|
||||
item.merchandise.product.featuredImage.altText ||
|
||||
item.merchandise.product.title
|
||||
}
|
||||
src={item.merchandise.product.featuredImage.url}
|
||||
/>
|
||||
{item.merchandise.product.featuredImage.url !== '' &&
|
||||
typeof item.merchandise.product.featuredImage.url !== 'undefined' ? (
|
||||
<Image
|
||||
className="h-full w-full object-cover"
|
||||
width={64}
|
||||
height={64}
|
||||
alt={
|
||||
item.merchandise.product.featuredImage.altText ||
|
||||
item.merchandise.product.title
|
||||
}
|
||||
src={item.merchandise.product.featuredImage.url}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col text-base">
|
||||
<span className="font-semibold">
|
||||
|
@ -10,6 +10,8 @@ type operationsWithoutOriginal = Omit<
|
||||
| 'readProductCrossSellings'
|
||||
| 'readProductListing'
|
||||
| 'searchPage'
|
||||
| 'readCart'
|
||||
| 'deleteLineItem'
|
||||
>;
|
||||
export type extendedPaths =
|
||||
| 'readCategory post /category/{navigationId}?slots'
|
||||
@ -19,6 +21,8 @@ export type extendedPaths =
|
||||
| 'readProductCrossSellings post /product/{productId}/cross-selling'
|
||||
| 'readProductListing post /product-listing/{categoryId}'
|
||||
| 'searchPage post /search'
|
||||
| 'readCart get /checkout/cart?name'
|
||||
| 'deleteLineItem delete /checkout/cart/line-item?id[]={ids}'
|
||||
| operationPaths;
|
||||
export type extendedOperations = operationsWithoutOriginal & {
|
||||
readCategory: extendedReadCategory;
|
||||
@ -28,14 +32,56 @@ export type extendedOperations = operationsWithoutOriginal & {
|
||||
readProductCrossSellings: extendedReadProductCrossSellings;
|
||||
readProductListing: extendedReadProductListing;
|
||||
searchPage: extendedSearchPage;
|
||||
readCart: extendedReadCart;
|
||||
deleteLineItem: extendedDeleteLineItem;
|
||||
};
|
||||
|
||||
export type ExtendedCart = Omit<schemas['Cart'], 'lineItems'> & {
|
||||
lineItems?: ExtendedLineItem[];
|
||||
};
|
||||
|
||||
export type ExtendedLineItem = schemas['LineItem'] & {
|
||||
payload: {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
};
|
||||
price: ProductPrice;
|
||||
cover?: schemas['Media'];
|
||||
};
|
||||
|
||||
type ProductPrice = {
|
||||
unitPrice: number;
|
||||
quantity: number;
|
||||
totalPrice: number;
|
||||
calculatedTaxes: ProductCalculatedTaxes[];
|
||||
taxRules: ProductTaxRules[];
|
||||
referencePrice?: number;
|
||||
listPrice?: number;
|
||||
regulationPrice?: number;
|
||||
apiAlias: string;
|
||||
};
|
||||
|
||||
type ProductCalculatedTaxes = {
|
||||
tax: number;
|
||||
taxRate: number;
|
||||
price: number;
|
||||
apiAlias: string;
|
||||
};
|
||||
|
||||
type ProductTaxRules = {
|
||||
taxRate: number;
|
||||
percentage: number;
|
||||
apiAlias: string;
|
||||
};
|
||||
|
||||
export type ExtendedCmsBlock = Omit<schemas['CmsBlock'], 'slots'> & {
|
||||
slots?: schemas['CmsSlot'][];
|
||||
};
|
||||
|
||||
export type ExtendedCmsSection = Omit<schemas['CmsSection'], 'blocks'> & {
|
||||
blocks?: ExtendedCmsBlock[];
|
||||
};
|
||||
|
||||
export type ExtendedCmsPage = Omit<schemas['CmsPage'], 'sections'> & {
|
||||
sections?: ExtendedCmsSection[];
|
||||
};
|
||||
@ -293,3 +339,37 @@ type extendedReadProductListing = {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type extendedReadCart = {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** The name of the new cart. This parameter will only be used when creating a new cart. */
|
||||
name?: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** Cart */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': ExtendedCart;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type extendedDeleteLineItem = {
|
||||
parameters: {
|
||||
query: {
|
||||
/** A list of product identifiers. */
|
||||
ids: string[];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** The updated cart. */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': ExtendedCart;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -17,11 +17,16 @@ import {
|
||||
} from './types';
|
||||
import { getStoreDomainWithApiType, getAccessToken, getApiType } from 'lib/shopware/helpers';
|
||||
|
||||
const apiInstance = createAPIClient<extendedOperations, extendedPaths>({
|
||||
baseURL: getStoreDomainWithApiType(),
|
||||
accessToken: getAccessToken(),
|
||||
apiType: getApiType()
|
||||
});
|
||||
export function getApiClient(cartId?: string) {
|
||||
const apiClientParams = {
|
||||
baseURL: getStoreDomainWithApiType(),
|
||||
accessToken: getAccessToken(),
|
||||
apiType: getApiType(),
|
||||
contextToken: cartId
|
||||
};
|
||||
|
||||
return createAPIClient<extendedOperations, extendedPaths>(apiClientParams);
|
||||
}
|
||||
|
||||
// reimport operations return types to use it in application
|
||||
export type ApiReturnType<OPERATION_NAME extends keyof operations> = RequestReturnType<
|
||||
@ -34,7 +39,7 @@ export async function requestNavigation(
|
||||
depth: number
|
||||
): Promise<ExtendedCategory[] | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke(
|
||||
return await getApiClient().invoke(
|
||||
'readNavigation post /navigation/{activeId}/{rootId} sw-include-seo-urls',
|
||||
{
|
||||
activeId: type,
|
||||
@ -57,7 +62,7 @@ export async function requestCategory(
|
||||
criteria?: Partial<ProductListingCriteria>
|
||||
): Promise<ExtendedCategory | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke('readCategory post /category/{navigationId}?slots', {
|
||||
return await getApiClient().invoke('readCategory post /category/{navigationId}?slots', {
|
||||
navigationId: categoryId,
|
||||
criteria
|
||||
});
|
||||
@ -75,7 +80,7 @@ export async function requestCategoryList(
|
||||
criteria: Partial<ExtendedCriteria>
|
||||
): Promise<CategoryListingResultSW | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke('readCategoryList post /category', criteria);
|
||||
return await getApiClient().invoke('readCategoryList post /category', criteria);
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
@ -90,7 +95,7 @@ export async function requestProductsCollection(
|
||||
criteria: Partial<ProductListingCriteria>
|
||||
): Promise<ExtendedProductListingResult | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke('readProduct post /product', criteria);
|
||||
return await getApiClient().invoke('readProduct post /product', criteria);
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
@ -106,7 +111,7 @@ export async function requestCategoryProductsCollection(
|
||||
criteria: Partial<ProductListingCriteria>
|
||||
): Promise<ExtendedProductListingResult | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke('readProductListing post /product-listing/{categoryId}', {
|
||||
return await getApiClient().invoke('readProductListing post /product-listing/{categoryId}', {
|
||||
...criteria,
|
||||
categoryId: categoryId
|
||||
});
|
||||
@ -124,7 +129,7 @@ export async function requestSearchCollectionProducts(
|
||||
criteria?: Partial<ProductListingCriteria>
|
||||
): Promise<ExtendedProductListingResult | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke('searchPage post /search', {
|
||||
return await getApiClient().invoke('searchPage post /search', {
|
||||
search: encodeURIComponent(criteria?.query || ''),
|
||||
...criteria
|
||||
});
|
||||
@ -140,7 +145,7 @@ export async function requestSearchCollectionProducts(
|
||||
|
||||
export async function requestSeoUrls(routeName: RouteNames, page: number = 1, limit: number = 100) {
|
||||
try {
|
||||
return await apiInstance.invoke('readSeoUrl post /seo-url', {
|
||||
return await getApiClient().invoke('readSeoUrl post /seo-url', {
|
||||
page: page,
|
||||
limit: limit,
|
||||
filter: [
|
||||
@ -190,7 +195,7 @@ export async function requestSeoUrl(
|
||||
]
|
||||
};
|
||||
// @ts-ignore
|
||||
return await apiInstance.invoke('readSeoUrl post /seo-url', criteriaSeoUrls);
|
||||
return await getApiClient().invoke('readSeoUrl post /seo-url', criteriaSeoUrls);
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
@ -206,7 +211,7 @@ export async function requestCrossSell(
|
||||
criteria?: Partial<ProductListingCriteria>
|
||||
): Promise<ExtendedCrossSellingElementCollection | undefined> {
|
||||
try {
|
||||
return await apiInstance.invoke(
|
||||
return await getApiClient().invoke(
|
||||
'readProductCrossSellings post /product/{productId}/cross-selling',
|
||||
{
|
||||
productId: productId,
|
||||
@ -223,9 +228,9 @@ export async function requestCrossSell(
|
||||
}
|
||||
}
|
||||
|
||||
export async function requestCart() {
|
||||
export async function requestContext(cartId?: string) {
|
||||
try {
|
||||
return apiInstance.invoke('readCart get /checkout/cart?name', {});
|
||||
return getApiClient(cartId).invoke('readContext get /context', {});
|
||||
} catch (error) {
|
||||
if (error instanceof ApiClientError) {
|
||||
console.error(error);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {
|
||||
requestCart,
|
||||
requestCategory,
|
||||
requestCategoryList,
|
||||
requestCategoryProductsCollection,
|
||||
@ -32,7 +31,6 @@ import {
|
||||
} from './transform';
|
||||
import {
|
||||
ApiSchemas,
|
||||
Cart,
|
||||
CategoryListingResultSW,
|
||||
Menu,
|
||||
Page,
|
||||
@ -293,75 +291,3 @@ export async function getProductRecommendations(productId: string): Promise<Prod
|
||||
|
||||
return products ? transformProducts(products) : [];
|
||||
}
|
||||
|
||||
export async function getCart(): Promise<Cart | undefined> {
|
||||
const cartData = await requestCart();
|
||||
if (cartData) {
|
||||
// @ToDo: should be moved to transformCart function
|
||||
const cart: Cart = {
|
||||
checkoutUrl: 'https://frontends-demo.vercel.app',
|
||||
cost: {
|
||||
subtotalAmount: {
|
||||
amount: cartData.price?.positionPrice?.toString() || '0',
|
||||
currencyCode: 'EUR'
|
||||
},
|
||||
totalAmount: {
|
||||
amount: cartData.price?.totalPrice?.toString() || '0',
|
||||
currencyCode: 'EUR'
|
||||
},
|
||||
totalTaxAmount: {
|
||||
amount: '0',
|
||||
currencyCode: 'EUR'
|
||||
}
|
||||
},
|
||||
id: cartData.token || '',
|
||||
lines:
|
||||
cartData.lineItems?.map((lineItem) => ({
|
||||
id: lineItem.referencedId || '',
|
||||
quantity: lineItem.quantity ?? 0,
|
||||
cost: {
|
||||
totalAmount: {
|
||||
amount: (lineItem as any)?.price?.totalPrice || '',
|
||||
currencyCode: 'EUR'
|
||||
}
|
||||
},
|
||||
merchandise: {
|
||||
id: lineItem.referencedId ?? '',
|
||||
title: lineItem.label ?? '',
|
||||
selectedOptions: [],
|
||||
product: {
|
||||
description: lineItem.description ?? '',
|
||||
descriptionHtml: lineItem.description ?? '',
|
||||
id: lineItem.referencedId ?? '',
|
||||
images: [],
|
||||
path: '',
|
||||
seo: {
|
||||
description: lineItem.description ?? '',
|
||||
title: lineItem.label ?? ''
|
||||
},
|
||||
availableForSale: true,
|
||||
featuredImage: (lineItem as any).cover?.url,
|
||||
handle: '',
|
||||
options: [],
|
||||
variants: [],
|
||||
priceRange: {
|
||||
minVariantPrice: {
|
||||
amount: '', // @ToDo: should be correct value
|
||||
currencyCode: 'EUR'
|
||||
},
|
||||
maxVariantPrice: {
|
||||
amount: '', // @ToDo: should be correct value
|
||||
currencyCode: 'EUR'
|
||||
}
|
||||
},
|
||||
tags: [],
|
||||
title: lineItem.label ?? '',
|
||||
updatedAt: (lineItem as any)?.payload?.updatedAt
|
||||
}
|
||||
}
|
||||
})) || [],
|
||||
totalQuantity: cartData.lineItems?.length || 0
|
||||
};
|
||||
return cart;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import {
|
||||
ApiSchemas,
|
||||
Cart,
|
||||
CartItem,
|
||||
CategoryListingResultSW,
|
||||
Collection,
|
||||
Menu,
|
||||
@ -9,8 +11,10 @@ import {
|
||||
ProductVariant
|
||||
} from './types';
|
||||
import {
|
||||
ExtendedCart,
|
||||
ExtendedCategory,
|
||||
ExtendedCmsPage,
|
||||
ExtendedLineItem,
|
||||
ExtendedProduct,
|
||||
ExtendedProductListingResult
|
||||
} from './api-extended';
|
||||
@ -329,3 +333,87 @@ export function transformHandle(handle: string | []): string {
|
||||
|
||||
return collectionName ?? '';
|
||||
}
|
||||
|
||||
export function transformCart(resCart: ExtendedCart): Cart {
|
||||
return {
|
||||
checkoutUrl: 'https://frontends-demo.vercel.app',
|
||||
cost: {
|
||||
subtotalAmount: {
|
||||
amount: resCart.price?.positionPrice?.toString() || '0',
|
||||
currencyCode: 'EUR'
|
||||
},
|
||||
totalAmount: {
|
||||
amount: resCart.price?.totalPrice?.toString() || '0',
|
||||
currencyCode: 'EUR'
|
||||
},
|
||||
totalTaxAmount: {
|
||||
amount: '0',
|
||||
currencyCode: 'EUR'
|
||||
}
|
||||
},
|
||||
id: resCart.token ?? '',
|
||||
lines:
|
||||
resCart.lineItems?.map((lineItem: ExtendedLineItem) => transformLineItem(lineItem)) || [],
|
||||
totalQuantity: resCart.lineItems ? calculateTotalCartQuantity(resCart.lineItems) : 0
|
||||
};
|
||||
}
|
||||
|
||||
function calculateTotalCartQuantity(lineItems: ExtendedLineItem[]) {
|
||||
let totalQuantity = 0;
|
||||
lineItems.forEach((lineItem) => {
|
||||
totalQuantity += lineItem.quantity ?? 0;
|
||||
});
|
||||
|
||||
return totalQuantity;
|
||||
}
|
||||
|
||||
function transformLineItem(resLineItem: ExtendedLineItem): CartItem {
|
||||
return {
|
||||
id: resLineItem.id || '',
|
||||
quantity: resLineItem.quantity ?? 0,
|
||||
cost: {
|
||||
totalAmount: {
|
||||
amount: resLineItem.price?.totalPrice.toString() || '',
|
||||
currencyCode: 'EUR'
|
||||
}
|
||||
},
|
||||
merchandise: {
|
||||
id: resLineItem.referencedId ?? '',
|
||||
title: resLineItem.label ?? '',
|
||||
selectedOptions: [],
|
||||
product: {
|
||||
description: resLineItem.description ?? '',
|
||||
descriptionHtml: resLineItem.description ?? '',
|
||||
id: resLineItem.referencedId ?? '',
|
||||
images: [],
|
||||
path: resLineItem.referencedId ?? '',
|
||||
seo: {
|
||||
description: resLineItem.description ?? '',
|
||||
title: resLineItem.label ?? ''
|
||||
},
|
||||
availableForSale: true,
|
||||
featuredImage: {
|
||||
url: resLineItem.cover?.url ?? '',
|
||||
altText: resLineItem.cover?.translated?.alt ?? resLineItem.cover?.alt ?? '',
|
||||
width: Number(resLineItem.cover?.metaData?.width) ?? 0,
|
||||
height: Number(resLineItem.cover?.metaData?.height) ?? 0
|
||||
},
|
||||
options: [],
|
||||
variants: [],
|
||||
priceRange: {
|
||||
minVariantPrice: {
|
||||
amount: '', // @ToDo: should be correct value
|
||||
currencyCode: 'EUR'
|
||||
},
|
||||
maxVariantPrice: {
|
||||
amount: '', // @ToDo: should be correct value
|
||||
currencyCode: 'EUR'
|
||||
}
|
||||
},
|
||||
tags: [],
|
||||
title: resLineItem.label ?? '',
|
||||
updatedAt: resLineItem.payload?.updatedAt ?? resLineItem.payload?.createdAt ?? ''
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
12
package.json
12
package.json
@ -20,11 +20,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.15",
|
||||
"@shopware/api-client": "0.0.0-canary-20230713092547",
|
||||
"@vercel/og": "^0.5.8",
|
||||
"@shopware/api-client": "0.0.0-canary-20230721083422",
|
||||
"@vercel/og": "^0.5.9",
|
||||
"clsx": "^1.2.1",
|
||||
"is-empty-iterable": "^3.0.0",
|
||||
"next": "13.4.10",
|
||||
"next": "13.4.12",
|
||||
"react": "18.2.0",
|
||||
"react-cookie": "^4.1.1",
|
||||
"react-dom": "18.2.0",
|
||||
@ -33,18 +33,18 @@
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.36.1",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@types/node": "^20.4.2",
|
||||
"@types/node": "^20.4.4",
|
||||
"@types/react": "18.2.15",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@vercel/git-hooks": "^1.0.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.45.0",
|
||||
"eslint-config-next": "^13.4.10",
|
||||
"eslint-config-next": "^13.4.12",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-unicorn": "^48.0.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.2.3",
|
||||
"postcss": "^8.4.26",
|
||||
"postcss": "^8.4.27",
|
||||
"prettier": "^3.0.0",
|
||||
"prettier-plugin-tailwindcss": "^0.4.1",
|
||||
"tailwindcss": "^3.3.3",
|
||||
|
223
pnpm-lock.yaml
generated
223
pnpm-lock.yaml
generated
@ -9,11 +9,11 @@ dependencies:
|
||||
specifier: ^1.7.15
|
||||
version: 1.7.15(react-dom@18.2.0)(react@18.2.0)
|
||||
'@shopware/api-client':
|
||||
specifier: 0.0.0-canary-20230713092547
|
||||
version: 0.0.0-canary-20230713092547
|
||||
specifier: 0.0.0-canary-20230721083422
|
||||
version: 0.0.0-canary-20230721083422
|
||||
'@vercel/og':
|
||||
specifier: ^0.5.8
|
||||
version: 0.5.8
|
||||
specifier: ^0.5.9
|
||||
version: 0.5.9
|
||||
clsx:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
@ -21,8 +21,8 @@ dependencies:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
next:
|
||||
specifier: 13.4.10
|
||||
version: 13.4.10(react-dom@18.2.0)(react@18.2.0)
|
||||
specifier: 13.4.12
|
||||
version: 13.4.12(react-dom@18.2.0)(react@18.2.0)
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
@ -44,8 +44,8 @@ devDependencies:
|
||||
specifier: ^0.5.9
|
||||
version: 0.5.9(tailwindcss@3.3.3)
|
||||
'@types/node':
|
||||
specifier: ^20.4.2
|
||||
version: 20.4.2
|
||||
specifier: ^20.4.4
|
||||
version: 20.4.4
|
||||
'@types/react':
|
||||
specifier: 18.2.15
|
||||
version: 18.2.15
|
||||
@ -57,13 +57,13 @@ devDependencies:
|
||||
version: 1.0.0
|
||||
autoprefixer:
|
||||
specifier: ^10.4.14
|
||||
version: 10.4.14(postcss@8.4.26)
|
||||
version: 10.4.14(postcss@8.4.27)
|
||||
eslint:
|
||||
specifier: ^8.45.0
|
||||
version: 8.45.0
|
||||
eslint-config-next:
|
||||
specifier: ^13.4.10
|
||||
version: 13.4.10(eslint@8.45.0)(typescript@5.1.6)
|
||||
specifier: ^13.4.12
|
||||
version: 13.4.12(eslint@8.45.0)(typescript@5.1.6)
|
||||
eslint-config-prettier:
|
||||
specifier: ^8.8.0
|
||||
version: 8.8.0(eslint@8.45.0)
|
||||
@ -77,8 +77,8 @@ devDependencies:
|
||||
specifier: ^13.2.3
|
||||
version: 13.2.3
|
||||
postcss:
|
||||
specifier: ^8.4.26
|
||||
version: 8.4.26
|
||||
specifier: ^8.4.27
|
||||
version: 8.4.27
|
||||
prettier:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
@ -142,8 +142,8 @@ packages:
|
||||
eslint-visitor-keys: 3.4.1
|
||||
dev: true
|
||||
|
||||
/@eslint-community/regexpp@4.5.1:
|
||||
resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==}
|
||||
/@eslint-community/regexpp@4.6.0:
|
||||
resolution: {integrity: sha512-uiPeRISaglZnaZk8vwrjQZ1CxogZeY/4IYft6gBOTqu1WhVXWmCmZMWxUv2Q/pxSvPdp1JPaO62kLOcOkMqWrw==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
@ -235,18 +235,18 @@ packages:
|
||||
'@jridgewell/sourcemap-codec': 1.4.14
|
||||
dev: true
|
||||
|
||||
/@next/env@13.4.10:
|
||||
resolution: {integrity: sha512-3G1yD/XKTSLdihyDSa8JEsaWOELY+OWe08o0LUYzfuHp1zHDA8SObQlzKt+v+wrkkPcnPweoLH1ImZeUa0A1NQ==}
|
||||
/@next/env@13.4.12:
|
||||
resolution: {integrity: sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ==}
|
||||
dev: false
|
||||
|
||||
/@next/eslint-plugin-next@13.4.10:
|
||||
resolution: {integrity: sha512-YJqyq6vk39JQfvaNtN83t/p5Jy45+bazRL+V4QI8FPd3FBqFYMEsULiwRLgSJMgFqkk4t4JbeZurz+gILEAFpA==}
|
||||
/@next/eslint-plugin-next@13.4.12:
|
||||
resolution: {integrity: sha512-6rhK9CdxEgj/j1qvXIyLTWEaeFv7zOK8yJMulz3Owel0uek0U9MJCGzmKgYxM3aAUBo3gKeywCZKyQnJKto60A==}
|
||||
dependencies:
|
||||
glob: 7.1.7
|
||||
dev: true
|
||||
|
||||
/@next/swc-darwin-arm64@13.4.10:
|
||||
resolution: {integrity: sha512-4bsdfKmmg7mgFGph0UorD1xWfZ5jZEw4kKRHYEeTK9bT1QnMbPVPlVXQRIiFPrhoDQnZUoa6duuPUJIEGLV1Jg==}
|
||||
/@next/swc-darwin-arm64@13.4.12:
|
||||
resolution: {integrity: sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
@ -254,8 +254,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-darwin-x64@13.4.10:
|
||||
resolution: {integrity: sha512-ngXhUBbcZIWZWqNbQSNxQrB9T1V+wgfCzAor2olYuo/YpaL6mUYNUEgeBMhr8qwV0ARSgKaOp35lRvB7EmCRBg==}
|
||||
/@next/swc-darwin-x64@13.4.12:
|
||||
resolution: {integrity: sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
@ -263,8 +263,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-arm64-gnu@13.4.10:
|
||||
resolution: {integrity: sha512-SjCZZCOmHD4uyM75MVArSAmF5Y+IJSGroPRj2v9/jnBT36SYFTORN8Ag/lhw81W9EeexKY/CUg2e9mdebZOwsg==}
|
||||
/@next/swc-linux-arm64-gnu@13.4.12:
|
||||
resolution: {integrity: sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@ -272,8 +272,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-arm64-musl@13.4.10:
|
||||
resolution: {integrity: sha512-F+VlcWijX5qteoYIOxNiBbNE8ruaWuRlcYyIRK10CugqI/BIeCDzEDyrHIHY8AWwbkTwe6GRHabMdE688Rqq4Q==}
|
||||
/@next/swc-linux-arm64-musl@13.4.12:
|
||||
resolution: {integrity: sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@ -281,8 +281,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-x64-gnu@13.4.10:
|
||||
resolution: {integrity: sha512-WDv1YtAV07nhfy3i1visr5p/tjiH6CeXp4wX78lzP1jI07t4PnHHG1WEDFOduXh3WT4hG6yN82EQBQHDi7hBrQ==}
|
||||
/@next/swc-linux-x64-gnu@13.4.12:
|
||||
resolution: {integrity: sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@ -290,8 +290,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-linux-x64-musl@13.4.10:
|
||||
resolution: {integrity: sha512-zFkzqc737xr6qoBgDa3AwC7jPQzGLjDlkNmt/ljvQJ/Veri5ECdHjZCUuiTUfVjshNIIpki6FuP0RaQYK9iCRg==}
|
||||
/@next/swc-linux-x64-musl@13.4.12:
|
||||
resolution: {integrity: sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@ -299,8 +299,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-win32-arm64-msvc@13.4.10:
|
||||
resolution: {integrity: sha512-IboRS8IWz5mWfnjAdCekkl8s0B7ijpWeDwK2O8CdgZkoCDY0ZQHBSGiJ2KViAG6+BJVfLvcP+a2fh6cdyBr9QQ==}
|
||||
/@next/swc-win32-arm64-msvc@13.4.12:
|
||||
resolution: {integrity: sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
@ -308,8 +308,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-win32-ia32-msvc@13.4.10:
|
||||
resolution: {integrity: sha512-bSA+4j8jY4EEiwD/M2bol4uVEu1lBlgsGdvM+mmBm/BbqofNBfaZ2qwSbwE2OwbAmzNdVJRFRXQZ0dkjopTRaQ==}
|
||||
/@next/swc-win32-ia32-msvc@13.4.12:
|
||||
resolution: {integrity: sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
@ -317,8 +317,8 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@next/swc-win32-x64-msvc@13.4.10:
|
||||
resolution: {integrity: sha512-g2+tU63yTWmcVQKDGY0MV1PjjqgZtwM4rB1oVVi/v0brdZAcrcTV+04agKzWtvWroyFz6IqtT0MoZJA7PNyLVw==}
|
||||
/@next/swc-win32-x64-msvc@13.4.12:
|
||||
resolution: {integrity: sha512-Z+56e/Ljt0bUs+T+jPjhFyxYBcdY2RIq9ELFU+qAMQMteHo7ymbV7CKmlcX59RI9C4YzN8PgMgLyAoi916b5HA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@ -352,7 +352,7 @@ packages:
|
||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||
dependencies:
|
||||
cross-spawn: 7.0.3
|
||||
fast-glob: 3.3.0
|
||||
fast-glob: 3.3.1
|
||||
is-glob: 4.0.3
|
||||
open: 9.1.0
|
||||
picocolors: 1.0.0
|
||||
@ -364,7 +364,7 @@ packages:
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/node': 20.4.2
|
||||
'@types/node': 20.4.4
|
||||
playwright-core: 1.36.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
@ -379,8 +379,8 @@ packages:
|
||||
resolution: {integrity: sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==}
|
||||
dev: true
|
||||
|
||||
/@shopware/api-client@0.0.0-canary-20230713092547:
|
||||
resolution: {integrity: sha512-+5dHwprTnpwtHQl3eletxpvMexqKf9N8fIiecqaeemrsWLkiFyAouP76UzYPVjEF54neOOaAI0DuIBvi2w4WXg==}
|
||||
/@shopware/api-client@0.0.0-canary-20230721083422:
|
||||
resolution: {integrity: sha512-5oOFf6SSrxSkksXzFDalp+jwMw5P93KpUNiNzaHyL8XAE/e8B5/DdtXCCMl74sS9fdU3aC5y9mfuyvrPA4t1Zg==}
|
||||
dependencies:
|
||||
ofetch: 1.1.1
|
||||
dev: false
|
||||
@ -427,8 +427,8 @@ packages:
|
||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||
dev: true
|
||||
|
||||
/@types/node@20.4.2:
|
||||
resolution: {integrity: sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==}
|
||||
/@types/node@20.4.4:
|
||||
resolution: {integrity: sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==}
|
||||
dev: true
|
||||
|
||||
/@types/normalize-package-data@2.4.1:
|
||||
@ -521,8 +521,8 @@ packages:
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
/@vercel/og@0.5.8:
|
||||
resolution: {integrity: sha512-WlY5q96e2OmQEUsgqKZrCljNHiD05aErsa7u2z2+pkxyoVSWPHXLYFwHPtp7+IubU4gt4JYfgSbzGQg7n6xeAQ==}
|
||||
/@vercel/og@0.5.9:
|
||||
resolution: {integrity: sha512-CtjaV/BVHtNCjRtxGqn8Q6AKFLqcG34Byxr91+mY+4eqyp/09LVe9jEeY9WXjbaKvu8syWPMteTpY+YQUQYzSg==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@resvg/resvg-wasm': 2.4.1
|
||||
@ -697,7 +697,7 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/autoprefixer@10.4.14(postcss@8.4.26):
|
||||
/autoprefixer@10.4.14(postcss@8.4.27):
|
||||
resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
hasBin: true
|
||||
@ -705,11 +705,11 @@ packages:
|
||||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.21.9
|
||||
caniuse-lite: 1.0.30001516
|
||||
caniuse-lite: 1.0.30001517
|
||||
fraction.js: 4.2.0
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.0
|
||||
postcss: 8.4.26
|
||||
postcss: 8.4.27
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: true
|
||||
|
||||
@ -774,8 +774,8 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001516
|
||||
electron-to-chromium: 1.4.461
|
||||
caniuse-lite: 1.0.30001517
|
||||
electron-to-chromium: 1.4.468
|
||||
node-releases: 2.0.13
|
||||
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
||||
dev: true
|
||||
@ -820,8 +820,8 @@ packages:
|
||||
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
||||
dev: false
|
||||
|
||||
/caniuse-lite@1.0.30001516:
|
||||
resolution: {integrity: sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==}
|
||||
/caniuse-lite@1.0.30001517:
|
||||
resolution: {integrity: sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==}
|
||||
|
||||
/chalk@2.4.2:
|
||||
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||
@ -1095,8 +1095,8 @@ packages:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium@1.4.461:
|
||||
resolution: {integrity: sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ==}
|
||||
/electron-to-chromium@1.4.468:
|
||||
resolution: {integrity: sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex@10.2.1:
|
||||
@ -1151,7 +1151,7 @@ packages:
|
||||
is-regex: 1.1.4
|
||||
is-shared-array-buffer: 1.0.2
|
||||
is-string: 1.0.7
|
||||
is-typed-array: 1.1.10
|
||||
is-typed-array: 1.1.12
|
||||
is-weakref: 1.0.2
|
||||
object-inspect: 1.12.3
|
||||
object-keys: 1.1.1
|
||||
@ -1167,7 +1167,7 @@ packages:
|
||||
typed-array-byte-offset: 1.0.0
|
||||
typed-array-length: 1.0.4
|
||||
unbox-primitive: 1.0.2
|
||||
which-typed-array: 1.1.10
|
||||
which-typed-array: 1.1.11
|
||||
dev: true
|
||||
|
||||
/es-set-tostringtag@2.0.1:
|
||||
@ -1213,8 +1213,8 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/eslint-config-next@13.4.10(eslint@8.45.0)(typescript@5.1.6):
|
||||
resolution: {integrity: sha512-+JjcM6lQmFR5Mw0ORm9o1CR29+z/uajgSfYAPEGIBxOhTHBgCMs7ysuwi72o7LkMmA8E3N7/h09pSGZxs0s85g==}
|
||||
/eslint-config-next@13.4.12(eslint@8.45.0)(typescript@5.1.6):
|
||||
resolution: {integrity: sha512-ZF0r5vxKaVazyZH/37Au/XItiG7qUOBw+HaH3PeyXltIMwXorsn6bdrl0Nn9N5v5v9spc+6GM2ryjugbjF6X2g==}
|
||||
peerDependencies:
|
||||
eslint: ^7.23.0 || ^8.0.0
|
||||
typescript: '>=3.3.1'
|
||||
@ -1222,7 +1222,7 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@next/eslint-plugin-next': 13.4.10
|
||||
'@next/eslint-plugin-next': 13.4.12
|
||||
'@rushstack/eslint-patch': 1.3.2
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@8.45.0)(typescript@5.1.6)
|
||||
eslint: 8.45.0
|
||||
@ -1230,7 +1230,7 @@ packages:
|
||||
eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.45.0)
|
||||
eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.45.0)
|
||||
eslint-plugin-jsx-a11y: 6.7.1(eslint@8.45.0)
|
||||
eslint-plugin-react: 7.32.2(eslint@8.45.0)
|
||||
eslint-plugin-react: 7.33.0(eslint@8.45.0)
|
||||
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.45.0)
|
||||
typescript: 5.1.6
|
||||
transitivePeerDependencies:
|
||||
@ -1378,8 +1378,8 @@ packages:
|
||||
eslint: 8.45.0
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-react@7.32.2(eslint@8.45.0):
|
||||
resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==}
|
||||
/eslint-plugin-react@7.33.0(eslint@8.45.0):
|
||||
resolution: {integrity: sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
|
||||
@ -1445,7 +1445,7 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0)
|
||||
'@eslint-community/regexpp': 4.5.1
|
||||
'@eslint-community/regexpp': 4.6.0
|
||||
'@eslint/eslintrc': 2.1.0
|
||||
'@eslint/js': 8.44.0
|
||||
'@humanwhocodes/config-array': 0.11.10
|
||||
@ -1552,8 +1552,8 @@ packages:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-glob@3.3.0:
|
||||
resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==}
|
||||
/fast-glob@3.3.1:
|
||||
resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@ -1762,7 +1762,7 @@ packages:
|
||||
dependencies:
|
||||
array-union: 2.1.0
|
||||
dir-glob: 3.0.1
|
||||
fast-glob: 3.3.0
|
||||
fast-glob: 3.3.1
|
||||
ignore: 5.2.4
|
||||
merge2: 1.4.1
|
||||
slash: 3.0.0
|
||||
@ -1773,7 +1773,7 @@ packages:
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dependencies:
|
||||
dir-glob: 3.0.1
|
||||
fast-glob: 3.3.0
|
||||
fast-glob: 3.3.1
|
||||
ignore: 5.2.4
|
||||
merge2: 1.4.1
|
||||
slash: 4.0.0
|
||||
@ -1915,7 +1915,7 @@ packages:
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.2.1
|
||||
is-typed-array: 1.1.10
|
||||
is-typed-array: 1.1.12
|
||||
dev: true
|
||||
|
||||
/is-arrayish@0.2.1:
|
||||
@ -2075,15 +2075,11 @@ packages:
|
||||
has-symbols: 1.0.3
|
||||
dev: true
|
||||
|
||||
/is-typed-array@1.1.10:
|
||||
resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
|
||||
/is-typed-array@1.1.12:
|
||||
resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.5
|
||||
call-bind: 1.0.2
|
||||
for-each: 0.3.3
|
||||
gopd: 1.0.1
|
||||
has-tostringtag: 1.0.0
|
||||
which-typed-array: 1.1.11
|
||||
dev: true
|
||||
|
||||
/is-weakref@1.0.2:
|
||||
@ -2358,8 +2354,8 @@ packages:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
dev: true
|
||||
|
||||
/next@13.4.10(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-4ep6aKxVTQ7rkUW2fBLhpBr/5oceCuf4KmlUpvG/aXuDTIf9mexNSpabUD6RWPspu6wiJJvozZREhXhueYO36A==}
|
||||
/next@13.4.12(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==}
|
||||
engines: {node: '>=16.8.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -2376,10 +2372,10 @@ packages:
|
||||
sass:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@next/env': 13.4.10
|
||||
'@next/env': 13.4.12
|
||||
'@swc/helpers': 0.5.1
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001516
|
||||
caniuse-lite: 1.0.30001517
|
||||
postcss: 8.4.14
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
@ -2387,15 +2383,15 @@ packages:
|
||||
watchpack: 2.4.0
|
||||
zod: 3.21.4
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 13.4.10
|
||||
'@next/swc-darwin-x64': 13.4.10
|
||||
'@next/swc-linux-arm64-gnu': 13.4.10
|
||||
'@next/swc-linux-arm64-musl': 13.4.10
|
||||
'@next/swc-linux-x64-gnu': 13.4.10
|
||||
'@next/swc-linux-x64-musl': 13.4.10
|
||||
'@next/swc-win32-arm64-msvc': 13.4.10
|
||||
'@next/swc-win32-ia32-msvc': 13.4.10
|
||||
'@next/swc-win32-x64-msvc': 13.4.10
|
||||
'@next/swc-darwin-arm64': 13.4.12
|
||||
'@next/swc-darwin-x64': 13.4.12
|
||||
'@next/swc-linux-arm64-gnu': 13.4.12
|
||||
'@next/swc-linux-arm64-musl': 13.4.12
|
||||
'@next/swc-linux-x64-gnu': 13.4.12
|
||||
'@next/swc-linux-x64-musl': 13.4.12
|
||||
'@next/swc-win32-arm64-msvc': 13.4.12
|
||||
'@next/swc-win32-ia32-msvc': 13.4.12
|
||||
'@next/swc-win32-x64-msvc': 13.4.12
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
@ -2686,29 +2682,29 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/postcss-import@15.1.0(postcss@8.4.26):
|
||||
/postcss-import@15.1.0(postcss@8.4.27):
|
||||
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.0.0
|
||||
dependencies:
|
||||
postcss: 8.4.26
|
||||
postcss: 8.4.27
|
||||
postcss-value-parser: 4.2.0
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.2
|
||||
dev: true
|
||||
|
||||
/postcss-js@4.0.1(postcss@8.4.26):
|
||||
/postcss-js@4.0.1(postcss@8.4.27):
|
||||
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
|
||||
engines: {node: ^12 || ^14 || >= 16}
|
||||
peerDependencies:
|
||||
postcss: ^8.4.21
|
||||
dependencies:
|
||||
camelcase-css: 2.0.1
|
||||
postcss: 8.4.26
|
||||
postcss: 8.4.27
|
||||
dev: true
|
||||
|
||||
/postcss-load-config@4.0.1(postcss@8.4.26):
|
||||
/postcss-load-config@4.0.1(postcss@8.4.27):
|
||||
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
|
||||
engines: {node: '>= 14'}
|
||||
peerDependencies:
|
||||
@ -2721,17 +2717,17 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
lilconfig: 2.1.0
|
||||
postcss: 8.4.26
|
||||
postcss: 8.4.27
|
||||
yaml: 2.3.1
|
||||
dev: true
|
||||
|
||||
/postcss-nested@6.0.1(postcss@8.4.26):
|
||||
/postcss-nested@6.0.1(postcss@8.4.27):
|
||||
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
|
||||
engines: {node: '>=12.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.2.14
|
||||
dependencies:
|
||||
postcss: 8.4.26
|
||||
postcss: 8.4.27
|
||||
postcss-selector-parser: 6.0.13
|
||||
dev: true
|
||||
|
||||
@ -2763,8 +2759,8 @@ packages:
|
||||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/postcss@8.4.26:
|
||||
resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==}
|
||||
/postcss@8.4.27:
|
||||
resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
dependencies:
|
||||
nanoid: 3.3.6
|
||||
@ -3293,8 +3289,8 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/sucrase@3.33.0:
|
||||
resolution: {integrity: sha512-ARGC7vbufOHfpvyGcZZXFaXCMZ9A4fffOGC5ucOW7+WHDGlAe8LJdf3Jts1sWhDeiI1RSWrKy5Hodl+JWGdW2A==}
|
||||
/sucrase@3.34.0:
|
||||
resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@ -3344,7 +3340,7 @@ packages:
|
||||
chokidar: 3.5.3
|
||||
didyoumean: 1.2.2
|
||||
dlv: 1.1.3
|
||||
fast-glob: 3.3.0
|
||||
fast-glob: 3.3.1
|
||||
glob-parent: 6.0.2
|
||||
is-glob: 4.0.3
|
||||
jiti: 1.19.1
|
||||
@ -3353,14 +3349,14 @@ packages:
|
||||
normalize-path: 3.0.0
|
||||
object-hash: 3.0.0
|
||||
picocolors: 1.0.0
|
||||
postcss: 8.4.26
|
||||
postcss-import: 15.1.0(postcss@8.4.26)
|
||||
postcss-js: 4.0.1(postcss@8.4.26)
|
||||
postcss-load-config: 4.0.1(postcss@8.4.26)
|
||||
postcss-nested: 6.0.1(postcss@8.4.26)
|
||||
postcss: 8.4.27
|
||||
postcss-import: 15.1.0(postcss@8.4.27)
|
||||
postcss-js: 4.0.1(postcss@8.4.27)
|
||||
postcss-load-config: 4.0.1(postcss@8.4.27)
|
||||
postcss-nested: 6.0.1(postcss@8.4.27)
|
||||
postcss-selector-parser: 6.0.13
|
||||
resolve: 1.22.2
|
||||
sucrase: 3.33.0
|
||||
sucrase: 3.34.0
|
||||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
dev: true
|
||||
@ -3470,7 +3466,7 @@ packages:
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.2.1
|
||||
is-typed-array: 1.1.10
|
||||
is-typed-array: 1.1.12
|
||||
dev: true
|
||||
|
||||
/typed-array-byte-length@1.0.0:
|
||||
@ -3480,7 +3476,7 @@ packages:
|
||||
call-bind: 1.0.2
|
||||
for-each: 0.3.3
|
||||
has-proto: 1.0.1
|
||||
is-typed-array: 1.1.10
|
||||
is-typed-array: 1.1.12
|
||||
dev: true
|
||||
|
||||
/typed-array-byte-offset@1.0.0:
|
||||
@ -3491,7 +3487,7 @@ packages:
|
||||
call-bind: 1.0.2
|
||||
for-each: 0.3.3
|
||||
has-proto: 1.0.1
|
||||
is-typed-array: 1.1.10
|
||||
is-typed-array: 1.1.12
|
||||
dev: true
|
||||
|
||||
/typed-array-length@1.0.4:
|
||||
@ -3499,7 +3495,7 @@ packages:
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
for-each: 0.3.3
|
||||
is-typed-array: 1.1.10
|
||||
is-typed-array: 1.1.12
|
||||
dev: true
|
||||
|
||||
/typescript@5.1.6:
|
||||
@ -3586,8 +3582,8 @@ packages:
|
||||
is-symbol: 1.0.4
|
||||
dev: true
|
||||
|
||||
/which-typed-array@1.1.10:
|
||||
resolution: {integrity: sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==}
|
||||
/which-typed-array@1.1.11:
|
||||
resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.5
|
||||
@ -3595,7 +3591,6 @@ packages:
|
||||
for-each: 0.3.3
|
||||
gopd: 1.0.1
|
||||
has-tostringtag: 1.0.0
|
||||
is-typed-array: 1.1.10
|
||||
dev: true
|
||||
|
||||
/which@2.0.2:
|
||||
|
Loading…
x
Reference in New Issue
Block a user