From a1e47a73d2ea0e305fb6c04cd6d6855027ab1e95 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Tue, 20 Oct 2020 22:27:38 -0500 Subject: [PATCH] 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()