@faststore/core 3.97.0 → 3.97.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +24 -24
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/server-production/0.pack +0 -0
  8. package/.next/cache/webpack/server-production/index.pack +0 -0
  9. package/.next/prerender-manifest.js +1 -1
  10. package/.next/prerender-manifest.json +1 -1
  11. package/.next/react-loadable-manifest.json +1 -1
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/2445.js +12 -1
  14. package/.next/server/chunks/3890.js +492 -0
  15. package/.next/server/chunks/3951.js +7 -0
  16. package/.next/server/chunks/4365.js +1 -1
  17. package/.next/server/chunks/870.js +1 -1
  18. package/.next/server/chunks/9563.js +2 -2
  19. package/.next/server/middleware-build-manifest.js +1 -1
  20. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  21. package/.next/server/pages/404.js +1 -1
  22. package/.next/server/pages/404.js.nft.json +1 -1
  23. package/.next/server/pages/500.js +1 -1
  24. package/.next/server/pages/500.js.nft.json +1 -1
  25. package/.next/server/pages/[...slug].js +1 -1
  26. package/.next/server/pages/[...slug].js.nft.json +1 -1
  27. package/.next/server/pages/[slug]/p.js +1 -1
  28. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  29. package/.next/server/pages/_app.js +1 -1
  30. package/.next/server/pages/_app.js.nft.json +1 -1
  31. package/.next/server/pages/_document.js +1 -1
  32. package/.next/server/pages/_document.js.nft.json +1 -1
  33. package/.next/server/pages/_error.js +1 -1
  34. package/.next/server/pages/_error.js.nft.json +1 -1
  35. package/.next/server/pages/api/fs/logout.js.nft.json +1 -1
  36. package/.next/server/pages/api/graphql.js +3 -3
  37. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  38. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  39. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  40. package/.next/server/pages/api/preview.js +1 -1
  41. package/.next/server/pages/api/preview.js.nft.json +1 -1
  42. package/.next/server/pages/checkout.js +1 -1
  43. package/.next/server/pages/checkout.js.nft.json +1 -1
  44. package/.next/server/pages/en-US/404.html +28 -13
  45. package/.next/server/pages/en-US/500.html +28 -13
  46. package/.next/server/pages/en-US/checkout.html +28 -13
  47. package/.next/server/pages/en-US/login.html +28 -13
  48. package/.next/server/pages/en-US/s.html +28 -13
  49. package/.next/server/pages/en-US.html +28 -13
  50. package/.next/server/pages/index.js +1 -1
  51. package/.next/server/pages/index.js.nft.json +1 -1
  52. package/.next/server/pages/login.js +1 -1
  53. package/.next/server/pages/login.js.nft.json +1 -1
  54. package/.next/server/pages/pvt/account/403.js +1 -1
  55. package/.next/server/pages/pvt/account/403.js.nft.json +1 -1
  56. package/.next/server/pages/pvt/account/404.js +1 -1
  57. package/.next/server/pages/pvt/account/404.js.nft.json +1 -1
  58. package/.next/server/pages/pvt/account/[...unknown].js +1 -1
  59. package/.next/server/pages/pvt/account/[...unknown].js.nft.json +1 -1
  60. package/.next/server/pages/pvt/account/orders/[id].js +1 -1
  61. package/.next/server/pages/pvt/account/orders/[id].js.nft.json +1 -1
  62. package/.next/server/pages/pvt/account/orders.js +1 -1
  63. package/.next/server/pages/pvt/account/orders.js.nft.json +1 -1
  64. package/.next/server/pages/pvt/account/profile.js +1 -1
  65. package/.next/server/pages/pvt/account/profile.js.nft.json +1 -1
  66. package/.next/server/pages/pvt/account/security.js +1 -1
  67. package/.next/server/pages/pvt/account/security.js.nft.json +1 -1
  68. package/.next/server/pages/pvt/account/user-details.js +1 -1
  69. package/.next/server/pages/pvt/account/user-details.js.nft.json +1 -1
  70. package/.next/server/pages/pvt/account.js +1 -1
  71. package/.next/server/pages/pvt/account.js.nft.json +1 -1
  72. package/.next/server/pages/s.js +1 -1
  73. package/.next/server/pages/s.js.nft.json +1 -1
  74. package/.next/server/pages-manifest.json +1 -1
  75. package/.next/static/{wEDc4gCW_Kv0gEGlYKana → DAJIfXczlTKGDp0c66INm}/_buildManifest.js +1 -1
  76. package/.next/static/chunks/7692.8d5bf4560341a2f6.js +1 -0
  77. package/.next/static/chunks/941.3e2782ab9c490eb0.js +1 -0
  78. package/.next/static/chunks/CartSidebar.f0c16e2bc6f96e9e.js +1 -0
  79. package/.next/static/chunks/pages/_app-1595678557980d65.js +1 -0
  80. package/.next/static/chunks/pages/pvt/account/orders/[id]-e03ebb0393ac92a2.js +1 -0
  81. package/.next/static/chunks/webpack-f3fde0e8298ce999.js +1 -0
  82. package/.next/static/css/{5eecefd2c6deeee4.css → 08d03445f1797608.css} +1 -1
  83. package/.next/trace +140 -139
  84. package/.turbo/turbo-build.log +26 -26
  85. package/.turbo/turbo-test.log +6 -7
  86. package/@generated/gql.ts +2 -2
  87. package/@generated/graphql.ts +54 -1
  88. package/@generated/persisted-documents.json +1 -1
  89. package/@generated/schema.graphql +41 -0
  90. package/CHANGELOG.md +32 -0
  91. package/discovery.config.default.js +1 -0
  92. package/package.json +4 -4
  93. package/src/Layout.tsx +2 -2
  94. package/src/components/ThirdPartyScripts/GoogleTagManager.tsx +19 -10
  95. package/src/components/ThirdPartyScripts/ThirdPartyScripts.tsx +1 -22
  96. package/src/components/ThirdPartyScripts/vtex.tsx +6 -1
  97. package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/MyAccountBudgetsCard.tsx +119 -0
  98. package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/index.ts +1 -0
  99. package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/styles.scss +129 -0
  100. package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActions/MyAccountOrderActions.tsx +19 -6
  101. package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActions/styles.scss +10 -0
  102. package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderDetails.tsx +18 -5
  103. package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/MyAccountReorderButton.tsx +37 -0
  104. package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/index.ts +2 -0
  105. package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/styles.scss +10 -0
  106. package/src/components/account/orders/MyAccountOrderDetails/section.module.scss +46 -17
  107. package/src/constants.ts +2 -0
  108. package/src/pages/_document.tsx +40 -0
  109. package/src/pages/api/preview.ts +4 -4
  110. package/src/pages/pvt/account/orders/[id].tsx +19 -1
  111. package/src/sdk/account/useReorder.ts +148 -0
  112. package/src/sdk/analytics/hooks/usePageViewEvent.ts +7 -2
  113. package/src/sdk/analytics/platform/vtex/search.ts +22 -8
  114. package/src/sdk/cart/redirectToCheckout.ts +15 -0
  115. package/src/sdk/cart/useCheckoutButton.ts +2 -9
  116. package/src/sdk/error/ReorderError/ReorderError.ts +6 -0
  117. package/.next/server/chunks/4168.js +0 -1
  118. package/.next/server/chunks/9630.js +0 -495
  119. package/.next/static/chunks/7692.a352cce6d744fa8b.js +0 -1
  120. package/.next/static/chunks/941.417f354fd61bae91.js +0 -1
  121. package/.next/static/chunks/CartSidebar.3342e22b115732a3.js +0 -1
  122. package/.next/static/chunks/pages/_app-dbee0add24c249fe.js +0 -1
  123. package/.next/static/chunks/pages/pvt/account/orders/[id]-dc662a778c5b8876.js +0 -1
  124. package/.next/static/chunks/webpack-c6f7dbc72e738310.js +0 -1
  125. /package/.next/static/{wEDc4gCW_Kv0gEGlYKana → DAJIfXczlTKGDp0c66INm}/_ssgManifest.js +0 -0
