-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
259 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import components from '#config/components' | ||
import CommerceLayerContext from '#context/CommerceLayerContext' | ||
import SkuContext from '#context/SkuContext' | ||
import skuReducer, { getSku, skuInitialState } from '#reducers/SkuReducer' | ||
import { QueryParamsList } from '@commercelayer/sdk' | ||
import { ReactNode, useContext, useEffect, useMemo, useReducer } from 'react' | ||
|
||
type Props = { | ||
skus: string[] | ||
children: ReactNode | ||
queryParams?: QueryParamsList | ||
} | ||
|
||
export default function SkuContainer<P extends Props>(props: P): JSX.Element { | ||
const { skus, children, queryParams } = props | ||
const [state, dispatch] = useReducer(skuReducer, skuInitialState) | ||
const config = useContext(CommerceLayerContext) | ||
const loadSkus = async () => | ||
await getSku({ config, dispatch, skus, queryParams }) | ||
useEffect(() => { | ||
if (config.accessToken && state?.skus) { | ||
if (state?.skus.length === 0) { | ||
loadSkus() | ||
} | ||
} | ||
return () => { | ||
dispatch({ | ||
type: 'setLoading', | ||
payload: { | ||
loading: true, | ||
}, | ||
}) | ||
} | ||
}, [config, skus]) | ||
const contextValue = useMemo(() => state, [state]) | ||
return ( | ||
<SkuContext.Provider value={contextValue}>{children}</SkuContext.Provider> | ||
) | ||
} | ||
|
||
SkuContainer.propTypes = components.SkuContainer.propTypes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { Sku } from '@commercelayer/sdk' | ||
import SkuChildrenContext from '#context/SkuChildrenContext' | ||
import { useContext } from 'react' | ||
import Parent from './utils/Parent' | ||
import components from '#config/components' | ||
|
||
type ExcludeTag<T extends keyof JSX.IntrinsicElements> = Exclude< | ||
keyof JSX.IntrinsicElements, | ||
T | ||
> | ||
|
||
type Conditional = | ||
| ({ | ||
attribute: 'image_url' | ||
tagElement: 'img' | ||
} & JSX.IntrinsicElements['img']) | ||
| ({ | ||
attribute: Exclude<keyof Sku, 'image_url'> | ||
tagElement: ExcludeTag<'img'> | ||
} & JSX.IntrinsicElements[ExcludeTag<'img'>]) | ||
|
||
type ChildrenProps = Omit<Props, 'children' | 'attribute'> & { | ||
element: Sku[keyof Sku] | ||
} | ||
|
||
type Props = { | ||
children?: (props: ChildrenProps) => JSX.Element | ||
} & Conditional | ||
|
||
export default function SkuField<P extends Props>({ | ||
attribute, | ||
tagElement, | ||
children, | ||
...p | ||
}: P): JSX.Element { | ||
const { sku } = useContext(SkuChildrenContext) | ||
const element = (sku && sku[attribute]) || '' | ||
const Tag = tagElement | ||
if (Tag === 'img') { | ||
const src = element as string | ||
const name = sku?.name | ||
return <img alt={name} src={src} {...(p as JSX.IntrinsicElements['img'])} /> | ||
} | ||
const parentProps = { | ||
element, | ||
tagElement, | ||
...p, | ||
} | ||
return children ? ( | ||
<Parent {...parentProps}>{children}</Parent> | ||
) : ( | ||
<Tag>{element}</Tag> | ||
) | ||
} | ||
|
||
SkuField.propTypes = components.SkuField.propTypes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import components from '#config/components' | ||
import SkuChildrenContext from '#context/SkuChildrenContext' | ||
import SkuContext from '#context/SkuContext' | ||
import { ReactNode, useContext } from 'react' | ||
|
||
type Props = { | ||
children: ReactNode | ||
} | ||
|
||
export default function Skus<P extends Props>({ children }: P): JSX.Element { | ||
const { skus } = useContext(SkuContext) | ||
const components = | ||
skus && | ||
skus.map((sku, key) => { | ||
const value = { sku } | ||
return ( | ||
<SkuChildrenContext.Provider key={key} value={value}> | ||
{children} | ||
</SkuChildrenContext.Provider> | ||
) | ||
}) | ||
return <>{components}</> | ||
} | ||
|
||
Skus.propTypes = components.Skus.propTypes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { createContext } from 'react' | ||
import { Sku } from '@commercelayer/sdk' | ||
|
||
export type InitialSkuContext = Partial<{ | ||
sku: Sku | ||
}> | ||
|
||
const initial: InitialSkuContext = {} | ||
|
||
const SkuChildrenContext = createContext<InitialSkuContext>(initial) | ||
|
||
export default SkuChildrenContext |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { SkuState } from '#reducers/SkuReducer' | ||
import { createContext } from 'react' | ||
|
||
export type SkuContextValue = SkuState | ||
|
||
const SkuContext = createContext<SkuContextValue>({}) | ||
|
||
export default SkuContext |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import baseReducer from '#utils/baseReducer' | ||
import { CommerceLayerConfig } from '#context/CommerceLayerContext' | ||
import getSdk from '#utils/getSdk' | ||
import { BaseAction } from '#typings' | ||
import { QueryParamsList, Sku } from '@commercelayer/sdk' | ||
import { Dispatch } from 'react' | ||
|
||
type SkuActionType = 'getSkus' | 'setLoading' | ||
type SkuAction = BaseAction<SkuActionType, SkuState> | ||
export type SkuState = Partial<{ | ||
skus: Sku[] | ||
loading: boolean | ||
}> | ||
|
||
const actionType: SkuActionType[] = ['getSkus'] | ||
|
||
export const skuInitialState: SkuState = { | ||
skus: [], | ||
loading: true, | ||
} | ||
|
||
type GetSku = { | ||
config: CommerceLayerConfig | ||
skus: string[] | ||
dispatch: Dispatch<SkuAction> | ||
queryParams?: QueryParamsList | ||
} | ||
|
||
export async function getSku<T extends GetSku>({ | ||
config, | ||
skus, | ||
dispatch, | ||
queryParams, | ||
}: T): Promise<void> { | ||
if (!config.accessToken) return | ||
if (skus.length === 0) return | ||
const sdk = getSdk(config) | ||
let allSkus: Sku[] = [] | ||
const get = await sdk.skus.list({ | ||
...queryParams, | ||
filters: { ...queryParams?.filters, code_in: skus.join(',') }, | ||
}) | ||
allSkus = [...get] | ||
const meta = get.meta | ||
if (meta.pageCount > 1) { | ||
for ( | ||
let pageNumber = meta.currentPage + 1; | ||
pageNumber <= meta.pageCount; | ||
pageNumber++ | ||
) { | ||
const getPage = await sdk.skus.list({ | ||
...queryParams, | ||
filters: { ...queryParams?.filters, code_in: skus.join(',') }, | ||
pageNumber, | ||
}) | ||
allSkus = [...allSkus, ...getPage] | ||
} | ||
} | ||
dispatch({ | ||
type: 'getSkus', | ||
payload: { | ||
skus: allSkus, | ||
loading: false, | ||
}, | ||
}) | ||
} | ||
|
||
export default function skuReducer( | ||
state: SkuState, | ||
reducer: SkuAction | ||
): SkuState { | ||
return baseReducer<SkuState, SkuAction, SkuActionType[]>( | ||
state, | ||
reducer, | ||
actionType | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters