-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add navigation to shopper store context
- Loading branch information
Showing
8 changed files
with
146 additions
and
12 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
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 |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./products" | ||
export * from "./shared" | ||
export * from "./shared" | ||
export * from "./navigation" |
89 changes: 89 additions & 0 deletions
89
packages/shopper-common/src/navigation/build-navigation.ts
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,89 @@ | ||
import type { Hierarchy, Moltin as EPCCClient } from "@moltin/sdk" | ||
import { | ||
getHierarchies, | ||
getHierarchyChildren, | ||
getHierarchyNodes, | ||
} from "./services/hierarchy" | ||
import { ISchema, NavigationNode } from "./navigation-types" | ||
|
||
export async function buildSiteNavigation( | ||
client: EPCCClient, | ||
): Promise<NavigationNode[]> { | ||
// Fetch hierarchies to be used as top level nav | ||
const hierarchies = await getHierarchies(client) | ||
return constructTree(hierarchies, client) | ||
} | ||
|
||
/** | ||
* Construct hierarchy tree, limited to 5 hierarchies at the top level | ||
*/ | ||
function constructTree( | ||
hierarchies: Hierarchy[], | ||
client: EPCCClient, | ||
): Promise<NavigationNode[]> { | ||
const tree = hierarchies | ||
.slice(0, 4) | ||
.map((hierarchy) => | ||
createNode({ | ||
name: hierarchy.attributes.name, | ||
id: hierarchy.id, | ||
slug: hierarchy.attributes.slug, | ||
}), | ||
) | ||
.map(async (hierarchy) => { | ||
// Fetch first-level nav ('parent nodes') - the direct children of each hierarchy | ||
const directChildren = await getHierarchyChildren(hierarchy.id, client) | ||
// Fetch all nodes in each hierarchy (i.e. all 'child nodes' belonging to a hierarchy) | ||
const allNodes = await getHierarchyNodes(hierarchy.id, client) | ||
|
||
// Build 2nd level by finding all 'child nodes' belonging to each first level featured-nodes | ||
const directs = directChildren.slice(0, 4).map((child) => { | ||
const children: ISchema[] = allNodes | ||
.filter((node) => node?.relationships?.parent.data.id === child.id) | ||
.map((node) => | ||
createNode({ | ||
name: node.attributes.name, | ||
id: node.id, | ||
slug: node.attributes.slug, | ||
hrefBase: `${hierarchy.href}/${child.attributes.slug}`, | ||
}), | ||
) | ||
|
||
return createNode({ | ||
name: child.attributes.name, | ||
id: child.id, | ||
slug: child.attributes.slug, | ||
hrefBase: hierarchy.href, | ||
children, | ||
}) | ||
}) | ||
|
||
return { ...hierarchy, children: directs } | ||
}) | ||
|
||
return Promise.all(tree) | ||
} | ||
|
||
interface CreateNodeDefinition { | ||
name: string | ||
id: string | ||
slug?: string | ||
hrefBase?: string | ||
children?: ISchema[] | ||
} | ||
|
||
function createNode({ | ||
name, | ||
id, | ||
slug = "missing-slug", | ||
hrefBase = "", | ||
children = [], | ||
}: CreateNodeDefinition): ISchema { | ||
return { | ||
name, | ||
id, | ||
slug, | ||
href: `${hrefBase}/${slug}`, | ||
children, | ||
} | ||
} |
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,2 @@ | ||
export * from "./build-navigation" | ||
export * from "./navigation-types" |
15 changes: 15 additions & 0 deletions
15
packages/shopper-common/src/navigation/navigation-types.ts
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,15 @@ | ||
export interface ISchema { | ||
name: string | ||
slug: string | ||
href: string | ||
id: string | ||
children: ISchema[] | ||
} | ||
|
||
export interface NavigationNode { | ||
name: string | ||
slug: string | ||
href: string | ||
id: string | ||
children: NavigationNode[] | ||
} |
28 changes: 28 additions & 0 deletions
28
packages/shopper-common/src/navigation/services/hierarchy.ts
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,28 @@ | ||
import type { Node, Hierarchy } from "@moltin/sdk" | ||
import { Moltin as EPCCClient } from "@moltin/sdk" | ||
|
||
export async function getHierarchies(client: EPCCClient): Promise<Hierarchy[]> { | ||
const result = await client.ShopperCatalog.Hierarchies.All() | ||
return result.data | ||
} | ||
|
||
export async function getHierarchyChildren( | ||
hierarchyId: string, | ||
client: EPCCClient, | ||
): Promise<Node[]> { | ||
const result = await client.ShopperCatalog.Hierarchies.GetHierarchyChildren({ | ||
hierarchyId, | ||
}) | ||
return result.data | ||
} | ||
|
||
export async function getHierarchyNodes( | ||
hierarchyId: string, | ||
client: EPCCClient, | ||
): Promise<Node[]> { | ||
const result = await client.ShopperCatalog.Hierarchies.GetHierarchyNodes({ | ||
hierarchyId, | ||
}) | ||
|
||
return result.data | ||
} |