@@ -0,0 +1,148 @@
1
+ import { useState } from 'react'
2
+ import type { ServerOrderDetailsQueryQuery } from '@generated/graphql'
3
+ import { cartStore, ValidateCartMutation } from '../cart'
4
+ import type {
5
+ IStoreOffer,
6
+ ValidateCartMutationMutation,
7
+ ValidateCartMutationMutationVariables,
8
+ CartItemFragment,
9
+ IStoreCart,
10
+ } from '@generated/graphql'
11
+ import { request } from '../graphql/request'
12
+ import { sessionStore } from '../session'
13
+ import { redirectToCheckout } from '../cart/redirectToCheckout'
14
+ import ReorderError from '../error/ReorderError/ReorderError'
15
+
16
+ type Order = ServerOrderDetailsQueryQuery['userOrder']
17
+ type AdditionalProperties =
18
+ CartItemFragment['itemOffered']['additionalProperty']
19
+
20
+ const getItemId = (item: CartItemFragment) => {
21
+ const propertyIds =
22
+ item.itemOffered.additionalProperty
23
+ ?.map((prop) => prop.propertyID)
24
+ .join('-') ?? ''
25
+
26
+ const sellerId = item.seller?.identifier ?? ''
27
+
28
+ return [item.itemOffered.sku, sellerId, propertyIds]
29
+ .filter(Boolean)
30
+ .join('::')
31
+ }
32
+
33
+ export const useReorder = () => {
34
+ const [loading, setLoading] = useState(false)
35
+ const [error, setError] = useState<Error | null>(null)
36
+
37
+ const reorder = async (order: Order | null | undefined) => {
38
+ if (!order) {
39
+ const err = new ReorderError('Order not found')
40
+ setError(err)
41
+ return
42
+ }
43
+
44
+ const deliveryOptions = order.deliveryOptionsData?.deliveryOptions ?? []
45
+ const orderItemsWithSeller =
46
+ deliveryOptions.flatMap((option) =>
47
+ (option?.items ?? []).map((item) => ({
48
+ ...item,
49
+ seller: option?.seller,
50
+ }))
51
+ ) ?? []
52
+
53
+ if (!orderItemsWithSeller || orderItemsWithSeller.length === 0) {
54
+ const err = new ReorderError('No items found in order')
55
+ setError(err)
56
+ return
57
+ }
58
+
59
+ setLoading(true)
60
+ setError(null)
61
+
62
+ try {
63
+ const currentCart = cartStore.read()
64
+
65
+ const acceptedOffer: IStoreOffer[] = orderItemsWithSeller
66
+ .filter(
67
+ (item) =>
68
+ item && item.id && item.quantity && item.seller && item.quantity > 0
69
+ )
70
+ .map((item) => ({
71
+ quantity: item.quantity,
72
+ seller: {
73
+ identifier: item.seller,
74
+ },
75
+ price: item.price ?? 0,
76
+ listPrice: item.price ?? 0,
77
+ itemOffered: {
78
+ sku: item.id ?? '',
79
+ image: item.imageUrl
80
+ ? [
81
+ {
82
+ url: item.imageUrl,
83
+ alternateName: item.name ?? '',
84
+ },
85
+ ]
86
+ : [],
87
+ name: item.name ?? '',
88
+ additionalProperty: [] as AdditionalProperties,
89
+ },
90
+ }))
91
+
92
+ if (acceptedOffer.length === 0) {
93
+ throw new ReorderError('No valid items to reorder')
94
+ }
95
+
96
+ const orderPayload: Partial<IStoreCart['order']> & {
97
+ acceptedOffer: IStoreCart['order']['acceptedOffer']
98
+ shouldSplitItem?: IStoreCart['order']['shouldSplitItem']
99
+ } = {
100
+ acceptedOffer,
101
+ shouldSplitItem: false,
102
+ }
103
+
104
+ if (currentCart.id) {
105
+ orderPayload.orderNumber = currentCart.id
106
+ }
107
+
108
+ const { validateCart: validated } = await request<
109
+ ValidateCartMutationMutation,
110
+ ValidateCartMutationMutationVariables
111
+ >(ValidateCartMutation, {
112
+ session: sessionStore.read(),
113
+ cart: {
114
+ order: orderPayload as IStoreCart['order'],
115
+ },
116
+ })
117
+
118
+ if (!validated) {
119
+ throw new ReorderError('Failed to add items to cart')
120
+ }
121
+
122
+ const updatedCart = {
123
+ id: validated.order.orderNumber,
124
+ items: validated.order.acceptedOffer.map((item) => ({
125
+ ...item,
126
+ id: getItemId(item),
127
+ })),
128
+ messages: validated.messages,
129
+ shouldSplitItem: validated.order.shouldSplitItem,
130
+ }
131
+
132
+ cartStore.set(updatedCart)
133
+
134
+ redirectToCheckout(validated.order.orderNumber)
135
+ } catch (err) {
136
+ setError(err instanceof Error ? err : new ReorderError('Unknown error'))
137
+ console.error('Error reordering:', err)
138
+ } finally {
139
+ setLoading(false)
140
+ }
141
+ }
142
+
143
+ return {
144
+ reorder,
145
+ loading,
146
+ error,
147
+ }
148
+ }
@@ -1,6 +1,6 @@
1
1
  import type { PageViewEvent } from '@faststore/sdk'
