diff --git a/packages/bigcommerce/src/api/endpoints/customer/get-logged-in-customer.ts b/packages/bigcommerce/src/api/endpoints/customer/get-logged-in-customer.ts index 4c93730f6..e517072ae 100644 --- a/packages/bigcommerce/src/api/endpoints/customer/get-logged-in-customer.ts +++ b/packages/bigcommerce/src/api/endpoints/customer/get-logged-in-customer.ts @@ -47,7 +47,19 @@ const getLoggedInCustomer: CustomerEndpoint['handlers']['getLoggedInCustomer'] = }) } - return res.status(200).json({ data: { customer } }) + return res.status(200).json({ + data: { + customer: { + id: String(customer.entityId), + firstName: customer.firstName, + lastName: customer.lastName, + email: customer.email, + company: customer.company, + phone: customer.phone, + notes: customer.notes, + }, + }, + }) } res.status(200).json({ data: null }) diff --git a/packages/bigcommerce/src/customer/use-customer.tsx b/packages/bigcommerce/src/customer/use-customer.tsx index 36bf88617..0756377ff 100644 --- a/packages/bigcommerce/src/customer/use-customer.tsx +++ b/packages/bigcommerce/src/customer/use-customer.tsx @@ -1,5 +1,7 @@ import { SWRHook } from '@vercel/commerce/utils/types' -import useCustomer, { UseCustomer } from '@vercel/commerce/customer/use-customer' +import useCustomer, { + UseCustomer, +} from '@vercel/commerce/customer/use-customer' import type { CustomerHook } from '../types/customer' export default useCustomer as UseCustomer diff --git a/packages/bigcommerce/src/lib/normalize.ts b/packages/bigcommerce/src/lib/normalize.ts index 4db1fea0e..19a3d467a 100644 --- a/packages/bigcommerce/src/lib/normalize.ts +++ b/packages/bigcommerce/src/lib/normalize.ts @@ -2,6 +2,7 @@ import type { Product } from '../types/product' import type { Cart, BigcommerceCart, LineItem } from '../types/cart' import type { Page } from '../types/page' import type { BCCategory, BCBrand, Category, Brand } from '../types/site' + import { definitions } from '../api/definitions/store-content' import update from './immutability' import getSlug from './get-slug' diff --git a/packages/bigcommerce/src/wishlist/use-wishlist.tsx b/packages/bigcommerce/src/wishlist/use-wishlist.tsx index 7882233f5..f11a75ec0 100644 --- a/packages/bigcommerce/src/wishlist/use-wishlist.tsx +++ b/packages/bigcommerce/src/wishlist/use-wishlist.tsx @@ -32,7 +32,7 @@ export const handler: SWRHook = { const { data: customer } = useCustomer() const response = useData({ input: [ - ['customerId', customer?.entityId], + ['customerId', customer?.id], ['includeProducts', input?.includeProducts], ], swrOptions: { diff --git a/packages/commerce/src/api/endpoints/customer/index.ts b/packages/commerce/src/api/endpoints/customer/index.ts index eb2a048b7..2107ebb89 100644 --- a/packages/commerce/src/api/endpoints/customer/index.ts +++ b/packages/commerce/src/api/endpoints/customer/index.ts @@ -6,7 +6,7 @@ import isAllowedOperation from '../../utils/is-allowed-operation' const customerEndpoint: GetAPISchema< any, - CustomerSchema + CustomerSchema >['endpoint']['handler'] = async (ctx) => { const { req, res, handlers } = ctx diff --git a/packages/commerce/src/customer/use-customer.tsx b/packages/commerce/src/customer/use-customer.tsx index bbeeb3269..9bb703f7e 100644 --- a/packages/commerce/src/customer/use-customer.tsx +++ b/packages/commerce/src/customer/use-customer.tsx @@ -5,7 +5,7 @@ import type { HookFetcherFn, SWRHook } from '../utils/types' import type { Provider } from '..' export type UseCustomer< - H extends SWRHook> = SWRHook + H extends SWRHook = SWRHook > = ReturnType export const fetcher: HookFetcherFn = SWRFetcher diff --git a/packages/commerce/src/types/customer/address.ts b/packages/commerce/src/types/customer/address.ts index 6c8d8009f..e0895e3c7 100644 --- a/packages/commerce/src/types/customer/address.ts +++ b/packages/commerce/src/types/customer/address.ts @@ -49,6 +49,9 @@ export interface AddressFields { country: string } +/** + * Hook for getting a customer's addresses. + */ export interface GetAddressesHook { data: Address[] | null input: {} @@ -56,6 +59,9 @@ export interface GetAddressesHook { swrState: { isEmpty: boolean } } +/** + * Hook for adding an address to a customer's account. + */ export interface AddItemHook { data: Address input?: AddressFields @@ -64,6 +70,9 @@ export interface AddItemHook { actionInput: AddressFields } +/** + * Hook for updating an address to a customer's account. + */ export interface UpdateItemHook { data: Address | null input: { item?: AddressFields; wait?: number } @@ -72,6 +81,9 @@ export interface UpdateItemHook { actionInput: AddressFields & { id: string } } +/** + * Hook for deliting an address to a customer's account. + */ export interface RemoveItemHook { data: Address | null | undefined input: { item?: Address } @@ -80,6 +92,9 @@ export interface RemoveItemHook { actionInput: { id: string } } +/** + * Hooks for managing a customer's addresses. + */ export interface CustomerAddressHooks { getAddresses: GetAddressesHook addItem: AddItemHook @@ -87,6 +102,10 @@ export interface CustomerAddressHooks { removeItem: RemoveItemHook } +/** + * API endpoints for managing a customer's addresses. + */ + export type AddItemHandler = AddItemHook & { body: { cartId: string } } diff --git a/packages/commerce/src/types/customer/card.ts b/packages/commerce/src/types/customer/card.ts index b4ad44012..15583b11b 100644 --- a/packages/commerce/src/types/customer/card.ts +++ b/packages/commerce/src/types/customer/card.ts @@ -4,8 +4,8 @@ export interface Card { */ id: string /** - * Masked card number. - * @example "************4242" + * Masked card number. Contains only the last 4 digits. + * @example "4242" */ mask: string /** diff --git a/packages/commerce/src/types/customer/index.ts b/packages/commerce/src/types/customer/index.ts index f0b210f62..87d954028 100644 --- a/packages/commerce/src/types/customer/index.ts +++ b/packages/commerce/src/types/customer/index.ts @@ -1,24 +1,53 @@ export * as Card from './card' export * as Address from './address' -// TODO: define this type -export type Customer = any - -export type CustomerTypes = { - customer: Customer +export interface Customer { + /** + * The unique identifier for the customer. + */ + id: string + /** + * The customer's first name. + */ + firstName: string + /** + * The customer's last name. + */ + lastName: string + /** + * The customer's email address. + */ + email?: string + /** + * The customer's phone number. + * @optional + */ + phone?: string + /** + * The customer's company name. + */ + company?: string + /** + * The customer's notes. + */ + notes?: string + /** + * Indicates wathever the customer accepts marketing, such as email newsletters. + */ + acceptsMarketing?: boolean } -export type CustomerHook = { - data: T['customer'] | null - fetchData: { customer: T['customer'] } | null +export interface CustomerHook { + data: Customer | null | undefined + fetchData: { customer: Customer } | null } -export type CustomerSchema = { +export type CustomerSchema = { endpoint: { options: {} handlers: { getLoggedInCustomer: { - data: { customer: T['customer'] } | null + data: { customer: Customer } | null } } } diff --git a/packages/commercejs/src/customer/use-customer.tsx b/packages/commercejs/src/customer/use-customer.tsx index 4906223fd..b121b0974 100644 --- a/packages/commercejs/src/customer/use-customer.tsx +++ b/packages/commercejs/src/customer/use-customer.tsx @@ -1,7 +1,9 @@ import Cookies from 'js-cookie' import { decode } from 'jsonwebtoken' import { SWRHook } from '@vercel/commerce/utils/types' -import useCustomer, { UseCustomer } from '@vercel/commerce/customer/use-customer' +import useCustomer, { + UseCustomer, +} from '@vercel/commerce/customer/use-customer' import { CUSTOMER_COOKIE, API_URL } from '../constants' import type { CustomerHook } from '../types/customer' @@ -13,12 +15,13 @@ export const handler: SWRHook = { }, async fetcher({ options, fetch }) { const token = Cookies.get(CUSTOMER_COOKIE) + if (!token) { return null } const decodedToken = decode(token) as { cid: string } - const customer = await fetch({ + const customer = await fetch({ query: options.query, method: options.method, variables: [ @@ -29,7 +32,16 @@ export const handler: SWRHook = { token, ], }) + return customer + ? { + id: customer.id, + firstName: customer.firstname, + lastName: customer.lastname, + email: customer.email, + phone: customer.phone, + } + : null }, useHook: ({ useData }) => diff --git a/packages/kibocommerce/src/lib/normalize.ts b/packages/kibocommerce/src/lib/normalize.ts index e62658084..1c2e1dc46 100644 --- a/packages/kibocommerce/src/lib/normalize.ts +++ b/packages/kibocommerce/src/lib/normalize.ts @@ -95,12 +95,11 @@ export function normalizeCart(data: any): Cart { export function normalizeCustomer(customer: CustomerAccountInput): Customer { return { - id: customer.id, - firstName: customer.firstName, - lastName: customer.lastName, - email: customer.emailAddress, - userName: customer.userName, - isAnonymous: customer.isAnonymous, + id: String(customer.id), + firstName: customer.firstName || '', + lastName: customer.lastName || '', + email: customer.emailAddress || '', + acceptsMarketing: !!customer.acceptsMarketing, } } diff --git a/packages/shopify/src/customer/use-customer.tsx b/packages/shopify/src/customer/use-customer.tsx index 6fc9a53a7..65e960240 100644 --- a/packages/shopify/src/customer/use-customer.tsx +++ b/packages/shopify/src/customer/use-customer.tsx @@ -14,14 +14,28 @@ export const handler: SWRHook = { }, async fetcher({ options, fetch }) { const customerAccessToken = getCustomerToken() + if (customerAccessToken) { - const data = await fetch({ + const { customer } = await fetch< + GetCustomerQuery, + GetCustomerQueryVariables + >({ ...options, variables: { customerAccessToken: getCustomerToken() }, }) - return data.customer + + if (!customer) { + return null + } + + return { + id: customer.id, + firstName: customer.firstName ?? 'N/A', + lastName: customer.lastName ?? '', + ...(customer.email && { email: customer.email }), + ...(customer.phone && { phone: customer.phone }), + } } - return null }, useHook: ({ useData }) => diff --git a/packages/spree/src/utils/normalizations/normalize-user.ts b/packages/spree/src/utils/normalizations/normalize-user.ts index 8b738fbaf..0bc94d995 100644 --- a/packages/spree/src/utils/normalizations/normalize-user.ts +++ b/packages/spree/src/utils/normalizations/normalize-user.ts @@ -6,10 +6,11 @@ const normalizeUser = ( _spreeSuccessResponse: SpreeSdkResponse, spreeUser: AccountAttr ): Customer => { - const email = spreeUser.attributes.email - return { - email, + id: spreeUser.id, + email: spreeUser.attributes.email, + firstName: spreeUser.attributes.firstname, + lastName: spreeUser.attributes.lastname, } } diff --git a/site/tsconfig.json b/site/tsconfig.json index 2de809a44..7f4d46619 100644 --- a/site/tsconfig.json +++ b/site/tsconfig.json @@ -23,8 +23,8 @@ "@components/*": ["components/*"], "@commerce": ["../packages/commerce/src"], "@commerce/*": ["../packages/commerce/src/*"], - "@framework": ["../packages/shopify/src"], - "@framework/*": ["../packages/shopify/src/*"] + "@framework": ["../packages/vendure/src"], + "@framework/*": ["../packages/vendure/src/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],