diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..9bf4d12b5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true +} diff --git a/commerce.config.json b/commerce.config.json index ad72b58de..8fcacf543 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -1,7 +1,7 @@ { "features": { - "cart": true, - "search": true, + "cart": false, + "search": false, "wishlist": false, "customerAuth": false, "customCheckout": false diff --git a/framework/commerce/config.js b/framework/commerce/config.js index 28502a04e..bfe4612cb 100644 --- a/framework/commerce/config.js +++ b/framework/commerce/config.js @@ -14,6 +14,7 @@ const PROVIDERS = [ 'swell', 'vendure', 'local', + 'ordercloud', ] function getProviderName() { diff --git a/framework/ordercloud/.env.template b/framework/ordercloud/.env.template new file mode 100644 index 000000000..2f3b5ddc6 --- /dev/null +++ b/framework/ordercloud/.env.template @@ -0,0 +1 @@ +COMMERCE_PROVIDER=ordercloud diff --git a/framework/ordercloud/README.md b/framework/ordercloud/README.md new file mode 100644 index 000000000..9bf6f63af --- /dev/null +++ b/framework/ordercloud/README.md @@ -0,0 +1 @@ +# Next.js Ordercloud Provider diff --git a/framework/ordercloud/api/endpoints/cart/index.ts b/framework/ordercloud/api/endpoints/cart/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/cart/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/catalog/index.ts b/framework/ordercloud/api/endpoints/catalog/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/catalog/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/catalog/products.ts b/framework/ordercloud/api/endpoints/catalog/products.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/catalog/products.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/checkout/index.ts b/framework/ordercloud/api/endpoints/checkout/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/checkout/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/customer/index.ts b/framework/ordercloud/api/endpoints/customer/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/customer/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/login/index.ts b/framework/ordercloud/api/endpoints/login/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/login/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/logout/index.ts b/framework/ordercloud/api/endpoints/logout/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/logout/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/signup/index.ts b/framework/ordercloud/api/endpoints/signup/index.ts new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/signup/index.ts @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/endpoints/wishlist/index.tsx b/framework/ordercloud/api/endpoints/wishlist/index.tsx new file mode 100644 index 000000000..491bf0ac9 --- /dev/null +++ b/framework/ordercloud/api/endpoints/wishlist/index.tsx @@ -0,0 +1 @@ +export default function noopApi(...args: any[]): void {} diff --git a/framework/ordercloud/api/index.ts b/framework/ordercloud/api/index.ts new file mode 100644 index 000000000..55007eada --- /dev/null +++ b/framework/ordercloud/api/index.ts @@ -0,0 +1,50 @@ +import type { CommerceAPI, CommerceAPIConfig } from '@commerce/api' +import { getCommerceApi as commerceApi } from '@commerce/api' +import createFetcher from './utils/fetch-rest' + +import getAllPages from './operations/get-all-pages' +import getPage from './operations/get-page' +import getSiteInfo from './operations/get-site-info' +import getCustomerWishlist from './operations/get-customer-wishlist' +import getAllProductPaths from './operations/get-all-product-paths' +import getAllProducts from './operations/get-all-products' +import getProduct from './operations/get-product' + +export interface OrdercloudConfig extends Omit { + fetch: ( + method: string, + resource: string, + body?: Record, + fetchOptions?: Record + ) => Promise +} + +const config: OrdercloudConfig = { + commerceUrl: 'https://sandboxapi.ordercloud.io/v1', + apiToken: '', + cartCookie: '', + customerCookie: '', + cartCookieMaxAge: 2592000, + fetch: createFetcher(() => getCommerceApi().getConfig()), +} + +const operations = { + getAllPages, + getPage, + getSiteInfo, + getCustomerWishlist, + getAllProductPaths, + getAllProducts, + getProduct, +} + +export const provider = { config, operations } + +export type Provider = typeof provider +export type OrderCloudAPI

= CommerceAPI

+ +export function getCommerceApi

( + customProvider: P = provider as any +): OrderCloudAPI

{ + return commerceApi(customProvider as any) +} diff --git a/framework/ordercloud/api/operations/get-all-pages.ts b/framework/ordercloud/api/operations/get-all-pages.ts new file mode 100644 index 000000000..642047dba --- /dev/null +++ b/framework/ordercloud/api/operations/get-all-pages.ts @@ -0,0 +1,19 @@ +export type Page = { url: string } +export type GetAllPagesResult = { pages: Page[] } +import type { OrdercloudConfig } from '../index' + +export default function getAllPagesOperation() { + function getAllPages({ + config, + preview, + }: { + url?: string + config?: Partial + preview?: boolean + }): Promise { + return Promise.resolve({ + pages: [], + }) + } + return getAllPages +} diff --git a/framework/ordercloud/api/operations/get-all-product-paths.ts b/framework/ordercloud/api/operations/get-all-product-paths.ts new file mode 100644 index 000000000..aa5c8d052 --- /dev/null +++ b/framework/ordercloud/api/operations/get-all-product-paths.ts @@ -0,0 +1,16 @@ +import data from '../../data.json' + +export type GetAllProductPathsResult = { + products: Array<{ path: string }> +} + +export default function getAllProductPathsOperation() { + function getAllProductPaths(): Promise { + return Promise.resolve({ + products: [] + // products: data.products.map(({ path }) => ({ path })), + }) + } + + return getAllProductPaths +} diff --git a/framework/ordercloud/api/operations/get-all-products.ts b/framework/ordercloud/api/operations/get-all-products.ts new file mode 100644 index 000000000..71a3e4f2f --- /dev/null +++ b/framework/ordercloud/api/operations/get-all-products.ts @@ -0,0 +1,44 @@ +import { Product } from '@commerce/types/product' +import { GetAllProductsOperation } from '@commerce/types/product' +import type { OperationContext } from '@commerce/api/operations' +import type { OrdercloudConfig, Provider } from '../index' +import { + PriceSchedule, + RawProduct, + RawProductWithPrice, +} from '@framework/types/product' +import { normalize as normalizeProduct } from '@framework/utils/product' + +export default function getAllProductsOperation({ + commerce, +}: OperationContext) { + async function getAllProducts({ + config, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise<{ products: Product[] }> { + const { fetch } = commerce.getConfig(config) + + const rawProducts: RawProduct[] = await fetch<{ Items: RawProduct[] }>( + 'GET', + '/products' + ).then((response) => response.Items) + const rawProductsWithPrice: RawProductWithPrice[] = await Promise.all( + rawProducts.map(async (product) => ({ + ...product, + priceSchedule: await fetch( + 'GET', + `/priceschedules/${product.ID}` + ), + })) + ) + + return { + products: rawProductsWithPrice.map(normalizeProduct), + } + } + return getAllProducts +} diff --git a/framework/ordercloud/api/operations/get-customer-wishlist.ts b/framework/ordercloud/api/operations/get-customer-wishlist.ts new file mode 100644 index 000000000..8c34b9e87 --- /dev/null +++ b/framework/ordercloud/api/operations/get-customer-wishlist.ts @@ -0,0 +1,6 @@ +export default function getCustomerWishlistOperation() { + function getCustomerWishlist(): any { + return { wishlist: {} } + } + return getCustomerWishlist +} diff --git a/framework/ordercloud/api/operations/get-page.ts b/framework/ordercloud/api/operations/get-page.ts new file mode 100644 index 000000000..b0cfdf58f --- /dev/null +++ b/framework/ordercloud/api/operations/get-page.ts @@ -0,0 +1,13 @@ +export type Page = any +export type GetPageResult = { page?: Page } + +export type PageVariables = { + id: number +} + +export default function getPageOperation() { + function getPage(): Promise { + return Promise.resolve({}) + } + return getPage +} diff --git a/framework/ordercloud/api/operations/get-product.ts b/framework/ordercloud/api/operations/get-product.ts new file mode 100644 index 000000000..3f1dfed21 --- /dev/null +++ b/framework/ordercloud/api/operations/get-product.ts @@ -0,0 +1,26 @@ +import type { OrdercloudConfig } from '../index' +import { Product } from '@commerce/types/product' +import { GetProductOperation } from '@commerce/types/product' +import data from '../../data.json' +import type { OperationContext } from '@commerce/api/operations' + +export default function getProductOperation({ + commerce, +}: OperationContext) { + async function getProduct({ + query = '', + variables, + config, + }: { + query?: string + variables?: T['variables'] + config?: Partial + preview?: boolean + } = {}): Promise { + return { + product: null // data.products.find(({ slug }) => slug === variables!.slug), + } + } + + return getProduct +} diff --git a/framework/ordercloud/api/operations/get-site-info.ts b/framework/ordercloud/api/operations/get-site-info.ts new file mode 100644 index 000000000..abe4defea --- /dev/null +++ b/framework/ordercloud/api/operations/get-site-info.ts @@ -0,0 +1,43 @@ +import { OperationContext } from '@commerce/api/operations' +import { Category } from '@commerce/types/site' +import { OrdercloudConfig } from '../index' + +export type GetSiteInfoResult< + T extends { categories: any[]; brands: any[] } = { + categories: Category[] + brands: any[] + } +> = T + +export default function getSiteInfoOperation({}: OperationContext) { + function getSiteInfo({ + query, + variables, + config: cfg, + }: { + query?: string + variables?: any + config?: Partial + preview?: boolean + } = {}): Promise { + return Promise.resolve({ + categories: [ + { + id: 'new-arrivals', + name: 'New Arrivals', + slug: 'new-arrivals', + path: '/new-arrivals', + }, + { + id: 'featured', + name: 'Featured', + slug: 'featured', + path: '/featured', + }, + ], + brands: [], + }) + } + + return getSiteInfo +} diff --git a/framework/ordercloud/api/operations/index.ts b/framework/ordercloud/api/operations/index.ts new file mode 100644 index 000000000..086fdf83a --- /dev/null +++ b/framework/ordercloud/api/operations/index.ts @@ -0,0 +1,6 @@ +export { default as getPage } from './get-page' +export { default as getSiteInfo } from './get-site-info' +export { default as getAllPages } from './get-all-pages' +export { default as getProduct } from './get-product' +export { default as getAllProducts } from './get-all-products' +export { default as getAllProductPaths } from './get-all-product-paths' diff --git a/framework/ordercloud/api/utils/fetch-rest.ts b/framework/ordercloud/api/utils/fetch-rest.ts new file mode 100644 index 000000000..e6d1403e6 --- /dev/null +++ b/framework/ordercloud/api/utils/fetch-rest.ts @@ -0,0 +1,43 @@ +import { FetcherError } from '@commerce/utils/errors' +import type { OrdercloudConfig } from '../index' +import fetch from './fetch' + +const fetchRestApi: ( + getConfig: () => OrdercloudConfig +) => ( + method: string, + resource: string, + body?: Record, + fetchOptions?: Record +) => Promise = + (getConfig) => + async ( + method: string, + resource: string, + body?: Record, + fetchOptions?: Record + ) => { + const { commerceUrl } = getConfig() + const res = await fetch(`${commerceUrl}${resource}`, { + ...fetchOptions, + method, + headers: { + ...fetchOptions?.headers, + accept: 'application/json, text/plain, */*', + 'accept-language': 'es,en;q=0.9,es-ES;q=0.8,fr;q=0.7', + authorization: 'Bearer ', + }, + body: body ? JSON.stringify(body) : undefined, + }) + + if (!res.ok) { + throw new FetcherError({ + errors: [{ message: res.statusText }], + status: res.status, + }) + } + + return (await res.json()) as T + } + +export default fetchRestApi diff --git a/framework/ordercloud/api/utils/fetch.ts b/framework/ordercloud/api/utils/fetch.ts new file mode 100644 index 000000000..9d9fff3ed --- /dev/null +++ b/framework/ordercloud/api/utils/fetch.ts @@ -0,0 +1,3 @@ +import zeitFetch from '@vercel/fetch' + +export default zeitFetch() diff --git a/framework/ordercloud/auth/index.ts b/framework/ordercloud/auth/index.ts new file mode 100644 index 000000000..36e757a89 --- /dev/null +++ b/framework/ordercloud/auth/index.ts @@ -0,0 +1,3 @@ +export { default as useLogin } from './use-login' +export { default as useLogout } from './use-logout' +export { default as useSignup } from './use-signup' diff --git a/framework/ordercloud/auth/use-login.tsx b/framework/ordercloud/auth/use-login.tsx new file mode 100644 index 000000000..28351dc7f --- /dev/null +++ b/framework/ordercloud/auth/use-login.tsx @@ -0,0 +1,16 @@ +import { MutationHook } from '@commerce/utils/types' +import useLogin, { UseLogin } from '@commerce/auth/use-login' + +export default useLogin as UseLogin + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return null + }, + useHook: () => () => { + return async function () {} + }, +} diff --git a/framework/ordercloud/auth/use-logout.tsx b/framework/ordercloud/auth/use-logout.tsx new file mode 100644 index 000000000..9b3fc3e44 --- /dev/null +++ b/framework/ordercloud/auth/use-logout.tsx @@ -0,0 +1,17 @@ +import { MutationHook } from '@commerce/utils/types' +import useLogout, { UseLogout } from '@commerce/auth/use-logout' + +export default useLogout as UseLogout + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return null + }, + useHook: + ({ fetch }) => + () => + async () => {}, +} diff --git a/framework/ordercloud/auth/use-signup.tsx b/framework/ordercloud/auth/use-signup.tsx new file mode 100644 index 000000000..e9ad13458 --- /dev/null +++ b/framework/ordercloud/auth/use-signup.tsx @@ -0,0 +1,19 @@ +import { useCallback } from 'react' +import useCustomer from '../customer/use-customer' +import { MutationHook } from '@commerce/utils/types' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' + +export default useSignup as UseSignup + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return null + }, + useHook: + ({ fetch }) => + () => + () => {}, +} diff --git a/framework/ordercloud/cart/index.ts b/framework/ordercloud/cart/index.ts new file mode 100644 index 000000000..3b8ba990e --- /dev/null +++ b/framework/ordercloud/cart/index.ts @@ -0,0 +1,4 @@ +export { default as useCart } from './use-cart' +export { default as useAddItem } from './use-add-item' +export { default as useRemoveItem } from './use-remove-item' +export { default as useUpdateItem } from './use-update-item' diff --git a/framework/ordercloud/cart/use-add-item.tsx b/framework/ordercloud/cart/use-add-item.tsx new file mode 100644 index 000000000..7f3d1061f --- /dev/null +++ b/framework/ordercloud/cart/use-add-item.tsx @@ -0,0 +1,17 @@ +import useAddItem, { UseAddItem } from '@commerce/cart/use-add-item' +import { MutationHook } from '@commerce/utils/types' + +export default useAddItem as UseAddItem +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: + ({ fetch }) => + () => { + return async function addItem() { + return {} + } + }, +} diff --git a/framework/ordercloud/cart/use-cart.tsx b/framework/ordercloud/cart/use-cart.tsx new file mode 100644 index 000000000..b3e509a21 --- /dev/null +++ b/framework/ordercloud/cart/use-cart.tsx @@ -0,0 +1,42 @@ +import { useMemo } from 'react' +import { SWRHook } from '@commerce/utils/types' +import useCart, { UseCart } from '@commerce/cart/use-cart' + +export default useCart as UseCart + +export const handler: SWRHook = { + fetchOptions: { + query: '', + }, + async fetcher() { + return { + id: '', + createdAt: '', + currency: { code: '' }, + taxesIncluded: '', + lineItems: [], + lineItemsSubtotalPrice: '', + subtotalPrice: 0, + totalPrice: 0, + } + }, + useHook: + ({ useData }) => + (input) => { + return useMemo( + () => + Object.create( + {}, + { + isEmpty: { + get() { + return true + }, + enumerable: true, + }, + } + ), + [] + ) + }, +} diff --git a/framework/ordercloud/cart/use-remove-item.tsx b/framework/ordercloud/cart/use-remove-item.tsx new file mode 100644 index 000000000..b4ed583b8 --- /dev/null +++ b/framework/ordercloud/cart/use-remove-item.tsx @@ -0,0 +1,18 @@ +import { MutationHook } from '@commerce/utils/types' +import useRemoveItem, { UseRemoveItem } from '@commerce/cart/use-remove-item' + +export default useRemoveItem as UseRemoveItem + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: + ({ fetch }) => + () => { + return async function removeItem(input) { + return {} + } + }, +} diff --git a/framework/ordercloud/cart/use-update-item.tsx b/framework/ordercloud/cart/use-update-item.tsx new file mode 100644 index 000000000..06d703f70 --- /dev/null +++ b/framework/ordercloud/cart/use-update-item.tsx @@ -0,0 +1,18 @@ +import { MutationHook } from '@commerce/utils/types' +import useUpdateItem, { UseUpdateItem } from '@commerce/cart/use-update-item' + +export default useUpdateItem as UseUpdateItem + +export const handler: MutationHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: + ({ fetch }) => + () => { + return async function addItem() { + return {} + } + }, +} diff --git a/framework/ordercloud/commerce.config.json b/framework/ordercloud/commerce.config.json new file mode 100644 index 000000000..9bad66aad --- /dev/null +++ b/framework/ordercloud/commerce.config.json @@ -0,0 +1,9 @@ +{ + "provider": "ordercloud", + "features": { + "wishlist": false, + "cart": false, + "search": false, + "customerAuth": false + } +} diff --git a/framework/ordercloud/customer/index.ts b/framework/ordercloud/customer/index.ts new file mode 100644 index 000000000..6c903ecc5 --- /dev/null +++ b/framework/ordercloud/customer/index.ts @@ -0,0 +1 @@ +export { default as useCustomer } from './use-customer' diff --git a/framework/ordercloud/customer/use-customer.tsx b/framework/ordercloud/customer/use-customer.tsx new file mode 100644 index 000000000..41757cd0d --- /dev/null +++ b/framework/ordercloud/customer/use-customer.tsx @@ -0,0 +1,15 @@ +import { SWRHook } from '@commerce/utils/types' +import useCustomer, { UseCustomer } from '@commerce/customer/use-customer' + +export default useCustomer as UseCustomer +export const handler: SWRHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: () => () => { + return async function addItem() { + return {} + } + }, +} diff --git a/framework/ordercloud/fetcher.ts b/framework/ordercloud/fetcher.ts new file mode 100644 index 000000000..ba6fd5bf7 --- /dev/null +++ b/framework/ordercloud/fetcher.ts @@ -0,0 +1,7 @@ +import { Fetcher } from '@commerce/utils/types' + +export const fetcher: Fetcher = async () => { + throw new Error( + 'Client side fetching has not been implemented yet, try to fetch from server side.' + ) +} diff --git a/framework/ordercloud/index.tsx b/framework/ordercloud/index.tsx new file mode 100644 index 000000000..07258e3c0 --- /dev/null +++ b/framework/ordercloud/index.tsx @@ -0,0 +1,32 @@ +import * as React from 'react' +import { ReactNode } from 'react' +import { ordercloudProvider } from './provider' +import { + CommerceConfig, + CommerceProvider as CoreCommerceProvider, + useCommerce as useCoreCommerce, +} from '@commerce' + +export const ordercloudConfig: CommerceConfig = { + locale: 'en-us', + cartCookie: 'session', +} + +export function CommerceProvider({ + children, + ...config +}: { + children?: ReactNode + locale: string +} & Partial) { + return ( + + {children} + + ) +} + +export const useCommerce = () => useCoreCommerce() diff --git a/framework/ordercloud/next.config.js b/framework/ordercloud/next.config.js new file mode 100644 index 000000000..ce46b706f --- /dev/null +++ b/framework/ordercloud/next.config.js @@ -0,0 +1,8 @@ +const commerce = require('./commerce.config.json') + +module.exports = { + commerce, + images: { + domains: ['localhost'], + }, +} diff --git a/framework/ordercloud/product/index.ts b/framework/ordercloud/product/index.ts new file mode 100644 index 000000000..426a3edcd --- /dev/null +++ b/framework/ordercloud/product/index.ts @@ -0,0 +1,2 @@ +export { default as usePrice } from './use-price' +export { default as useSearch } from './use-search' diff --git a/framework/ordercloud/product/use-price.tsx b/framework/ordercloud/product/use-price.tsx new file mode 100644 index 000000000..0174faf5e --- /dev/null +++ b/framework/ordercloud/product/use-price.tsx @@ -0,0 +1,2 @@ +export * from '@commerce/product/use-price' +export { default } from '@commerce/product/use-price' diff --git a/framework/ordercloud/product/use-search.tsx b/framework/ordercloud/product/use-search.tsx new file mode 100644 index 000000000..30e699537 --- /dev/null +++ b/framework/ordercloud/product/use-search.tsx @@ -0,0 +1,17 @@ +import { SWRHook } from '@commerce/utils/types' +import useSearch, { UseSearch } from '@commerce/product/use-search' +export default useSearch as UseSearch + +export const handler: SWRHook = { + fetchOptions: { + query: '', + }, + async fetcher({ input, options, fetch }) {}, + useHook: () => () => { + return { + data: { + products: [], + }, + } + }, +} diff --git a/framework/ordercloud/provider.ts b/framework/ordercloud/provider.ts new file mode 100644 index 000000000..9b5d267c6 --- /dev/null +++ b/framework/ordercloud/provider.ts @@ -0,0 +1,21 @@ +import { fetcher } from './fetcher' +import { handler as useCart } from './cart/use-cart' +import { handler as useAddItem } from './cart/use-add-item' +import { handler as useUpdateItem } from './cart/use-update-item' +import { handler as useRemoveItem } from './cart/use-remove-item' +import { handler as useCustomer } from './customer/use-customer' +import { handler as useSearch } from './product/use-search' +import { handler as useLogin } from './auth/use-login' +import { handler as useLogout } from './auth/use-logout' +import { handler as useSignup } from './auth/use-signup' + +export type Provider = typeof ordercloudProvider +export const ordercloudProvider = { + locale: 'en-us', + cartCookie: 'session', + fetcher: fetcher, + cart: { useCart, useAddItem, useUpdateItem, useRemoveItem }, + customer: { useCustomer }, + products: { useSearch }, + auth: { useLogin, useLogout, useSignup }, +} diff --git a/framework/ordercloud/types/product.ts b/framework/ordercloud/types/product.ts new file mode 100644 index 000000000..465ef5f53 --- /dev/null +++ b/framework/ordercloud/types/product.ts @@ -0,0 +1,44 @@ +export interface RawProduct { + OwnerID: string + DefaultPriceScheduleID: string | null + AutoForward: boolean + ID: string + Name: string + Description: string + QuantityMultiplier: number + ShipWeight: null + ShipHeight: null + ShipWidth: null + ShipLength: null + Active: boolean + SpecCount: number + VariantCount: number + ShipFromAddressID: null + Inventory: null + DefaultSupplierID: null + AllSuppliersCanSell: boolean + xp: null +} + +export interface RawProductWithPrice extends RawProduct { + priceSchedule: PriceSchedule +} + +export interface PriceSchedule { + OwnerID: string + ID: string + Name: string + ApplyTax: boolean + ApplyShipping: boolean + MinQuantity: number + MaxQuantity: number + UseCumulativeQuantity: boolean + RestrictedQuantity: boolean + PriceBreaks: [ + { + Quantity: number + Price: number + } + ] + xp: null +} diff --git a/framework/ordercloud/utils/product.ts b/framework/ordercloud/utils/product.ts new file mode 100644 index 000000000..125e443d6 --- /dev/null +++ b/framework/ordercloud/utils/product.ts @@ -0,0 +1,17 @@ +import type { RawProductWithPrice } from '@framework/types/product' +import type { Product } from '@commerce/types/product' + +export function normalize(product: RawProductWithPrice): Product { + return { + id: product.ID, + name: product.Name, + description: product.Description, + images: [], + variants: [], + price: { + value: product.priceSchedule.PriceBreaks[0].Price, + currencyCode: 'USD', + }, + options: [], + } +} diff --git a/framework/ordercloud/wishlist/use-add-item.tsx b/framework/ordercloud/wishlist/use-add-item.tsx new file mode 100644 index 000000000..75f067c3a --- /dev/null +++ b/framework/ordercloud/wishlist/use-add-item.tsx @@ -0,0 +1,13 @@ +import { useCallback } from 'react' + +export function emptyHook() { + const useEmptyHook = async (options = {}) => { + return useCallback(async function () { + return Promise.resolve() + }, []) + } + + return useEmptyHook +} + +export default emptyHook diff --git a/framework/ordercloud/wishlist/use-remove-item.tsx b/framework/ordercloud/wishlist/use-remove-item.tsx new file mode 100644 index 000000000..a2d3a8a05 --- /dev/null +++ b/framework/ordercloud/wishlist/use-remove-item.tsx @@ -0,0 +1,17 @@ +import { useCallback } from 'react' + +type Options = { + includeProducts?: boolean +} + +export function emptyHook(options?: Options) { + const useEmptyHook = async ({ id }: { id: string | number }) => { + return useCallback(async function () { + return Promise.resolve() + }, []) + } + + return useEmptyHook +} + +export default emptyHook diff --git a/framework/ordercloud/wishlist/use-wishlist.tsx b/framework/ordercloud/wishlist/use-wishlist.tsx new file mode 100644 index 000000000..9fe0e758f --- /dev/null +++ b/framework/ordercloud/wishlist/use-wishlist.tsx @@ -0,0 +1,43 @@ +import { HookFetcher } from '@commerce/utils/types' +import type { Product } from '@commerce/types/product' + +const defaultOpts = {} + +export type Wishlist = { + items: [ + { + product_id: number + variant_id: number + id: number + product: Product + } + ] +} + +export interface UseWishlistOptions { + includeProducts?: boolean +} + +export interface UseWishlistInput extends UseWishlistOptions { + customerId?: number +} + +export const fetcher: HookFetcher = () => { + return null +} + +export function extendHook( + customFetcher: typeof fetcher, + // swrOptions?: SwrOptions + swrOptions?: any +) { + const useWishlist = ({ includeProducts }: UseWishlistOptions = {}) => { + return { data: null } + } + + useWishlist.extend = extendHook + + return useWishlist +} + +export default extendHook(fetcher) diff --git a/tsconfig.json b/tsconfig.json index 340929669..340dad193 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,8 +23,8 @@ "@components/*": ["components/*"], "@commerce": ["framework/commerce"], "@commerce/*": ["framework/commerce/*"], - "@framework": ["framework/local"], - "@framework/*": ["framework/local/*"] + "@framework": ["framework/ordercloud"], + "@framework/*": ["framework/ordercloud/*"] } }, "include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],