2
2
  import { useRouter } from 'next/router'
3
- import { useCallback, useEffect } from 'react'
3
+ import { useCallback, useEffect, useRef } from 'react'
4
4
 
5
5
  export const usePageViewEvent = (props?: any) => {
6
6
  const sendPageViewEvent = useCallback(() => {
@@ -18,10 +18,15 @@ export const usePageViewEvent = (props?: any) => {
18
18
  }, [props])
19
19
 
20
20
  const router = useRouter()
21
+ const lastPathRef = useRef<string | null>(null)
21
22
 
22
23
  useEffect(() => {
24
+ if (lastPathRef.current === router.asPath) {
25
+ return
26
+ }
27
+ lastPathRef.current = router.asPath
23
28
  sendPageViewEvent()
24
- }, [router.pathname, sendPageViewEvent])
29
+ }, [router.asPath, sendPageViewEvent])
25
30
 
26
31
  return { sendPageViewEvent }
27
32
  }
@@ -4,6 +4,7 @@
4
4
  import type { AnalyticsEvent } from '@faststore/sdk'
5
5
  import type { SearchEvents } from '../../types'
6
6
 
7
+ import { LOG_LABEL_STYLE } from 'src/constants'
7
8
  import { getBaseDomain } from 'src/utils/getBaseDomain'
