Add customer updated types & fixes

This commit is contained in:
Catalin Pinte 2022-09-14 09:28:12 +03:00
parent 6d289d1b5e
commit 5b6e50e7d0
14 changed files with 122 additions and 33 deletions

View File

@ -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 })

View File

@ -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<typeof handler>

View File

@ -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'

View File

@ -32,7 +32,7 @@ export const handler: SWRHook<GetWishlistHook> = {
const { data: customer } = useCustomer()
const response = useData({
input: [
['customerId', customer?.entityId],
['customerId', customer?.id],
['includeProducts', input?.includeProducts],
],
swrOptions: {

View File

@ -6,7 +6,7 @@ import isAllowedOperation from '../../utils/is-allowed-operation'
const customerEndpoint: GetAPISchema<
any,
CustomerSchema<any>
CustomerSchema
>['endpoint']['handler'] = async (ctx) => {
const { req, res, handlers } = ctx

View File

@ -5,7 +5,7 @@ import type { HookFetcherFn, SWRHook } from '../utils/types'
import type { Provider } from '..'
export type UseCustomer<
H extends SWRHook<CustomerHook<any>> = SWRHook<CustomerHook>
H extends SWRHook<CustomerHook> = SWRHook<CustomerHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<CustomerHook> = SWRFetcher

View File

@ -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 }
}

View File

@ -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
/**

View File

@ -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<T extends CustomerTypes = CustomerTypes> = {
data: T['customer'] | null
fetchData: { customer: T['customer'] } | null
export interface CustomerHook {
data: Customer | null | undefined
fetchData: { customer: Customer } | null
}
export type CustomerSchema<T extends CustomerTypes = CustomerTypes> = {
export type CustomerSchema = {
endpoint: {
options: {}
handlers: {
getLoggedInCustomer: {
data: { customer: T['customer'] } | null
data: { customer: Customer } | null
}
}
}

View File

@ -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<CustomerHook> = {
},
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<any>({
query: options.query,
method: options.method,
variables: [
@ -29,7 +32,16 @@ export const handler: SWRHook<CustomerHook> = {
token,
],
})
return customer
? {
id: customer.id,
firstName: customer.firstname,
lastName: customer.lastname,
email: customer.email,
phone: customer.phone,
}
: null
},
useHook:
({ useData }) =>

View File

@ -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,
}
}

View File

@ -14,14 +14,28 @@ export const handler: SWRHook<CustomerHook> = {
},
async fetcher({ options, fetch }) {
const customerAccessToken = getCustomerToken()
if (customerAccessToken) {
const data = await fetch<GetCustomerQuery, GetCustomerQueryVariables>({
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 }) =>

View File

@ -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,
}
}

View File

@ -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"],