Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example: API Extensions + Section Override v2 #199

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
28 changes: 16 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,29 @@
"dev": "faststore dev",
"build": "faststore build",
"start": "faststore start",
"cms-sync": "faststore cms-sync"
"cms-sync": "faststore cms-sync",
"test": "faststore test"
},
"dependencies": {
"@faststore/core": "^2.1.93",
"next": "^12.3.1",
"@faststore/core": "3.0.61",
"next": "^13.5.6",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@cypress/code-coverage": "^3.9.10",
"@faststore/cli": "2.1.79",
"@faststore/lighthouse": "^2.1.31",
"@cypress/code-coverage": "^3.12.1",
"@faststore/cli": "3.0.54",
"@faststore/lighthouse": "^3.0.54",
"@lhci/cli": "^0.9.0",
"@testing-library/cypress": "^8.0.0",
"@types/cypress": "^1.1.3",
"cypress": "9.6.0",
"cypress-axe": "^0.13.0",
"cypress-wait-until": "^1.7.2",
"@testing-library/cypress": "^10.0.1",
"cypress": "12.17.4",
"cypress-axe": "^1.5.0",
"cypress-wait-until": "^2.0.1",
"typescript": "^4.9.4"
},
"volta": {
"node": "18.19.0",
"yarn": "1.19.1"
},
"author": "VTEX"
}
}
19 changes: 19 additions & 0 deletions src/components/CallToAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { usePLP } from "@faststore/core";

export interface CallToActionProps {
title: string;
link: {
text: string;
url: string;
};
}

export default function CallToAction(props: CallToActionProps) {
const context = usePLP();
console.log("🚀 ~ context:", context);
return (
<section>
<h2>{`${props.title} ${context?.data?.namedExtraData?.data}`}</h2>
</section>
);
}
18 changes: 18 additions & 0 deletions src/components/CustomBuyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Button as UIButton } from "@faststore/ui";
import { usePDP } from "@faststore/core";

export function CustomBuyButton(_) {
const context = usePDP();
console.log("🚀 ~ CustomBuyButton context:", context);

return (
<UIButton
variant="primary"
onClick={() => {
alert("Hello User!");
}}
>
{context?.data?.product.customData}
</UIButton>
);
}
52 changes: 52 additions & 0 deletions src/components/CustomShippingSimulation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ShippingSimulation } from "@faststore/ui";
import { useShippingSimulation_unstable } from "@faststore/core/experimental";

export function CustomShippingSimulation(props: any) {
const {
productShippingInfo,
formatter,
inputLabel,
title,
idkPostalCodeLinkProps,
...otherProps
} = props;

const {
input,
shippingSimulation,
handleSubmit,
handleOnInput,
handleOnClear,
} = useShippingSimulation_unstable(productShippingInfo);

const { postalCode, displayClearButton, errorMessage } = input;

const location =
[
shippingSimulation?.address?.neighborhood,
shippingSimulation?.address?.city,
]
.filter(Boolean)
.join(" / ") ?? "";

const options = shippingSimulation?.logisticsInfo?.[0]?.slas ?? [];

return (
<ShippingSimulation
formatter={formatter}
onInput={handleOnInput}
onSubmit={handleSubmit}
onClear={handleOnClear}
location={`${location}, ${shippingSimulation?.address?.state}`}
options={options}
address={shippingSimulation?.address}
displayClearButton={displayClearButton}
errorMessage={errorMessage}
postalCode={postalCode}
inputLabel={inputLabel}
title={title}
idkPostalCodeLinkProps={idkPostalCodeLinkProps}
{...otherProps}
/>
);
}
3 changes: 3 additions & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CallToAction from './CallToAction'

export default { CallToAction }
15 changes: 15 additions & 0 deletions src/components/overrides/ProductDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { SectionOverride } from "@faststore/core/src/typings/overrides";
import { CustomBuyButton } from "../CustomBuyButton";
import { CustomShippingSimulation } from "../CustomShippingSimulation";

const SECTION = "ProductDetails" as const;

const override: SectionOverride = {
section: SECTION,
components: {
BuyButton: { Component: CustomBuyButton },
__experimentalShippingSimulation: { Component: CustomShippingSimulation },
},
};

