diff --git a/app/error.tsx b/app/error.tsx index 3e2b40b1a..e0a7416a3 100644 --- a/app/error.tsx +++ b/app/error.tsx @@ -2,9 +2,18 @@ export default function Error({ reset }: { reset: () => void }) { return ( -
-

Something went wrong.

- +
+

Oh no!

+

+ There was an issue with our storefront. This could be a temporary issue, please try your + action again. +

+
); } diff --git a/app/layout.tsx b/app/layout.tsx index 49d2d62f0..7256fb488 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -4,10 +4,14 @@ import { ReactNode, Suspense } from 'react'; import './globals.css'; const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env; +const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` + : 'http://localhost:3000'; export const metadata = { + metadataBase: new URL(baseUrl), title: { - default: SITE_NAME || 'Shopware Composable Frontends', + default: SITE_NAME!, template: `%s | ${SITE_NAME}` }, robots: { diff --git a/components/cart/actions.ts b/components/cart/actions.ts index 384c0a623..5165f69ad 100644 --- a/components/cart/actions.ts +++ b/components/cart/actions.ts @@ -2,7 +2,7 @@ import { ApiClientError } from '@shopware/api-client'; import { getApiClient } from 'lib/shopware/api'; -import { ExtendedCart, ExtendedLineItem } from 'lib/shopware/api-extended'; +import { ExtendedCart, ExtendedLineItem, messageKeys } from 'lib/shopware/api-extended'; import { cookies } from 'next/headers'; export const fetchCart = async function (cartId?: string): Promise { @@ -38,7 +38,7 @@ export const addItem = async (variantId: string | undefined): Promise => const cartId = cookies().get('sw-context-token')?.value; if (!cartId) { - return new Error('Missing cartId'); + return { message: 'Missing cart ID' } as Error; } try { @@ -126,7 +126,7 @@ export const updateItemQuantity = async ({ const cartId = cookies().get('sw-context-token')?.value; if (!cartId) { - return new Error('Missing cartId'); + return { message: 'Missing cart ID' } as Error; } try { diff --git a/components/cart/add-to-cart.tsx b/components/cart/add-to-cart.tsx index 368d5521e..6849c3bf3 100644 --- a/components/cart/add-to-cart.tsx +++ b/components/cart/add-to-cart.tsx @@ -46,8 +46,10 @@ export function AddToCart({ const error = await addItem(selectedVariantId); if (error) { - alert(error.message); - return; + alert(error.message); // this is not a real error, this can be also out of stock message for the user + + // Example to trigger the error boundary in the root error.js + // throw new Error(error.toString()); } router.refresh(); diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx index 9b4bdd129..01e664804 100644 --- a/components/cart/delete-item-button.tsx +++ b/components/cart/delete-item-button.tsx @@ -19,8 +19,8 @@ export default function DeleteItemButton({ item }: { item: CartItem }) { const error = await removeItem(item.id); if (error) { - alert(error); - return; + // Trigger the error boundary in the root error.js + throw new Error(error.toString()); } router.refresh(); diff --git a/components/cart/edit-item-quantity-button.tsx b/components/cart/edit-item-quantity-button.tsx index 560f09db4..3eb2b8f89 100644 --- a/components/cart/edit-item-quantity-button.tsx +++ b/components/cart/edit-item-quantity-button.tsx @@ -32,8 +32,8 @@ export default function EditItemQuantityButton({ }); if (error) { - alert(error); - return; + // Trigger the error boundary in the root error.js + throw new Error(error.toString()); } router.refresh(); diff --git a/components/label.tsx b/components/label.tsx index e49efce40..113afacb0 100644 --- a/components/label.tsx +++ b/components/label.tsx @@ -18,8 +18,8 @@ const Label = ({ 'lg:px-20 lg:pb-[35%]': position === 'center' })} > -
-

{title}

+
+

{title}

diff --git a/lib/shopware/api-extended.ts b/lib/shopware/api-extended.ts index 87db588fa..97a2294d6 100644 --- a/lib/shopware/api-extended.ts +++ b/lib/shopware/api-extended.ts @@ -1,6 +1,7 @@ import { operations, operationPaths, components } from '@shopware/api-client/api-types'; type schemas = components['schemas']; + type operationsWithoutOriginal = Omit< operations, | 'readCategory' @@ -14,6 +15,7 @@ type operationsWithoutOriginal = Omit< | 'readCart' | 'deleteLineItem' >; + export type extendedPaths = | 'readCategory post /category/{navigationId}?slots' | 'readCategoryList post /category' @@ -26,6 +28,7 @@ export type extendedPaths = | 'readCart get /checkout/cart?name' | 'deleteLineItem delete /checkout/cart/line-item?id[]={ids}' | operationPaths; + export type extendedOperations = operationsWithoutOriginal & { readCategory: extendedReadCategory; readCategoryList: extendedReadCategoryList; @@ -39,8 +42,21 @@ export type extendedOperations = operationsWithoutOriginal & { deleteLineItem: extendedDeleteLineItem; }; -export type ExtendedCart = Omit & { +export type messageKeys = + | 'purchase-steps-quantity' + | 'product-stock-reached' + | 'product-out-of-stock' + | 'product-not-found' + | 'min-order-quantity'; + +export type ExtendedCart = Omit & { lineItems?: ExtendedLineItem[]; + errors?: { + key?: string; + level?: string; + message?: string; + messageKey?: string; + }[]; }; export type ExtendedLineItem = schemas['LineItem'] & { diff --git a/package.json b/package.json index 4e01ca692..b251475a4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@heroicons/react": "^2.0.18", "@shopware/api-client": "0.0.0-canary-20230801081457", "clsx": "^2.0.0", - "next": "13.4.12", + "next": "13.4.13-canary.15", "react": "18.2.0", "react-dom": "18.2.0", "react-paginate": "^8.2.0" @@ -43,7 +43,7 @@ "husky": "^8.0.3", "lint-staged": "^13.2.3", "postcss": "^8.4.27", - "prettier": "^3.0.0", + "prettier": "3.0.1", "prettier-plugin-tailwindcss": "^0.4.1", "tailwindcss": "^3.3.3", "typescript": "5.1.6" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e4145df2..e90bde79c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ dependencies: specifier: ^2.0.0 version: 2.0.0 next: - specifier: 13.4.12 - version: 13.4.12(react-dom@18.2.0)(react@18.2.0) + specifier: 13.4.13-canary.15 + version: 13.4.13-canary.15(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -74,11 +74,11 @@ devDependencies: specifier: ^8.4.27 version: 8.4.27 prettier: - specifier: ^3.0.0 - version: 3.0.0 + specifier: 3.0.1 + version: 3.0.1 prettier-plugin-tailwindcss: specifier: ^0.4.1 - version: 0.4.1(prettier@3.0.0) + version: 0.4.1(prettier@3.0.1) tailwindcss: specifier: ^3.3.3 version: 3.3.3 @@ -237,8 +237,8 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@next/env@13.4.12: - resolution: {integrity: sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ==} + /@next/env@13.4.13-canary.15: + resolution: {integrity: sha512-AljMmO5a2uB0ZTDcBVhcfkE7WtdQDfnPg2zz/e6jKjVMRFPSvxaoRoSGUwONIhk9CAPbX9px7bZYom2wbhrTkw==} dev: false /@next/eslint-plugin-next@13.4.12: @@ -247,8 +247,8 @@ packages: glob: 7.1.7 dev: true - /@next/swc-darwin-arm64@13.4.12: - resolution: {integrity: sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==} + /@next/swc-darwin-arm64@13.4.13-canary.15: + resolution: {integrity: sha512-ymE/tPjf5DXIqWxEefkqGX094ZDpKw/0sKb7xmzF0m8Kolac1eqA6ZnCsb1TKXYVQyrGUx/Z0xmxCK4cm2dEdw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -256,8 +256,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@13.4.12: - resolution: {integrity: sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==} + /@next/swc-darwin-x64@13.4.13-canary.15: + resolution: {integrity: sha512-B9fCPRjE1t5r1bmivq5fqHvU8mLNX7hkS2zj9arVrZEC7HdOugbSOpmQb5+yr5ZmNKMItQbPDJIATY+ZAiUtww==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -265,8 +265,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@13.4.12: - resolution: {integrity: sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==} + /@next/swc-linux-arm64-gnu@13.4.13-canary.15: + resolution: {integrity: sha512-K30IPFxZPtZLs1gqir95oNdCNgmu0awbC7MMLqOu9+wmW+LYjA6M3ltRe2Duy9nZ7JQob1oRl/s7MMbtCuzVAA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -274,8 +274,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@13.4.12: - resolution: {integrity: sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==} + /@next/swc-linux-arm64-musl@13.4.13-canary.15: + resolution: {integrity: sha512-ClJvWIhvCLXM3iSMet9bqKxyxifN7DGo8+wiV8gwIU+OMWHGNgGtmZ3xXae3R91w8DOLrsREyBN4uGLlgpwRXg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -283,8 +283,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@13.4.12: - resolution: {integrity: sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==} + /@next/swc-linux-x64-gnu@13.4.13-canary.15: + resolution: {integrity: sha512-/B0xaPcdx2HWDC9Bxks3dLIUyu9Falmd7ENRanYizfdihgM+kV2zIQe/5h5zaESKMEltLt2ELPOPCaFU5gOnYA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -292,8 +292,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@13.4.12: - resolution: {integrity: sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==} + /@next/swc-linux-x64-musl@13.4.13-canary.15: + resolution: {integrity: sha512-YZZlKne+5iwsPe9yN8QP5sfyDN7ybpWTuYukfv6sKL68STuAVqqp4QX2g7a3Fw+LMJiDwyCFJaUDgO9KSLEqDw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -301,8 +301,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@13.4.12: - resolution: {integrity: sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==} + /@next/swc-win32-arm64-msvc@13.4.13-canary.15: + resolution: {integrity: sha512-nOi9w+E+ajqJuQhcB260AMJERJPYS1K5pL+5Rymyt9VWCZEJZiHTRuaf8y/H7sObZcQKwRVa7C/EWyZjj658XA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -310,8 +310,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@13.4.12: - resolution: {integrity: sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==} + /@next/swc-win32-ia32-msvc@13.4.13-canary.15: + resolution: {integrity: sha512-EqV5Bt7TmdFWa00KkoEeb5K4uRFrV1BAiwqylsk+d+2U1N2UIad/dTOyTzobjDcZ9uii1EaCVMiTuMfcsGIahw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -319,8 +319,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@13.4.12: - resolution: {integrity: sha512-Z+56e/Ljt0bUs+T+jPjhFyxYBcdY2RIq9ELFU+qAMQMteHo7ymbV7CKmlcX59RI9C4YzN8PgMgLyAoi916b5HA==} + /@next/swc-win32-x64-msvc@13.4.13-canary.15: + resolution: {integrity: sha512-hZcZ0vS1eevRTr1JUyDfTYXF36DBEowNZWyzNW8ZrlGMZyQloE9yf/jHoLtutxr2jV6GoHWGGqVSw4exOyjjKw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2268,25 +2268,22 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /next@13.4.12(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==} + /next@13.4.13-canary.15(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-dSOzenhqdjH6fNbSKYZ4PkqmKLOviFSVUd75Csz+zZPoTWmAKR+9waUAttOyRnUgYd/qutt8KXGH+DiU0nmhVA==} engines: {node: '>=16.8.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 - fibers: '>= 3.1.0' react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true - fibers: - optional: true sass: optional: true dependencies: - '@next/env': 13.4.12 + '@next/env': 13.4.13-canary.15 '@swc/helpers': 0.5.1 busboy: 1.6.0 caniuse-lite: 1.0.30001519 @@ -2297,15 +2294,15 @@ packages: watchpack: 2.4.0 zod: 3.21.4 optionalDependencies: - '@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 + '@next/swc-darwin-arm64': 13.4.13-canary.15 + '@next/swc-darwin-x64': 13.4.13-canary.15 + '@next/swc-linux-arm64-gnu': 13.4.13-canary.15 + '@next/swc-linux-arm64-musl': 13.4.13-canary.15 + '@next/swc-linux-x64-gnu': 13.4.13-canary.15 + '@next/swc-linux-x64-musl': 13.4.13-canary.15 + '@next/swc-win32-arm64-msvc': 13.4.13-canary.15 + '@next/swc-win32-ia32-msvc': 13.4.13-canary.15 + '@next/swc-win32-x64-msvc': 13.4.13-canary.15 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -2680,7 +2677,7 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /prettier-plugin-tailwindcss@0.4.1(prettier@3.0.0): + /prettier-plugin-tailwindcss@0.4.1(prettier@3.0.1): resolution: {integrity: sha512-hwn2EiJmv8M+AW4YDkbjJ6HlZCTzLyz1QlySn9sMuKV/Px0fjwldlB7tol8GzdgqtkdPtzT3iJ4UzdnYXP25Ag==} engines: {node: '>=12.17.0'} peerDependencies: @@ -2732,11 +2729,11 @@ packages: prettier-plugin-twig-melody: optional: true dependencies: - prettier: 3.0.0 + prettier: 3.0.1 dev: true - /prettier@3.0.0: - resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} + /prettier@3.0.1: + resolution: {integrity: sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==} engines: {node: '>=14'} hasBin: true dev: true