From ef81a968af977ec2b32698f86bfc513a8862c617 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 20 Oct 2020 13:49:17 -0500 Subject: [PATCH 01/17] Fix potential body bug --- lib/bigcommerce/api/cart/index.ts | 6 +++--- lib/bigcommerce/api/customers/index.ts | 2 +- lib/bigcommerce/api/wishlist/index.ts | 11 +++++++---- lib/commerce/api/index.ts | 6 +----- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/bigcommerce/api/cart/index.ts b/lib/bigcommerce/api/cart/index.ts index f2f174b84..4f6062674 100644 --- a/lib/bigcommerce/api/cart/index.ts +++ b/lib/bigcommerce/api/cart/index.ts @@ -80,19 +80,19 @@ const cartApi: BigcommerceApiHandler = async ( // Create or add an item to the cart if (req.method === 'POST') { - const body = { cartId, ...req.body } + const body = { ...req.body, cartId } return await handlers['addItem']({ req, res, config, body }) } // Update item in cart if (req.method === 'PUT') { - const body = { cartId, ...req.body } + const body = { ...req.body, cartId } return await handlers['updateItem']({ req, res, config, body }) } // Remove an item from the cart if (req.method === 'DELETE') { - const body = { cartId, ...req.body } + const body = { ...req.body, cartId } return await handlers['removeItem']({ req, res, config, body }) } } catch (error) { diff --git a/lib/bigcommerce/api/customers/index.ts b/lib/bigcommerce/api/customers/index.ts index c39f55f6a..a626ef2c7 100644 --- a/lib/bigcommerce/api/customers/index.ts +++ b/lib/bigcommerce/api/customers/index.ts @@ -38,7 +38,7 @@ const customersApi: BigcommerceApiHandler = async ( try { if (req.method === 'POST') { - const body = { cartId, ...req.body } + const body = { ...req.body, cartId } return await handlers['createCustomer']({ req, res, config, body }) } } catch (error) { diff --git a/lib/bigcommerce/api/wishlist/index.ts b/lib/bigcommerce/api/wishlist/index.ts index 912d59491..7ab8c9173 100644 --- a/lib/bigcommerce/api/wishlist/index.ts +++ b/lib/bigcommerce/api/wishlist/index.ts @@ -47,7 +47,7 @@ export type Wishlist = { export type WishlistList = Wishlist[] export type WishlistHandlers = { - getAllWishlists: BigcommerceHandler + getAllWishlists: BigcommerceHandler getWishlist: BigcommerceHandler addWishlist: BigcommerceHandler< Wishlist, @@ -57,7 +57,10 @@ export type WishlistHandlers = { Wishlist, { wishlistId: string } & Body > - addItem: BigcommerceHandler> + addItem: BigcommerceHandler< + Wishlist, + { wishlistId: string } & Body + > removeItem: BigcommerceHandler< Wishlist, { wishlistId: string } & Body @@ -86,13 +89,13 @@ const wishlistApi: BigcommerceApiHandler = async ( // Add an item to the wishlist if (req.method === 'POST' && wishlistId) { - const body = { wishlistId, ...req.body } + const body = { ...req.body, wishlistId } return await handlers['addItem']({ req, res, config, body }) } // Update a wishlist if (req.method === 'PUT' && wishlistId) { - const body = { wishlistId, ...req.body } + const body = { ...req.body, wishlistId } return await handlers['updateWishlist']({ req, res, config, body }) } diff --git a/lib/commerce/api/index.ts b/lib/commerce/api/index.ts index 6c4bf0544..38ed70d4a 100644 --- a/lib/commerce/api/index.ts +++ b/lib/commerce/api/index.ts @@ -14,8 +14,4 @@ export interface CommerceAPIFetchOptions { preview?: boolean } -// TODO: define interfaces for all the available operations - -// export interface CommerceAPI { -// getAllProducts(options?: { query: string }): Promise; -// } +// TODO: define interfaces for all the available operations and API endpoints From e2b26715b9b8309a5012a92efda4f966d1434504 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 20 Oct 2020 13:49:37 -0500 Subject: [PATCH 02/17] use-signup --- lib/bigcommerce/use-signup.tsx | 52 +++++++++++++++++++++++++++++++ lib/commerce/use-signup.tsx | 5 +++ lib/commerce/utils/use-action.tsx | 4 +-- 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 lib/bigcommerce/use-signup.tsx create mode 100644 lib/commerce/use-signup.tsx diff --git a/lib/bigcommerce/use-signup.tsx b/lib/bigcommerce/use-signup.tsx new file mode 100644 index 000000000..699f0d9b1 --- /dev/null +++ b/lib/bigcommerce/use-signup.tsx @@ -0,0 +1,52 @@ +import { useCallback } from 'react' +import { HookFetcher } from '@lib/commerce/utils/types' +import useCommerceSignup from '@lib/commerce/use-signup' +import type { CreateCustomerBody } from './api/customers' + +const defaultOpts = { + url: '/api/bigcommerce/customers', + method: 'POST', +} + +export type SignupInput = CreateCustomerBody + +export const fetcher: HookFetcher = ( + options, + { firstName, lastName, email, password }, + fetch +) => { + if (!(firstName && lastName && email && password)) { + throw new Error( + 'A first name, last name, email and password are required to signup' + ) + } + + return fetch({ + url: options?.url ?? defaultOpts.url, + method: options?.method ?? defaultOpts.method, + body: { firstName, lastName, email, password }, + }) +} + +export function extendHook(customFetcher: typeof fetcher) { + const useSignup = () => { + const fn = useCommerceSignup( + defaultOpts, + customFetcher + ) + + return useCallback( + async function signup(input: SignupInput) { + const data = await fn(input) + return data + }, + [fn] + ) + } + + useSignup.extend = extendHook + + return useSignup +} + +export default extendHook(fetcher) diff --git a/lib/commerce/use-signup.tsx b/lib/commerce/use-signup.tsx new file mode 100644 index 000000000..08ddb22c0 --- /dev/null +++ b/lib/commerce/use-signup.tsx @@ -0,0 +1,5 @@ +import useAction from './utils/use-action' + +const useSignup = useAction + +export default useSignup diff --git a/lib/commerce/utils/use-action.tsx b/lib/commerce/utils/use-action.tsx index ef68a7641..e60cae06b 100644 --- a/lib/commerce/utils/use-action.tsx +++ b/lib/commerce/utils/use-action.tsx @@ -9,9 +9,7 @@ export default function useAction( const { fetcherRef } = useCommerce() return useCallback( - function addItem(input: Input) { - return fetcher(options, input, fetcherRef.current) - }, + (input: Input) => fetcher(options, input, fetcherRef.current), [fetcher] ) } From a1e47a73d2ea0e305fb6c04cd6d6855027ab1e95 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 20 Oct 2020 22:27:38 -0500 Subject: [PATCH 03/17] Added useLogin hook and API endpoint --- .../api/customers/handlers/create-customer.ts | 1 + .../api/customers/handlers/login.ts | 26 ++++++++++ lib/bigcommerce/api/customers/login.ts | 45 +++++++++++++++++ .../api/utils/create-api-handler.ts | 2 +- lib/bigcommerce/use-login.tsx | 49 +++++++++++++++++++ lib/bigcommerce/use-signup.tsx | 7 +-- lib/commerce/use-login.tsx | 5 ++ .../{customers.ts => customers/index.ts} | 0 pages/api/bigcommerce/customers/login.ts | 3 ++ 9 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 lib/bigcommerce/api/customers/handlers/login.ts create mode 100644 lib/bigcommerce/api/customers/login.ts create mode 100644 lib/bigcommerce/use-login.tsx create mode 100644 lib/commerce/use-login.tsx rename pages/api/bigcommerce/{customers.ts => customers/index.ts} (100%) create mode 100644 pages/api/bigcommerce/customers/login.ts diff --git a/lib/bigcommerce/api/customers/handlers/create-customer.ts b/lib/bigcommerce/api/customers/handlers/create-customer.ts index a666467ab..4ccbf31b4 100644 --- a/lib/bigcommerce/api/customers/handlers/create-customer.ts +++ b/lib/bigcommerce/api/customers/handlers/create-customer.ts @@ -57,6 +57,7 @@ const createCustomer: CustomersHandlers['createCustomer'] = async ({ console.log('DATA', result.data) + // TODO: Currently not working, fix this asap. const loginData = await login({ variables: { email, password }, config }) console.log('LOGIN DATA', loginData) diff --git a/lib/bigcommerce/api/customers/handlers/login.ts b/lib/bigcommerce/api/customers/handlers/login.ts new file mode 100644 index 000000000..787c055f8 --- /dev/null +++ b/lib/bigcommerce/api/customers/handlers/login.ts @@ -0,0 +1,26 @@ +import login from '../../operations/login' +import type { LoginHandlers } from '../login' + +const loginHandler: LoginHandlers['login'] = async ({ + res, + body: { email, password }, + config, +}) => { + // TODO: Add proper validations with something like Ajv + if (!(email && password)) { + return res.status(400).json({ + data: null, + errors: [{ message: 'Invalid request' }], + }) + } + // TODO: validate the password and email + // Passwords must be at least 7 characters and contain both alphabetic + // and numeric characters. + + // TODO: Currently not working, fix this asap. + const loginData = await login({ variables: { email, password }, config }) + + res.status(200).json({ data: null }) +} + +export default loginHandler diff --git a/lib/bigcommerce/api/customers/login.ts b/lib/bigcommerce/api/customers/login.ts new file mode 100644 index 000000000..e8f24a92d --- /dev/null +++ b/lib/bigcommerce/api/customers/login.ts @@ -0,0 +1,45 @@ +import createApiHandler, { + BigcommerceApiHandler, + BigcommerceHandler, +} from '../utils/create-api-handler' +import isAllowedMethod from '../utils/is-allowed-method' +import { BigcommerceApiError } from '../utils/errors' +import login from './handlers/login' + +export type LoginBody = { + email: string + password: string +} + +export type LoginHandlers = { + login: BigcommerceHandler> +} + +const METHODS = ['POST'] + +const loginApi: BigcommerceApiHandler = async ( + req, + res, + config, + handlers +) => { + if (!isAllowedMethod(req, res, METHODS)) return + + try { + const body = req.body ?? {} + return await handlers['login']({ req, res, config, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof BigcommerceApiError + ? 'An unexpected error ocurred with the Bigcommerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +const handlers = { login } + +export default createApiHandler(loginApi, handlers, {}) diff --git a/lib/bigcommerce/api/utils/create-api-handler.ts b/lib/bigcommerce/api/utils/create-api-handler.ts index c6363cb15..be623d4cd 100644 --- a/lib/bigcommerce/api/utils/create-api-handler.ts +++ b/lib/bigcommerce/api/utils/create-api-handler.ts @@ -3,7 +3,7 @@ import { BigcommerceConfig, getConfig } from '..' export type BigcommerceApiHandler< T = any, - H extends BigcommerceHandlers = {}, + H extends BigcommerceHandlers = {}, Options extends {} = {} > = ( req: NextApiRequest, diff --git a/lib/bigcommerce/use-login.tsx b/lib/bigcommerce/use-login.tsx new file mode 100644 index 000000000..37d59a79c --- /dev/null +++ b/lib/bigcommerce/use-login.tsx @@ -0,0 +1,49 @@ +import { useCallback } from 'react' +import { HookFetcher } from '@lib/commerce/utils/types' +import useCommerceLogin from '@lib/commerce/use-login' +import type { LoginBody } from './api/customers/login' + +const defaultOpts = { + url: '/api/bigcommerce/customers/login', + method: 'POST', +} + +export type LoginInput = LoginBody + +export const fetcher: HookFetcher = ( + options, + { email, password }, + fetch +) => { + if (!(email && password)) { + throw new Error( + 'A first name, last name, email and password are required to login' + ) + } + + return fetch({ + url: options?.url ?? defaultOpts.url, + method: options?.method ?? defaultOpts.method, + body: { email, password }, + }) +} + +export function extendHook(customFetcher: typeof fetcher) { + const useLogin = () => { + const fn = useCommerceLogin(defaultOpts, customFetcher) + + return useCallback( + async function login(input: LoginInput) { + const data = await fn(input) + return data + }, + [fn] + ) + } + + useLogin.extend = extendHook + + return useLogin +} + +export default extendHook(fetcher) diff --git a/lib/bigcommerce/use-signup.tsx b/lib/bigcommerce/use-signup.tsx index 699f0d9b1..5f7338d6e 100644 --- a/lib/bigcommerce/use-signup.tsx +++ b/lib/bigcommerce/use-signup.tsx @@ -10,7 +10,7 @@ const defaultOpts = { export type SignupInput = CreateCustomerBody -export const fetcher: HookFetcher = ( +export const fetcher: HookFetcher = ( options, { firstName, lastName, email, password }, fetch @@ -30,10 +30,7 @@ export const fetcher: HookFetcher = ( export function extendHook(customFetcher: typeof fetcher) { const useSignup = () => { - const fn = useCommerceSignup( - defaultOpts, - customFetcher - ) + const fn = useCommerceSignup(defaultOpts, customFetcher) return useCallback( async function signup(input: SignupInput) { diff --git a/lib/commerce/use-login.tsx b/lib/commerce/use-login.tsx new file mode 100644 index 000000000..2a251fea3 --- /dev/null +++ b/lib/commerce/use-login.tsx @@ -0,0 +1,5 @@ +import useAction from './utils/use-action' + +const useLogin = useAction + +export default useLogin diff --git a/pages/api/bigcommerce/customers.ts b/pages/api/bigcommerce/customers/index.ts similarity index 100% rename from pages/api/bigcommerce/customers.ts rename to pages/api/bigcommerce/customers/index.ts diff --git a/pages/api/bigcommerce/customers/login.ts b/pages/api/bigcommerce/customers/login.ts new file mode 100644 index 000000000..b64b2252a --- /dev/null +++ b/pages/api/bigcommerce/customers/login.ts @@ -0,0 +1,3 @@ +import loginApi from '@lib/bigcommerce/api/customers/login' + +export default loginApi() From f0a2c744e83daa8e6cb9cc793ffd5d91330b22e7 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 09:15:14 -0500 Subject: [PATCH 04/17] Moved create customer API to signup method --- .../api/customers/handlers/signup.ts | 68 +++++++++++++++++++ lib/bigcommerce/api/customers/signup.ts | 50 ++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 lib/bigcommerce/api/customers/handlers/signup.ts create mode 100644 lib/bigcommerce/api/customers/signup.ts diff --git a/lib/bigcommerce/api/customers/handlers/signup.ts b/lib/bigcommerce/api/customers/handlers/signup.ts new file mode 100644 index 000000000..85400e39b --- /dev/null +++ b/lib/bigcommerce/api/customers/handlers/signup.ts @@ -0,0 +1,68 @@ +import { BigcommerceApiError } from '../../utils/errors' +import login from '../../operations/login' +import { SignupHandlers } from '../signup' + +const signup: SignupHandlers['signup'] = async ({ + res, + body: { firstName, lastName, email, password }, + config, +}) => { + // TODO: Add proper validations with something like Ajv + if (!(firstName && lastName && email && password)) { + return res.status(400).json({ + data: null, + errors: [{ message: 'Invalid request' }], + }) + } + // TODO: validate the password and email + // Passwords must be at least 7 characters and contain both alphabetic + // and numeric characters. + + let result: { data?: any } = {} + + try { + result = await config.storeApiFetch('/v3/customers', { + method: 'POST', + body: JSON.stringify([ + { + first_name: firstName, + last_name: lastName, + email, + authentication: { + new_password: password, + }, + }, + ]), + }) + } catch (error) { + if (error instanceof BigcommerceApiError && error.status === 422) { + const hasEmailError = '0.email' in error.data?.errors + + // If there's an error with the email, it most likely means it's duplicated + if (hasEmailError) { + return res.status(400).json({ + data: null, + errors: [ + { + message: 'The email is already in use', + code: 'duplicated_email', + }, + ], + }) + } + } + + throw error + } + + console.log('DATA', result.data) + + // TODO: Currently not working, fix this asap. + const loginData = await login({ variables: { email, password }, config }) + + console.log('LOGIN DATA', loginData) + + res.status(200).json({ data: result.data ?? null }) +} + +export default signup diff --git a/lib/bigcommerce/api/customers/signup.ts b/lib/bigcommerce/api/customers/signup.ts new file mode 100644 index 000000000..aa26f78cf --- /dev/null +++ b/lib/bigcommerce/api/customers/signup.ts @@ -0,0 +1,50 @@ +import createApiHandler, { + BigcommerceApiHandler, + BigcommerceHandler, +} from '../utils/create-api-handler' +import isAllowedMethod from '../utils/is-allowed-method' +import { BigcommerceApiError } from '../utils/errors' +import signup from './handlers/signup' + +export type SignupBody = { + firstName: string + lastName: string + email: string + password: string +} + +export type SignupHandlers = { + signup: BigcommerceHandler> +} + +const METHODS = ['POST'] + +const signupApi: BigcommerceApiHandler = async ( + req, + res, + config, + handlers +) => { + if (!isAllowedMethod(req, res, METHODS)) return + + const { cookies } = req + const cartId = cookies[config.cartCookie] + + try { + const body = { ...req.body, cartId } + return await handlers['signup']({ req, res, config, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof BigcommerceApiError + ? 'An unexpected error ocurred with the Bigcommerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +const handlers = { signup } + +export default createApiHandler(signupApi, handlers, {}) From 377015ceac2a082c9b8bed2375d91f0a7ab713a5 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 09:17:52 -0500 Subject: [PATCH 05/17] updated useSignup hook --- lib/bigcommerce/use-signup.tsx | 8 ++++---- pages/api/bigcommerce/customers/signup.ts | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 pages/api/bigcommerce/customers/signup.ts diff --git a/lib/bigcommerce/use-signup.tsx b/lib/bigcommerce/use-signup.tsx index 5f7338d6e..e97594864 100644 --- a/lib/bigcommerce/use-signup.tsx +++ b/lib/bigcommerce/use-signup.tsx @@ -1,16 +1,16 @@ import { useCallback } from 'react' import { HookFetcher } from '@lib/commerce/utils/types' import useCommerceSignup from '@lib/commerce/use-signup' -import type { CreateCustomerBody } from './api/customers' +import type { SignupBody } from './api/customers/signup' const defaultOpts = { - url: '/api/bigcommerce/customers', + url: '/api/bigcommerce/customers/signup', method: 'POST', } -export type SignupInput = CreateCustomerBody +export type SignupInput = SignupBody -export const fetcher: HookFetcher = ( +export const fetcher: HookFetcher = ( options, { firstName, lastName, email, password }, fetch diff --git a/pages/api/bigcommerce/customers/signup.ts b/pages/api/bigcommerce/customers/signup.ts new file mode 100644 index 000000000..d8be5512f --- /dev/null +++ b/pages/api/bigcommerce/customers/signup.ts @@ -0,0 +1,3 @@ +import signupApi from '@lib/bigcommerce/api/customers/signup' + +export default signupApi() From c2788c256b5df1b7296232143b0e5b22c998c7ce Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 21 Oct 2020 11:23:42 -0300 Subject: [PATCH 06/17] Reordering --- .../ProductCard/ProductCard.module.css | 19 +++++++++++++------ .../product/ProductCard/ProductCard.tsx | 12 +++++++----- components/ui/Grid/Grid.module.css | 3 ++- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/components/product/ProductCard/ProductCard.module.css b/components/product/ProductCard/ProductCard.module.css index 7846da50e..b7fd0aa35 100644 --- a/components/product/ProductCard/ProductCard.module.css +++ b/components/product/ProductCard/ProductCard.module.css @@ -65,23 +65,30 @@ @apply transform absolute inset-0 z-0 bg-secondary; } -.squareBg.gray { - @apply bg-gray-300 !important; +.simple { + & .squareBg { + @apply bg-gray-300 !important; + } } .productTitle { - line-height: 40px; - width: 18vw; + @apply pt-4 leading-8; + box-sizing: border-box; + width: 17vw; + margin-top: -1.2rem; & span { - @apply inline text-2xl leading-6 p-4 bg-primary text-primary font-bold; + @apply inline p-4 bg-primary text-primary font-bold; + font-size: inherit; + line-height: inherit; + letter-spacing: 0.4px; box-decoration-break: clone; -webkit-box-decoration-break: clone; } } .productPrice { - @apply px-3 py-1 pb-2 bg-primary text-base font-semibold inline-block text-sm leading-6; + @apply py-4 px-4 bg-primary text-base font-semibold inline-block text-sm leading-6; } .wishlistButton { diff --git a/components/product/ProductCard/ProductCard.tsx b/components/product/ProductCard/ProductCard.tsx index cae070fbd..dc04715c2 100644 --- a/components/product/ProductCard/ProductCard.tsx +++ b/components/product/ProductCard/ProductCard.tsx @@ -31,19 +31,21 @@ const ProductCard: FC = ({ className, product: p, variant }) => { return ( - +
-
+
-
-

+

+

{p.name} -

+

${p.prices?.price.value}
diff --git a/components/ui/Grid/Grid.module.css b/components/ui/Grid/Grid.module.css index a61c42b80..15f775f9b 100644 --- a/components/ui/Grid/Grid.module.css +++ b/components/ui/Grid/Grid.module.css @@ -20,9 +20,10 @@ } .layoutNormal { - @apply gap-6; + @apply gap-3; & > * { + font-size: 1.5rem; min-height: 325px; } } From f530f7d59747f1d88781de639a5bb5a6d6124722 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 21 Oct 2020 11:36:38 -0300 Subject: [PATCH 07/17] Changes to the headings --- .../ProductCard/ProductCard.module.css | 20 ++++++++++++++----- components/ui/Container/Container.tsx | 2 +- components/ui/Grid/Grid.module.css | 1 - pages/search.tsx | 3 ++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/components/product/ProductCard/ProductCard.module.css b/components/product/ProductCard/ProductCard.module.css index b7fd0aa35..d0ea6d80c 100644 --- a/components/product/ProductCard/ProductCard.module.css +++ b/components/product/ProductCard/ProductCard.module.css @@ -69,19 +69,28 @@ & .squareBg { @apply bg-gray-300 !important; } + + & .productTitle { + width: 18vw; + margin-top: -7px; + font-size: 1rem; + } + + & .productPrice { + @apply text-sm; + } } .productTitle { @apply pt-4 leading-8; - box-sizing: border-box; - width: 17vw; - margin-top: -1.2rem; + width: 400px; + font-size: 2rem; + letter-spacing: 0.4px; & span { @apply inline p-4 bg-primary text-primary font-bold; font-size: inherit; - line-height: inherit; - letter-spacing: 0.4px; + letter-spacing: inherit; box-decoration-break: clone; -webkit-box-decoration-break: clone; } @@ -89,6 +98,7 @@ .productPrice { @apply py-4 px-4 bg-primary text-base font-semibold inline-block text-sm leading-6; + letter-spacing: 0.4px; } .wishlistButton { diff --git a/components/ui/Container/Container.tsx b/components/ui/Container/Container.tsx index fa3c725f0..b8e07ee07 100644 --- a/components/ui/Container/Container.tsx +++ b/components/ui/Container/Container.tsx @@ -8,7 +8,7 @@ interface Props { } const Container: FC = ({ children, className, el = 'div' }) => { - const rootClassName = cn('mx-auto max-w-7xl px-6 md:px-12', className) + const rootClassName = cn('mx-auto max-w-7xl px-3 md:px-6', className) let Component: React.ComponentType * { - font-size: 1.5rem; min-height: 325px; } } diff --git a/pages/search.tsx b/pages/search.tsx index be2b28ee2..15f1b1ba0 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -59,7 +59,7 @@ export default function Search({ return ( -
+ -
+
From 2aae613f1b01b16a29c356ccf5819c3dc0a969c2 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 09:53:19 -0500 Subject: [PATCH 09/17] Added op to get the logged in customer --- codegen.json | 2 +- .../api/customers/handlers/create-customer.ts | 68 ------------------- .../handlers/get-logged-in-customer.ts | 44 ++++++++++++ lib/bigcommerce/api/customers/index.ts | 40 ++++------- lib/bigcommerce/schema.d.ts | 24 +++++++ 5 files changed, 83 insertions(+), 95 deletions(-) delete mode 100644 lib/bigcommerce/api/customers/handlers/create-customer.ts create mode 100644 lib/bigcommerce/api/customers/handlers/get-logged-in-customer.ts diff --git a/codegen.json b/codegen.json index cce0f4f8b..e08292091 100644 --- a/codegen.json +++ b/codegen.json @@ -8,7 +8,7 @@ }, "documents": [ { - "./lib/bigcommerce/api/{operations,fragments}/**/*.ts": { + "./lib/bigcommerce/api/**/*.ts": { "noRequire": true } } diff --git a/lib/bigcommerce/api/customers/handlers/create-customer.ts b/lib/bigcommerce/api/customers/handlers/create-customer.ts deleted file mode 100644 index 4ccbf31b4..000000000 --- a/lib/bigcommerce/api/customers/handlers/create-customer.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { BigcommerceApiError } from '../../utils/errors' -import login from '../../operations/login' -import type { CustomersHandlers } from '..' - -const createCustomer: CustomersHandlers['createCustomer'] = async ({ - res, - body: { firstName, lastName, email, password }, - config, -}) => { - // TODO: Add proper validations with something like Ajv - if (!(firstName && lastName && email && password)) { - return res.status(400).json({ - data: null, - errors: [{ message: 'Invalid request' }], - }) - } - // TODO: validate the password and email - // Passwords must be at least 7 characters and contain both alphabetic - // and numeric characters. - - let result: { data?: any } = {} - - try { - result = await config.storeApiFetch('/v3/customers', { - method: 'POST', - body: JSON.stringify([ - { - first_name: firstName, - last_name: lastName, - email, - authentication: { - new_password: password, - }, - }, - ]), - }) - } catch (error) { - if (error instanceof BigcommerceApiError && error.status === 422) { - const hasEmailError = '0.email' in error.data?.errors - - // If there's an error with the email, it most likely means it's duplicated - if (hasEmailError) { - return res.status(400).json({ - data: null, - errors: [ - { - message: 'The email is already in use', - code: 'duplicated_email', - }, - ], - }) - } - } - - throw error - } - - console.log('DATA', result.data) - - // TODO: Currently not working, fix this asap. - const loginData = await login({ variables: { email, password }, config }) - - console.log('LOGIN DATA', loginData) - - res.status(200).json({ data: result.data ?? null }) -} - -export default createCustomer diff --git a/lib/bigcommerce/api/customers/handlers/get-logged-in-customer.ts b/lib/bigcommerce/api/customers/handlers/get-logged-in-customer.ts new file mode 100644 index 000000000..99e9191f5 --- /dev/null +++ b/lib/bigcommerce/api/customers/handlers/get-logged-in-customer.ts @@ -0,0 +1,44 @@ +import { GetLoggedInCustomerQuery } from '@lib/bigcommerce/schema' +import type { CustomersHandlers } from '..' + +export const getLoggedInCustomerQuery = /* GraphQL */ ` + query getLoggedInCustomer { + customer { + entityId + firstName + lastName + email + company + customerGroupId + notes + phone + addressCount + attributeCount + storeCredit { + value + currencyCode + } + } + } +` + +const getLoggedInCustomer: CustomersHandlers['getLoggedInCustomer'] = async ({ + res, + config, +}) => { + const data = await config.fetch( + getLoggedInCustomerQuery + ) + const { customer } = data + + if (!customer) { + return res.status(400).json({ + data: null, + errors: [{ message: 'Customer not found', code: 'not_found' }], + }) + } + + res.status(200).json({ data: { customer } }) +} + +export default getLoggedInCustomer diff --git a/lib/bigcommerce/api/customers/index.ts b/lib/bigcommerce/api/customers/index.ts index a626ef2c7..228e882e7 100644 --- a/lib/bigcommerce/api/customers/index.ts +++ b/lib/bigcommerce/api/customers/index.ts @@ -4,42 +4,30 @@ import createApiHandler, { } from '../utils/create-api-handler' import isAllowedMethod from '../utils/is-allowed-method' import { BigcommerceApiError } from '../utils/errors' -import createCustomer from './handlers/create-customer' +import getLoggedInCustomer from './handlers/get-logged-in-customer' -type Body = Partial | undefined +export type Customer = any -export type Customer = null - -export type CreateCustomerBody = { - firstName: string - lastName: string - email: string - password: string +export type CustomerData = { + customer: Customer } export type CustomersHandlers = { - createCustomer: BigcommerceHandler< - Customer, - { cartId?: string } & Body - > + getLoggedInCustomer: BigcommerceHandler } -const METHODS = ['POST'] +const METHODS = ['GET'] -const customersApi: BigcommerceApiHandler = async ( - req, - res, - config -) => { +const customersApi: BigcommerceApiHandler< + CustomerData, + CustomersHandlers +> = async (req, res, config, handlers) => { if (!isAllowedMethod(req, res, METHODS)) return - const { cookies } = req - const cartId = cookies[config.cartCookie] - try { - if (req.method === 'POST') { - const body = { ...req.body, cartId } - return await handlers['createCustomer']({ req, res, config, body }) + if (req.method === 'GET') { + const body = null + return await handlers['getLoggedInCustomer']({ req, res, config, body }) } } catch (error) { console.error(error) @@ -53,6 +41,6 @@ const customersApi: BigcommerceApiHandler = async ( } } -const handlers = { createCustomer } +const handlers = { getLoggedInCustomer } export default createApiHandler(customersApi, handlers, {}) diff --git a/lib/bigcommerce/schema.d.ts b/lib/bigcommerce/schema.d.ts index eae1c8187..361d45a30 100644 --- a/lib/bigcommerce/schema.d.ts +++ b/lib/bigcommerce/schema.d.ts @@ -1653,6 +1653,30 @@ export enum CurrencyCode { Zwr = 'ZWR', } +export type GetLoggedInCustomerQueryVariables = Exact<{ [key: string]: never }> + +export type GetLoggedInCustomerQuery = { __typename?: 'Query' } & { + customer?: Maybe< + { __typename?: 'Customer' } & Pick< + Customer, + | 'entityId' + | 'firstName' + | 'lastName' + | 'email' + | 'company' + | 'customerGroupId' + | 'notes' + | 'phone' + | 'addressCount' + | 'attributeCount' + > & { + storeCredit: Array< + { __typename?: 'Money' } & Pick + > + } + > +} + export type CategoryTreeItemFragment = { __typename?: 'CategoryTreeItem' } & Pick< From 9d8db18c3883d354ca90c41671d01d62119b02be Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 21 Oct 2020 11:57:22 -0300 Subject: [PATCH 10/17] UI tweaks --- components/product/ProductView/ProductView.module.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/product/ProductView/ProductView.module.css b/components/product/ProductView/ProductView.module.css index e86769c44..99346db11 100644 --- a/components/product/ProductView/ProductView.module.css +++ b/components/product/ProductView/ProductView.module.css @@ -37,7 +37,9 @@ @apply absolute top-6 left-0 z-50; & .name { - @apply px-6 py-2 bg-primary text-primary font-bold text-3xl; + @apply px-6 py-2 bg-primary text-primary font-bold; + font-size: 2rem; + letter-spacing: 0.4px; } & .price { From 1b800807629f457d30115545eb6ce171d0a3eccc Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 21 Oct 2020 12:17:26 -0300 Subject: [PATCH 11/17] Added dropdown --- components/core/UserNav/UserNav.module.css | 9 +++++++ components/core/UserNav/UserNav.tsx | 28 ++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/components/core/UserNav/UserNav.module.css b/components/core/UserNav/UserNav.module.css index 21b149f80..d6a8e296e 100644 --- a/components/core/UserNav/UserNav.module.css +++ b/components/core/UserNav/UserNav.module.css @@ -15,3 +15,12 @@ @apply mr-0; } } + +.dropdownMenu { + @apply absolute right-0 mt-2 w-screen max-w-xs sm:px-0 z-50 border border-accents-1; + max-width: 160px; + + & .link { + @apply px-6 py-3 block space-y-1 hover:bg-accents-1 transition ease-in-out duration-150 text-base leading-6 font-medium text-gray-900; + } +} diff --git a/components/core/UserNav/UserNav.tsx b/components/core/UserNav/UserNav.tsx index 812c2a413..e005f625a 100644 --- a/components/core/UserNav/UserNav.tsx +++ b/components/core/UserNav/UserNav.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react' +import { FC, useState } from 'react' import cn from 'classnames' import useCart from '@lib/bigcommerce/cart/use-cart' import { Avatar } from '@components/core' @@ -17,6 +17,7 @@ const countItems = (count: number, items: any[]) => const UserNav: FC = ({ className }) => { const { data } = useCart() + const [displayDropdown, setDisplayDropdown] = useState(false) const { openSidebar, closeSidebar, displaySidebar } = useUI() const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0) @@ -39,10 +40,33 @@ const UserNav: FC = ({ className }) => { -
  • +
  • { + setDisplayDropdown((i) => !i) + }} + >
  • + + {displayDropdown && ( +
    +
    + +
    +
    + )} ) } From d98897a7e353db5e349dffefd0a064f08f62e485 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 10:23:05 -0500 Subject: [PATCH 12/17] Added useCustomer hook --- lib/bigcommerce/cart/use-cart.tsx | 7 +----- lib/bigcommerce/use-customer.tsx | 40 +++++++++++++++++++++++++++++++ lib/commerce/use-customer.tsx | 30 +++++++++++++++++++++++ lib/commerce/utils/use-data.tsx | 1 + 4 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 lib/bigcommerce/use-customer.tsx create mode 100644 lib/commerce/use-customer.tsx diff --git a/lib/bigcommerce/cart/use-cart.tsx b/lib/bigcommerce/cart/use-cart.tsx index 8fe80747a..38d1d8bac 100644 --- a/lib/bigcommerce/cart/use-cart.tsx +++ b/lib/bigcommerce/cart/use-cart.tsx @@ -14,12 +14,7 @@ export const fetcher: HookFetcher = ( { cartId }, fetch ) => { - return cartId - ? fetch({ - url: options?.url, - query: options?.query, - }) - : null + return cartId ? fetch({ ...options }) : null } export function extendHook( diff --git a/lib/bigcommerce/use-customer.tsx b/lib/bigcommerce/use-customer.tsx new file mode 100644 index 000000000..273e4c871 --- /dev/null +++ b/lib/bigcommerce/use-customer.tsx @@ -0,0 +1,40 @@ +import { ConfigInterface } from 'swr' +import { HookFetcher } from '@lib/commerce/utils/types' +import useCommerceCustomer, { CustomerInput } from '@lib/commerce/use-customer' +import type { Customer, CustomerData } from './api/customers' + +const defaultOpts = { + url: '/api/bigcommerce/customer', +} + +export type { Customer } + +export const fetcher: HookFetcher = ( + options, + { cartId }, + fetch +) => { + return cartId ? fetch({ ...options }) : null +} + +export function extendHook( + customFetcher: typeof fetcher, + swrOptions?: ConfigInterface +) { + const useCustomer = () => { + const cart = useCommerceCustomer( + defaultOpts, + [], + customFetcher, + { revalidateOnFocus: false, ...swrOptions } + ) + + return cart + } + + useCustomer.extend = extendHook + + return useCustomer +} + +export default extendHook(fetcher) diff --git a/lib/commerce/use-customer.tsx b/lib/commerce/use-customer.tsx new file mode 100644 index 000000000..e33587dcf --- /dev/null +++ b/lib/commerce/use-customer.tsx @@ -0,0 +1,30 @@ +import { responseInterface, ConfigInterface } from 'swr' +import Cookies from 'js-cookie' +import type { HookInput, HookFetcher, HookFetcherOptions } from './utils/types' +import useData from './utils/use-data' +import { useCommerce } from '.' + +export type CustomerResponse = responseInterface + +export type CustomerInput = { + cartId: string | undefined +} + +export default function useCustomer( + options: HookFetcherOptions, + input: HookInput, + fetcherFn: HookFetcher, + swrOptions?: ConfigInterface +) { + // TODO: Replace this with the login cookie + const { cartCookie } = useCommerce() + + const fetcher: typeof fetcherFn = (options, input, fetch) => { + input.cartId = Cookies.get(cartCookie) + return fetcherFn(options, input, fetch) + } + + const response = useData(options, input, fetcher, swrOptions) + + return response as CustomerResponse +} diff --git a/lib/commerce/utils/use-data.tsx b/lib/commerce/utils/use-data.tsx index fa2b6175c..513bec7bc 100644 --- a/lib/commerce/utils/use-data.tsx +++ b/lib/commerce/utils/use-data.tsx @@ -12,6 +12,7 @@ export default function useData( const fetcher = (url?: string, query?: string, ...args: any[]) => { return fetcherFn( { url, query }, + // Transform the input array into an object args.reduce((obj, val, i) => { obj[input[i][0]!] = val return obj From 2804627aefdd752923ca721d31717627a277f5b6 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 10:35:49 -0500 Subject: [PATCH 13/17] Updated defaults in all hooks --- lib/bigcommerce/cart/use-add-item.tsx | 4 ++-- lib/bigcommerce/cart/use-cart.tsx | 3 ++- lib/bigcommerce/cart/use-remove-item.tsx | 4 ++-- lib/bigcommerce/cart/use-update-item.tsx | 4 ++-- lib/bigcommerce/use-customer.tsx | 3 ++- lib/bigcommerce/use-login.tsx | 4 ++-- lib/bigcommerce/use-signup.tsx | 4 ++-- lib/bigcommerce/wishlist/use-add-item.tsx | 4 ++-- lib/bigcommerce/wishlist/use-remove-item.tsx | 4 ++-- lib/bigcommerce/wishlist/use-wishlist.tsx | 4 +++- lib/commerce/utils/use-data.tsx | 13 ++++++++++--- 11 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib/bigcommerce/cart/use-add-item.tsx b/lib/bigcommerce/cart/use-add-item.tsx index a18a7b651..fa8bb8b46 100644 --- a/lib/bigcommerce/cart/use-add-item.tsx +++ b/lib/bigcommerce/cart/use-add-item.tsx @@ -26,8 +26,8 @@ export const fetcher: HookFetcher = ( } return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { item }, }) } diff --git a/lib/bigcommerce/cart/use-cart.tsx b/lib/bigcommerce/cart/use-cart.tsx index 38d1d8bac..7ed6ba7d8 100644 --- a/lib/bigcommerce/cart/use-cart.tsx +++ b/lib/bigcommerce/cart/use-cart.tsx @@ -5,6 +5,7 @@ import type { Cart } from '../api/cart' const defaultOpts = { url: '/api/bigcommerce/cart', + method: 'GET', } export type { Cart } @@ -14,7 +15,7 @@ export const fetcher: HookFetcher = ( { cartId }, fetch ) => { - return cartId ? fetch({ ...options }) : null + return cartId ? fetch({ ...defaultOpts, ...options }) : null } export function extendHook( diff --git a/lib/bigcommerce/cart/use-remove-item.tsx b/lib/bigcommerce/cart/use-remove-item.tsx index 386462c7f..c07aa718e 100644 --- a/lib/bigcommerce/cart/use-remove-item.tsx +++ b/lib/bigcommerce/cart/use-remove-item.tsx @@ -19,8 +19,8 @@ export const fetcher: HookFetcher = ( fetch ) => { return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { itemId }, }) } diff --git a/lib/bigcommerce/cart/use-update-item.tsx b/lib/bigcommerce/cart/use-update-item.tsx index 78dd1bb84..bcad7ab3a 100644 --- a/lib/bigcommerce/cart/use-update-item.tsx +++ b/lib/bigcommerce/cart/use-update-item.tsx @@ -28,8 +28,8 @@ export const fetcher: HookFetcher = ( } return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { itemId, item }, }) } diff --git a/lib/bigcommerce/use-customer.tsx b/lib/bigcommerce/use-customer.tsx index 273e4c871..549fd3fa1 100644 --- a/lib/bigcommerce/use-customer.tsx +++ b/lib/bigcommerce/use-customer.tsx @@ -5,6 +5,7 @@ import type { Customer, CustomerData } from './api/customers' const defaultOpts = { url: '/api/bigcommerce/customer', + method: 'GET', } export type { Customer } @@ -14,7 +15,7 @@ export const fetcher: HookFetcher = ( { cartId }, fetch ) => { - return cartId ? fetch({ ...options }) : null + return cartId ? fetch({ ...defaultOpts, ...options }) : null } export function extendHook( diff --git a/lib/bigcommerce/use-login.tsx b/lib/bigcommerce/use-login.tsx index 37d59a79c..d2b86a827 100644 --- a/lib/bigcommerce/use-login.tsx +++ b/lib/bigcommerce/use-login.tsx @@ -22,8 +22,8 @@ export const fetcher: HookFetcher = ( } return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { email, password }, }) } diff --git a/lib/bigcommerce/use-signup.tsx b/lib/bigcommerce/use-signup.tsx index e97594864..68183aa6c 100644 --- a/lib/bigcommerce/use-signup.tsx +++ b/lib/bigcommerce/use-signup.tsx @@ -22,8 +22,8 @@ export const fetcher: HookFetcher = ( } return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { firstName, lastName, email, password }, }) } diff --git a/lib/bigcommerce/wishlist/use-add-item.tsx b/lib/bigcommerce/wishlist/use-add-item.tsx index 862041bbd..9bbbe009e 100644 --- a/lib/bigcommerce/wishlist/use-add-item.tsx +++ b/lib/bigcommerce/wishlist/use-add-item.tsx @@ -17,8 +17,8 @@ export const fetcher: HookFetcher = ( fetch ) => { return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { wishlistId, item }, }) } diff --git a/lib/bigcommerce/wishlist/use-remove-item.tsx b/lib/bigcommerce/wishlist/use-remove-item.tsx index ca9648d35..05f9744cb 100644 --- a/lib/bigcommerce/wishlist/use-remove-item.tsx +++ b/lib/bigcommerce/wishlist/use-remove-item.tsx @@ -19,8 +19,8 @@ export const fetcher: HookFetcher = ( fetch ) => { return fetch({ - url: options?.url ?? defaultOpts.url, - method: options?.method ?? defaultOpts.method, + ...defaultOpts, + ...options, body: { wishlistId, itemId }, }) } diff --git a/lib/bigcommerce/wishlist/use-wishlist.tsx b/lib/bigcommerce/wishlist/use-wishlist.tsx index 1d93609f0..d60660c05 100644 --- a/lib/bigcommerce/wishlist/use-wishlist.tsx +++ b/lib/bigcommerce/wishlist/use-wishlist.tsx @@ -4,6 +4,7 @@ import type { Wishlist } from '../api/wishlist' const defaultOpts = { url: '/api/bigcommerce/wishlists', + method: 'GET', } export type { Wishlist } @@ -18,7 +19,8 @@ export const fetcher: HookFetcher = ( fetch ) => { return fetch({ - url: options?.url, + ...defaultOpts, + ...options, body: { wishlistId }, }) } diff --git a/lib/commerce/utils/use-data.tsx b/lib/commerce/utils/use-data.tsx index 513bec7bc..c8e31657f 100644 --- a/lib/commerce/utils/use-data.tsx +++ b/lib/commerce/utils/use-data.tsx @@ -9,9 +9,14 @@ export default function useData( swrOptions?: ConfigInterface ) { const { fetcherRef } = useCommerce() - const fetcher = (url?: string, query?: string, ...args: any[]) => { + const fetcher = ( + url?: string, + query?: string, + method?: string, + ...args: any[] + ) => { return fetcherFn( - { url, query }, + { url, query, method }, // Transform the input array into an object args.reduce((obj, val, i) => { obj[input[i][0]!] = val @@ -24,7 +29,9 @@ export default function useData( const response = useSWR( () => { const opts = typeof options === 'function' ? options() : options - return opts ? [opts.url, opts.query, ...input.map((e) => e[1])] : null + return opts + ? [opts.url, opts.query, opts.method, ...input.map((e) => e[1])] + : null }, fetcher, swrOptions From 620df7f675e74c01207eb5ac0f2652806758756f Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 21 Oct 2020 13:22:27 -0300 Subject: [PATCH 14/17] Added dropdown --- components/core/UserNav/UserNav.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/core/UserNav/UserNav.module.css b/components/core/UserNav/UserNav.module.css index d6a8e296e..a554b1119 100644 --- a/components/core/UserNav/UserNav.module.css +++ b/components/core/UserNav/UserNav.module.css @@ -17,7 +17,7 @@ } .dropdownMenu { - @apply absolute right-0 mt-2 w-screen max-w-xs sm:px-0 z-50 border border-accents-1; + @apply absolute right-0 mt-2 w-screen max-w-xs sm:px-0 z-50 border border-accents-1 bg-primary; max-width: 160px; & .link { From 5bbe5d21b01db901fb78131cf45a78116070e302 Mon Sep 17 00:00:00 2001 From: Belen Curcio Date: Wed, 21 Oct 2020 14:24:42 -0300 Subject: [PATCH 15/17] navBar --- components/core/UserNav/UserNav.module.css | 5 +++++ components/core/UserNav/UserNav.tsx | 24 ++++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/components/core/UserNav/UserNav.module.css b/components/core/UserNav/UserNav.module.css index a554b1119..530cea1ae 100644 --- a/components/core/UserNav/UserNav.module.css +++ b/components/core/UserNav/UserNav.module.css @@ -1,4 +1,5 @@ .root { + @apply relative; } .list { @@ -20,6 +21,10 @@ @apply absolute right-0 mt-2 w-screen max-w-xs sm:px-0 z-50 border border-accents-1 bg-primary; max-width: 160px; + &.dropdownMenuContainer { + @apply shadow-lg overflow-hidden relative grid py-2; + } + & .link { @apply px-6 py-3 block space-y-1 hover:bg-accents-1 transition ease-in-out duration-150 text-base leading-6 font-medium text-gray-900; } diff --git a/components/core/UserNav/UserNav.tsx b/components/core/UserNav/UserNav.tsx index e005f625a..b25ffee6c 100644 --- a/components/core/UserNav/UserNav.tsx +++ b/components/core/UserNav/UserNav.tsx @@ -52,19 +52,17 @@ const UserNav: FC = ({ className }) => { {displayDropdown && (
    -
    - -
    +
    )} From 1569d62902ca121c9eae6e6a64a0d4447f53d068 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 12:49:59 -0500 Subject: [PATCH 16/17] Fixed type issue and updated to latest canary --- .../api/utils/create-api-handler.ts | 2 +- lib/bigcommerce/api/wishlist/index.ts | 4 +- package.json | 2 +- yarn.lock | 112 +++++++----------- 4 files changed, 43 insertions(+), 77 deletions(-) diff --git a/lib/bigcommerce/api/utils/create-api-handler.ts b/lib/bigcommerce/api/utils/create-api-handler.ts index be623d4cd..c6363cb15 100644 --- a/lib/bigcommerce/api/utils/create-api-handler.ts +++ b/lib/bigcommerce/api/utils/create-api-handler.ts @@ -3,7 +3,7 @@ import { BigcommerceConfig, getConfig } from '..' export type BigcommerceApiHandler< T = any, - H extends BigcommerceHandlers = {}, + H extends BigcommerceHandlers = {}, Options extends {} = {} > = ( req: NextApiRequest, diff --git a/lib/bigcommerce/api/wishlist/index.ts b/lib/bigcommerce/api/wishlist/index.ts index 7ab8c9173..3bcba106b 100644 --- a/lib/bigcommerce/api/wishlist/index.ts +++ b/lib/bigcommerce/api/wishlist/index.ts @@ -44,10 +44,8 @@ export type Wishlist = { // TODO: add missing fields } -export type WishlistList = Wishlist[] - export type WishlistHandlers = { - getAllWishlists: BigcommerceHandler + getAllWishlists: BigcommerceHandler getWishlist: BigcommerceHandler addWishlist: BigcommerceHandler< Wishlist, diff --git a/package.json b/package.json index ed4c562c5..9365500a3 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "js-cookie": "^2.2.1", "lodash.debounce": "^4.0.8", "lodash.random": "^3.2.0", - "next": "^9.5.6-canary.4", + "next": "^9.5.6-canary.9", "next-seo": "^4.11.0", "next-themes": "^0.0.4", "nextjs-progressbar": "^0.0.6", diff --git a/yarn.lock b/yarn.lock index b4a232911..023467d2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1514,20 +1514,20 @@ meow "^7.0.0" prettier "^2.0.5" -"@next/env@9.5.6-canary.6": - version "9.5.6-canary.6" - resolved "https://registry.yarnpkg.com/@next/env/-/env-9.5.6-canary.6.tgz#1aef358efc8d97ef6279d8539067df1ee4cea8af" - integrity sha512-WeM+gDMDUSDq+AidayYYkYKM9d8tqrpz6NMeM1Ga7zB96iymj72RdYZjEG2du4YcoSZ69m4nRHKUTMO9D2FTfQ== +"@next/env@9.5.6-canary.9": + version "9.5.6-canary.9" + resolved "https://registry.yarnpkg.com/@next/env/-/env-9.5.6-canary.9.tgz#d1f4fbfc424074b791b5e94ed8b1018624d8f588" + integrity sha512-/LQJcKrgWOCMWiEE4V56IQivLeVx8dvEpWLNGdeX5zaWIB9Vqp/peK8VJaz2mZf2+RRwy3GidBCueatAa37SLg== -"@next/polyfill-module@9.5.6-canary.6": - version "9.5.6-canary.6" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-9.5.6-canary.6.tgz#185b659bbc06f75ff221c02a934a342bde181f85" - integrity sha512-rt1XA3RILd4MU+mVI33yeyyCS8qlEaWuRHbX/LTKNNlVY9u3fQKr1ir0EboPj4ovQrZQaPzShgOoeN9Xe5xeaw== +"@next/polyfill-module@9.5.6-canary.9": + version "9.5.6-canary.9" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-9.5.6-canary.9.tgz#1270e7bbeb11c88103f6013794f89c92d7e37d5a" + integrity sha512-X4csjgv4CBcu6hr4XT21fWv9s5CvQw7UlCvTQa4H+No/ELfi4ITCBJJzHa4smCYcYSZXRHkW1J71p+D2HvQ23w== -"@next/react-dev-overlay@9.5.6-canary.6": - version "9.5.6-canary.6" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.6-canary.6.tgz#73950f96f2f57b34424988693e4734b3a5c010b6" - integrity sha512-oEY43VgFRdesKzI42Q+gfiagXlBbDtvQ0m8WSuFZS1VqTPFvrOKQ1BqUhOyNciryi5vdNo6QFW0vreeejlccLw== +"@next/react-dev-overlay@9.5.6-canary.9": + version "9.5.6-canary.9" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.6-canary.9.tgz#a295117b6837e6c0bd7822fb689a5765e74702b4" + integrity sha512-sqcler8Jl29p4UPdGRUAIfbWO0UwsWUyJ7KY4w5xLNu21z5fu0+cb47JoZAaOfdxYx15ySnkhMqCp5O14/QpUA== dependencies: "@babel/code-frame" "7.10.4" ally.js "1.4.1" @@ -1540,10 +1540,10 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@9.5.6-canary.6": - version "9.5.6-canary.6" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.6-canary.6.tgz#a81fce1feb00e2ba8bc13e42191b04e4d810c6dd" - integrity sha512-SEVl95GfbwRWBZOkCUkMX9iYnD7EufIsduBs8npFuUfFwqVxGmvL2RmWqKQhloHeLPJELzTzPBxuydJ07MXxog== +"@next/react-refresh-utils@9.5.6-canary.9": + version "9.5.6-canary.9" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.6-canary.9.tgz#e552e441a6a61acb94d81e76bea315d88bd12fed" + integrity sha512-i9lbMJ3RTZ3GBVAmgjpRuvr3nxLEdJeAbUD8WDcHJo5Asa2VIsH/+TJgdhZ7Td9eJ6c2A+xmrEVBVvVwZsca+w== "@nodelib/fs.scandir@2.1.3": version "2.1.3" @@ -2528,16 +2528,13 @@ acorn@^8.0.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.0.4.tgz#7a3ae4191466a6984eee0fe3407a4f3aa9db8354" integrity sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ== -adjust-sourcemap-loader@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz#6471143af75ec02334b219f54bc7970c52fb29a4" - integrity sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA== +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== dependencies: - assert "1.4.1" - camelcase "5.0.0" - loader-utils "1.2.3" - object-path "0.11.4" - regex-parser "2.2.10" + loader-utils "^2.0.0" + regex-parser "^2.2.11" agent-base@6: version "6.0.1" @@ -2732,13 +2729,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= - dependencies: - util "0.10.3" - assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -3187,11 +3177,6 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" -camelcase@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" - integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== - camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -4918,11 +4903,6 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -6011,10 +5991,10 @@ next-tick@~1.0.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= -next@^9.5.6-canary.4: - version "9.5.6-canary.6" - resolved "https://registry.yarnpkg.com/next/-/next-9.5.6-canary.6.tgz#5335a3cd93a3fe85ebfb986c614081885d8e1a2d" - integrity sha512-u54H/v91wHayaJzIx+u9x9mtt8fuPUJpFzLk6VORM9jhwDZbgbtzaFyp7rkq71rECtJhzu+X2KtTHPcEejtX8A== +next@^9.5.6-canary.9: + version "9.5.6-canary.9" + resolved "https://registry.yarnpkg.com/next/-/next-9.5.6-canary.9.tgz#93acf48d395a54269eeff77d67a5bb6b46c87c22" + integrity sha512-i/vNrr4VxqPUiPn5HdR0C2TcAqUmfc5lY6Qj7Hywi4Uit+f9ltWKC+r4WoOw6iIs+TRTej/EzrKnyXEUn5vAcQ== dependencies: "@ampproject/toolbox-optimizer" "2.6.0" "@babel/code-frame" "7.10.4" @@ -6035,10 +6015,10 @@ next@^9.5.6-canary.4: "@babel/runtime" "7.11.2" "@babel/types" "7.11.5" "@hapi/accept" "5.0.1" - "@next/env" "9.5.6-canary.6" - "@next/polyfill-module" "9.5.6-canary.6" - "@next/react-dev-overlay" "9.5.6-canary.6" - "@next/react-refresh-utils" "9.5.6-canary.6" + "@next/env" "9.5.6-canary.9" + "@next/polyfill-module" "9.5.6-canary.9" + "@next/react-dev-overlay" "9.5.6-canary.9" + "@next/react-refresh-utils" "9.5.6-canary.9" ast-types "0.13.2" babel-plugin-transform-define "2.0.0" babel-plugin-transform-react-remove-prop-types "0.4.24" @@ -6064,7 +6044,7 @@ next@^9.5.6-canary.4: prop-types "15.7.2" react-is "16.13.1" react-refresh "0.8.3" - resolve-url-loader "3.1.1" + resolve-url-loader "3.1.2" sass-loader "10.0.2" schema-utils "2.7.1" stream-browserify "3.0.0" @@ -6235,11 +6215,6 @@ object-keys@^1.0.12, object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-path@0.11.4: - version "0.11.4" - resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" - integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -7274,10 +7249,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regex-parser@2.2.10: - version "2.2.10" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.10.tgz#9e66a8f73d89a107616e63b39d4deddfee912b37" - integrity sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA== +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexpu-core@^4.7.1: version "4.7.1" @@ -7423,12 +7398,12 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-url-loader@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz#28931895fa1eab9be0647d3b2958c100ae3c0bf0" - integrity sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ== +resolve-url-loader@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" + integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ== dependencies: - adjust-sourcemap-loader "2.0.0" + adjust-sourcemap-loader "3.0.0" camelcase "5.3.1" compose-function "3.0.3" convert-source-map "1.7.0" @@ -8417,13 +8392,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" From 316801627bf1725e04af77c64f2191775c07faa4 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 21 Oct 2020 15:21:31 -0500 Subject: [PATCH 17/17] Fixed type --- .../api/customers/handlers/signup.ts | 64 +++++++++---------- .../api/utils/fetch-graphql-api.ts | 12 ++++ .../wishlist/handlers/get-all-wishlists.ts | 9 +-- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/lib/bigcommerce/api/customers/handlers/signup.ts b/lib/bigcommerce/api/customers/handlers/signup.ts index 85400e39b..911919088 100644 --- a/lib/bigcommerce/api/customers/handlers/signup.ts +++ b/lib/bigcommerce/api/customers/handlers/signup.ts @@ -20,40 +20,40 @@ const signup: SignupHandlers['signup'] = async ({ let result: { data?: any } = {} - try { - result = await config.storeApiFetch('/v3/customers', { - method: 'POST', - body: JSON.stringify([ - { - first_name: firstName, - last_name: lastName, - email, - authentication: { - new_password: password, - }, - }, - ]), - }) - } catch (error) { - if (error instanceof BigcommerceApiError && error.status === 422) { - const hasEmailError = '0.email' in error.data?.errors + // try { + // result = await config.storeApiFetch('/v3/customers', { + // method: 'POST', + // body: JSON.stringify([ + // { + // first_name: firstName, + // last_name: lastName, + // email, + // authentication: { + // new_password: password, + // }, + // }, + // ]), + // }) + // } catch (error) { + // if (error instanceof BigcommerceApiError && error.status === 422) { + // const hasEmailError = '0.email' in error.data?.errors - // If there's an error with the email, it most likely means it's duplicated - if (hasEmailError) { - return res.status(400).json({ - data: null, - errors: [ - { - message: 'The email is already in use', - code: 'duplicated_email', - }, - ], - }) - } - } + // // If there's an error with the email, it most likely means it's duplicated + // if (hasEmailError) { + // return res.status(400).json({ + // data: null, + // errors: [ + // { + // message: 'The email is already in use', + // code: 'duplicated_email', + // }, + // ], + // }) + // } + // } - throw error - } + // throw error + // } console.log('DATA', result.data) diff --git a/lib/bigcommerce/api/utils/fetch-graphql-api.ts b/lib/bigcommerce/api/utils/fetch-graphql-api.ts index 1e79f7c2f..1ab323832 100644 --- a/lib/bigcommerce/api/utils/fetch-graphql-api.ts +++ b/lib/bigcommerce/api/utils/fetch-graphql-api.ts @@ -20,6 +20,8 @@ export default async function fetchGraphqlApi( }), }) + // console.log('HEADERS', getRawHeaders(res)) + const json = await res.json() if (json.errors) { console.error(json.errors) @@ -27,3 +29,13 @@ export default async function fetchGraphqlApi( } return json.data } + +function getRawHeaders(res: Response) { + const headers: { [key: string]: string } = {} + + res.headers.forEach((value, key) => { + headers[key] = value + }) + + return headers +} diff --git a/lib/bigcommerce/api/wishlist/handlers/get-all-wishlists.ts b/lib/bigcommerce/api/wishlist/handlers/get-all-wishlists.ts index 310c7f41d..30fb83c2f 100644 --- a/lib/bigcommerce/api/wishlist/handlers/get-all-wishlists.ts +++ b/lib/bigcommerce/api/wishlist/handlers/get-all-wishlists.ts @@ -1,5 +1,4 @@ -import { BigcommerceApiError } from '../../utils/errors' -import type { WishlistList, WishlistHandlers } from '..' +import type { Wishlist, WishlistHandlers } from '..' // Return all wishlists const getAllWishlists: WishlistHandlers['getAllWishlists'] = async ({ @@ -7,10 +6,12 @@ const getAllWishlists: WishlistHandlers['getAllWishlists'] = async ({ body: { customerId }, config, }) => { - let result: { data?: WishlistList } = {} + let result: { data?: Wishlist[] } = {} try { - result = await config.storeApiFetch(`/v3/wishlists/customer_id=${customerId}`) + result = await config.storeApiFetch( + `/v3/wishlists/customer_id=${customerId}` + ) } catch (error) { throw error }