export { override };
29 changes: 29 additions & 0 deletions src/fragments/ClientManyProducts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ClientManyProducts on Query {
search(
first: $first
after: $after
sort: $sort
term: $term
selectedFacets: $selectedFacets
) {
products {
pageInfo {
totalCount
}
edges {
node {
customData
skuVariations {
itemId
name
image
}
}
}
}
}
}
`);
14 changes: 14 additions & 0 deletions src/fragments/ClientProduct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ClientProduct on Query {
product(locator: $locator) {
customData
skuVariations {
itemId
name
image
}
}
}
`);
19 changes: 19 additions & 0 deletions src/fragments/ClientProductGallery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ClientProductGallery on Query {
search(
first: $first
after: $after
sort: $sort
term: $term
selectedFacets: $selectedFacets
) {
products {
pageInfo {
totalCount
}
}
}
}
`);
13 changes: 13 additions & 0 deletions src/fragments/ClientSearchSuggestions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ClientSearchSuggestions on Query {
search(first: 5, term: $term, selectedFacets: $selectedFacets) {
suggestions {
terms {
value
}
}
}
}
`);
13 changes: 13 additions & 0 deletions src/fragments/ClientShippingSimulation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ClientShippingSimulation on Query {
shipping(items: $items, postalCode: $postalCode, country: $country) {
address {
city
state
number
}
}
}
`);
13 changes: 13 additions & 0 deletions src/fragments/ClientTopSearchSuggestions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ClientTopSearchSuggestions on Query {
search(first: 5, term: $term, selectedFacets: $selectedFacets) {
suggestions {
terms {
value
}
}
}
}
`);
15 changes: 15 additions & 0 deletions src/fragments/ServerCollectionPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ServerCollectionPage on Query {
extraData {
data
}
namedExtraData(name: "Hello") {
data
}
collection(slug: $slug) {
id
}
}
`);
20 changes: 20 additions & 0 deletions src/fragments/ServerProduct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { gql } from "@faststore/core/api";

export const fragment = gql(`
fragment ServerProduct on Query {
extraData {
data
}
namedExtraData(name: "Hello") {
data
}
product(locator: $locator) {
customData
skuVariations {
itemId
name
image
}
}
}
`);
15 changes: 15 additions & 0 deletions src/graphql/thirdParty/resolvers/extra.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const extraDataResolver = {
Query: {
extraData: () => {
return {
data: 'Extra data',
}
},
namedExtraData: (_, { name }) => {
return {
data: `Named extra data: ${name}`,
}
},
},
}
export default extraDataResolver
7 changes: 7 additions & 0 deletions src/graphql/thirdParty/resolvers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import extraDataResolver from './extra'

const resolvers = {
...extraDataResolver,
}

export default resolvers
11 changes: 11 additions & 0 deletions src/graphql/thirdParty/typeDefs/extra.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type ExtraData {
"""
Data customizing ExtraData
"""
data: String!
}

type Query {
extraData: ExtraData
namedExtraData(name: String!): ExtraData
}
7 changes: 7 additions & 0 deletions src/graphql/vtex/resolvers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { default as StoreProductResolver } from './product'

const resolvers = {
...StoreProductResolver,
}

export default resolvers
41 changes: 41 additions & 0 deletions src/graphql/vtex/resolvers/product.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { StoreProductRoot } from "@faststore/core/api"

const productResolver = {
StoreProduct: {
customData: (root: StoreProductRoot) => {
return "My item id: " + root.itemId
},
skuVariations: (root: StoreProductRoot) => {

const extractImage = (item: any) => {
return item.images.length > 0
? item.images[0].imageUrl
: "default-image.jpg"
}

const uniqueItemIds = new Set<string>()

const transformItem = (item: any) => {
if (!uniqueItemIds.has(item.itemId)) {
uniqueItemIds.add(item.itemId)
return {
itemId: item.itemId,
name: item.name,
image: extractImage(item),
}
}
return null
}

const itemDetails = [
transformItem(root),
...root.isVariantOf.items.map(transformItem),
].filter((item) => item !== null)

Check warning on line 33 in src/graphql/vtex/resolvers/product.ts

View check run for this annotation

VTEX Sites / SonarQube

src/graphql/vtex/resolvers/product.ts#L30-L33

Immediately return this expression instead of assigning it to the temporary variable "itemDetails".


return itemDetails
},
},
}

export default productResolver
Loading