8
9
  import { getCookie } from 'src/utils/getCookie'
9
10
  import config from '../../../../../discovery.config'
@@ -11,6 +12,7 @@ import config from '../../../../../discovery.config'
11
12
  const THIRTY_MINUTES_S = 30 * 60
12
13
  const ONE_YEAR_S = 365 * 24 * 3600
13
14
 
15
+ const enableScriptsLogs = config.experimental?.enableScriptsLogs === true
14
16
  const randomUUID = () =>
15
17
  typeof crypto.randomUUID === 'function'
16
18
  ? crypto.randomUUID().replaceAll('-', '')
@@ -83,19 +85,31 @@ type SearchEvent =
83
85
  type: 'search.autocomplete.click'
84
86
  }
85
87
 
86
- const sendEvent = (options: SearchEvent & { url?: string }) =>
87
- fetch(`https://sp.vtex.com/event-api/v1/${config.api.storeId}/event`, {
88
+ const sendEvent = (options: SearchEvent & { url?: string }) => {
89
+ const payload = {
90
+ ...options,
91
+ userAgent: navigator.userAgent,
92
+ anonymous: user.anonymous(),
93
+ session: user.session(),
94
+ }
95
+
96
+ if (enableScriptsLogs) {
97
+ console.debug(
98
+ '%cvtex%c Search Event',
99
+ LOG_LABEL_STYLE,
100
+ 'color:inherit',
101
+ payload
102
+ )
103
+ }
104
+
105
+ return fetch(`https://sp.vtex.com/event-api/v1/${config.api.storeId}/event`, {
88
106
  method: 'POST',
89
- body: JSON.stringify({
90
- ...options,
91
- userAgent: navigator.userAgent,
92
- anonymous: user.anonymous(),
93
- session: user.session(),
94
- }),
107
+ body: JSON.stringify(payload),
95
108
  headers: {
96
109
  'content-type': 'application/json',
97
110
  },
98
111
  })
112
+ }
99
113
 
100
114
  const isFullTextSearch = (url: URL) =>
101
115
  typeof url.searchParams.get('q') === 'string' &&
@@ -0,0 +1,15 @@
1
+ import storeConfig from '../../../discovery.config'
2
+
3
+ export const redirectToCheckout = (orderFormId?: string) => {
4
+ const isDevEnv =
5
+ window.location.host.includes('.vtex.app') ||
6
+ window.location.host.includes('localhost')
7
+
8
+ if (!isDevEnv) {
9
+ window.location.href = `${storeConfig.checkoutUrl}`
10
+ } else if (orderFormId) {
11
+ window.location.href = `${storeConfig.checkoutUrl}?orderFormId=${orderFormId}`
12
+ } else {
13
+ window.location.href = `${storeConfig.checkoutUrl}`
14
+ }
15
+ }
@@ -1,21 +1,14 @@
1
- import storeConfig from '../../../discovery.config'
2
1
  import { useCart } from './index'
2
+ import { redirectToCheckout } from './redirectToCheckout'
3
3
 
4
4
  export const useCheckoutButton = () => {
5
5
  const { isValidating, id } = useCart()
6
6
 
7
7
  const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
8
8
  e.preventDefault()
9
- const isDevEnv =
10
- window.location.host.includes('.vtex.app') ||
11
- window.location.host.includes('localhost')
12
9
 
13
10
  if (!isValidating) {
14
- if (!isDevEnv) {
15
- window.location.href = `${storeConfig.checkoutUrl}`
16
- } else if (id) {
17
- window.location.href = `${storeConfig.checkoutUrl}?orderFormId=${id}`
18
- }
11
+ redirectToCheckout(id)
19
12
  }
20
13
  }
21
14
 
@@ -0,0 +1,6 @@
1
+ export default class ReorderError extends Error {
2
+ constructor(message: string) {
3
+ super(message)
4
+ this.name = 'ReorderError'
5
+ }
6
+ }
@@ -1 +0,0 @@
1
- exports.id=4168,exports.ids=[4168],exports.modules={38038:e=>{e.exports={seo:{title:"FastStore Starter",description:"Fast Demo Store",titleTemplate:"%s | FastStore",author:"Store Framework",name:"FastStore",publisherId:"",plp:{titleTemplate:"%s | FastStore PLP",descriptionTemplate:"%s products on FastStore Product Listing Page"},pdp:{titleTemplate:"%s | FastStore PDP",descriptionTemplate:"%s products on FastStore Product Detail Page",minPriceAmountFractionDigits:void 0},search:{titleTemplate:"%s | Search results",descriptionTemplate:"%s Search results description",noIndex:!0,noFollow:!0,bodyH1:"Showing results for:"}},theme:"custom-theme",platform:"vtex",api:{storeId:"storeframework",workspace:"master",subDomainPrefix:["www"],environment:"vtexcommercestable",hideUnavailableItems:!1,showSponsored:!1,incrementAddress:!0,enableUnavailableItemsOnCart:!1},session:{currency:{code:"USD",symbol:"$"},locale:"en-US",channel:'{"salesChannel":"1","regionId":"","hasOnlyDefaultSalesChannel":"true"}',country:"USA",deliveryMode:null,addressType:null,city:null,postalCode:null,geoCoordinates:null,b2b:null,person:null,marketingData:{utmCampaign:"",utmMedium:"",utmSource:"",utmiCampaign:"",utmiPart:"",utmiPage:""},refreshAfter:null},cart:{id:"",items:[],messages:[],shouldSplitItem:!0},storeUrl:"https://homebrewqa.fast.store",secureSubdomain:"https://homebrewqa.fast.store",checkoutUrl:"https://homebrewqa.fast.store/checkout",loginUrl:"https://homebrewqa.fast.store/api/io/login",accountUrl:"https://homebrewqa.fast.store/api/io/account",previewRedirects:{home:"/",plp:"/office",search:"/s?q=headphone",pdp:"/apple-magic-mouse/p",500:"/500",404:"/404"},lighthouse:{server:process.env.BASE_SITE_URL||"http://localhost:3000",pages:{home:"/",pdp:"/4k-philips-monitor-99988213/p",collection:"/office"}},cypress:{pages:{home:"/",pdp:"/4k-philips-monitor-99988213/p",collection:"/office",collection_2:"/technology",collection_filtered:"/office/?category-1=office&marca=acer&facets=category-1%2Cmarca",search:"/s?q=orange"}},analytics:{gtmContainerId:"GTM-PGHZ95N"},cms:{data:process.env.CMS_DATA},contentSource:{type:"CMS"},deliveryPromise:{enabled:!1,mandatory:!1},experimental:{cypressVersion:12,enableCypressExtension:!1,noRobots:!1,noindex:!1,nofollow:!1,preact:!1,enableRedirects:!1,enableSearchSSR:!1,enableFaststoreMyAccount:!1,graphqlCacheControl:{maxAge:0,staleWhileRevalidate:3600},refreshToken:!1,scrollRestoration:!1},direction:"ltr"}},43412:(e,t,o)=>{let r=o(38038),s=o(2512),n=o(56330),a=n(r,s);e.exports=a},2512:e=>{e.exports={}},39729:(e,t,o)=>{"use strict";o.d(t,{Q:()=>c,Z:()=>i});var r=o(20997);let fonts_WebFonts=function(){return r.jsx(r.Fragment,{})},s={components:{WebFonts:fonts_WebFonts}},n={components:{ThirdPartyScripts:()=>r.jsx(r.Fragment,{})}};function ownKeys(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,r)}return o}function _objectSpread(e){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{};t%2?ownKeys(Object(o),!0).forEach(function(t){var r;r=o[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(o)):ownKeys(Object(o)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(o,t))})}return e}let a=_objectSpread(_objectSpread(_objectSpread(_objectSpread({WebFonts:fonts_WebFonts},n.components),s.components),s.components),n.components),c=a.WebFonts,i=a}};