@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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +24 -24
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/react-loadable-manifest.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/2445.js +12 -1
- package/.next/server/chunks/3890.js +492 -0
- package/.next/server/chunks/3951.js +7 -0
- package/.next/server/chunks/4365.js +1 -1
- package/.next/server/chunks/870.js +1 -1
- package/.next/server/chunks/9563.js +2 -2
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.js +1 -1
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.js +1 -1
- package/.next/server/pages/500.js.nft.json +1 -1
- package/.next/server/pages/[...slug].js +1 -1
- package/.next/server/pages/[...slug].js.nft.json +1 -1
- package/.next/server/pages/[slug]/p.js +1 -1
- package/.next/server/pages/[slug]/p.js.nft.json +1 -1
- package/.next/server/pages/_app.js +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/api/fs/logout.js.nft.json +1 -1
- package/.next/server/pages/api/graphql.js +3 -3
- package/.next/server/pages/api/graphql.js.nft.json +1 -1
- package/.next/server/pages/api/health/live.js.nft.json +1 -1
- package/.next/server/pages/api/health/ready.js.nft.json +1 -1
- package/.next/server/pages/api/preview.js +1 -1
- package/.next/server/pages/api/preview.js.nft.json +1 -1
- package/.next/server/pages/checkout.js +1 -1
- package/.next/server/pages/checkout.js.nft.json +1 -1
- package/.next/server/pages/en-US/404.html +28 -13
- package/.next/server/pages/en-US/500.html +28 -13
- package/.next/server/pages/en-US/checkout.html +28 -13
- package/.next/server/pages/en-US/login.html +28 -13
- package/.next/server/pages/en-US/s.html +28 -13
- package/.next/server/pages/en-US.html +28 -13
- package/.next/server/pages/index.js +1 -1
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/login.js +1 -1
- package/.next/server/pages/login.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/403.js +1 -1
- package/.next/server/pages/pvt/account/403.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/404.js +1 -1
- package/.next/server/pages/pvt/account/404.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/[...unknown].js +1 -1
- package/.next/server/pages/pvt/account/[...unknown].js.nft.json +1 -1
- package/.next/server/pages/pvt/account/orders/[id].js +1 -1
- package/.next/server/pages/pvt/account/orders/[id].js.nft.json +1 -1
- package/.next/server/pages/pvt/account/orders.js +1 -1
- package/.next/server/pages/pvt/account/orders.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/profile.js +1 -1
- package/.next/server/pages/pvt/account/profile.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/security.js +1 -1
- package/.next/server/pages/pvt/account/security.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/user-details.js +1 -1
- package/.next/server/pages/pvt/account/user-details.js.nft.json +1 -1
- package/.next/server/pages/pvt/account.js +1 -1
- package/.next/server/pages/pvt/account.js.nft.json +1 -1
- package/.next/server/pages/s.js +1 -1
- package/.next/server/pages/s.js.nft.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/{wEDc4gCW_Kv0gEGlYKana → DAJIfXczlTKGDp0c66INm}/_buildManifest.js +1 -1
- package/.next/static/chunks/7692.8d5bf4560341a2f6.js +1 -0
- package/.next/static/chunks/941.3e2782ab9c490eb0.js +1 -0
- package/.next/static/chunks/CartSidebar.f0c16e2bc6f96e9e.js +1 -0
- package/.next/static/chunks/pages/_app-1595678557980d65.js +1 -0
- package/.next/static/chunks/pages/pvt/account/orders/[id]-e03ebb0393ac92a2.js +1 -0
- package/.next/static/chunks/webpack-f3fde0e8298ce999.js +1 -0
- package/.next/static/css/{5eecefd2c6deeee4.css → 08d03445f1797608.css} +1 -1
- package/.next/trace +140 -139
- package/.turbo/turbo-build.log +26 -26
- package/.turbo/turbo-test.log +6 -7
- package/@generated/gql.ts +2 -2
- package/@generated/graphql.ts +54 -1
- package/@generated/persisted-documents.json +1 -1
- package/@generated/schema.graphql +41 -0
- package/CHANGELOG.md +32 -0
- package/discovery.config.default.js +1 -0
- package/package.json +4 -4
- package/src/Layout.tsx +2 -2
- package/src/components/ThirdPartyScripts/GoogleTagManager.tsx +19 -10
- package/src/components/ThirdPartyScripts/ThirdPartyScripts.tsx +1 -22
- package/src/components/ThirdPartyScripts/vtex.tsx +6 -1
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/MyAccountBudgetsCard.tsx +119 -0
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/index.ts +1 -0
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountBudgetsCard/styles.scss +129 -0
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActions/MyAccountOrderActions.tsx +19 -6
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActions/styles.scss +10 -0
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountOrderDetails.tsx +18 -5
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/MyAccountReorderButton.tsx +37 -0
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/index.ts +2 -0
- package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/styles.scss +10 -0
- package/src/components/account/orders/MyAccountOrderDetails/section.module.scss +46 -17
- package/src/constants.ts +2 -0
- package/src/pages/_document.tsx +40 -0
- package/src/pages/api/preview.ts +4 -4
- package/src/pages/pvt/account/orders/[id].tsx +19 -1
- package/src/sdk/account/useReorder.ts +148 -0
- package/src/sdk/analytics/hooks/usePageViewEvent.ts +7 -2
- package/src/sdk/analytics/platform/vtex/search.ts +22 -8
- package/src/sdk/cart/redirectToCheckout.ts +15 -0
- package/src/sdk/cart/useCheckoutButton.ts +2 -9
- package/src/sdk/error/ReorderError/ReorderError.ts +6 -0
- package/.next/server/chunks/4168.js +0 -1
- package/.next/server/chunks/9630.js +0 -495
- package/.next/static/chunks/7692.a352cce6d744fa8b.js +0 -1
- package/.next/static/chunks/941.417f354fd61bae91.js +0 -1
- package/.next/static/chunks/CartSidebar.3342e22b115732a3.js +0 -1
- package/.next/static/chunks/pages/_app-dbee0add24c249fe.js +0 -1
- package/.next/static/chunks/pages/pvt/account/orders/[id]-dc662a778c5b8876.js +0 -1
- package/.next/static/chunks/webpack-c6f7dbc72e738310.js +0 -1
- /package/.next/static/{wEDc4gCW_Kv0gEGlYKana → DAJIfXczlTKGDp0c66INm}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { ServerOrderDetailsQueryQuery } from '@generated/graphql'
|
|
2
|
+
import MyAccountCard from 'src/components/account/components/MyAccountCard'
|
|
3
|
+
import { useFormatPrice } from 'src/components/account/utils/useFormatPrice'
|
|
4
|
+
|
|
5
|
+
interface MyAccountBudgetsCardProps {
|
|
6
|
+
budgetData: ServerOrderDetailsQueryQuery['userOrder']['budgetData']
|
|
7
|
+
currencyCode: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function MyAccountBudgetsCard({
|
|
11
|
+
budgetData,
|
|
12
|
+
currencyCode,
|
|
13
|
+
}: MyAccountBudgetsCardProps) {
|
|
14
|
+
const formatPrice = useFormatPrice()
|
|
15
|
+
|
|
16
|
+
if (!budgetData?.budgets || budgetData.budgets.length === 0) {
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Process each budget to display correctly
|
|
21
|
+
const budgetRows = budgetData.budgets
|
|
22
|
+
.filter(
|
|
23
|
+
(budget) => budget && budget.allocations && budget.allocations.length > 0
|
|
24
|
+
)
|
|
25
|
+
.map((budget) => {
|
|
26
|
+
const allocations = budget.allocations.filter(Boolean)
|
|
27
|
+
|
|
28
|
+
// Calculate toBeSpent: sum all reservation values from all allocations
|
|
29
|
+
// reservations is an object (key: value), so we need to sum all values
|
|
30
|
+
const toBeSpent = allocations.reduce((total, allocation) => {
|
|
31
|
+
if (!allocation?.reservations) return total
|
|
32
|
+
|
|
33
|
+
const reservations = allocation.reservations
|
|
34
|
+
// If reservations is an object, sum all its values
|
|
35
|
+
if (typeof reservations === 'object' && reservations !== null) {
|
|
36
|
+
const reservationValues = Object.values(reservations).filter(
|
|
37
|
+
(val): val is number => typeof val === 'number'
|
|
38
|
+
)
|
|
39
|
+
return total + reservationValues.reduce((sum, val) => sum + val, 0)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return total
|
|
43
|
+
}, 0)
|
|
44
|
+
|
|
45
|
+
// Get remaining from budget.balance.remaining
|
|
46
|
+
const remaining = budget.balance?.remaining || 0
|
|
47
|
+
|
|
48
|
+
// Calculate available: toBeSpent + remaining
|
|
49
|
+
const available = toBeSpent + remaining
|
|
50
|
+
|
|
51
|
+
// Get list of allocation linkedEntity IDs
|
|
52
|
+
const allocationIds = allocations
|
|
53
|
+
.map((allocation) => allocation?.linkedEntity?.id)
|
|
54
|
+
.filter(Boolean)
|
|
55
|
+
.join(', ')
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
budget,
|
|
59
|
+
allocationIds,
|
|
60
|
+
toBeSpent,
|
|
61
|
+
remaining,
|
|
62
|
+
available,
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
if (budgetRows.length === 0) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<MyAccountCard title="Budgets" data-fs-order-budgets-card>
|
|
72
|
+
<div data-fs-budgets-table>
|
|
73
|
+
<div data-fs-budgets-table-header>
|
|
74
|
+
<div data-fs-budgets-header-name>Name</div>
|
|
75
|
+
<div data-fs-budgets-header-available>Available</div>
|
|
76
|
+
<div data-fs-budgets-header-to-be-spent>To be spent</div>
|
|
77
|
+
<div data-fs-budgets-header-remaining>Remaining</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div data-fs-budgets-table-body>
|
|
80
|
+
{budgetRows.map(
|
|
81
|
+
(
|
|
82
|
+
{ budget, allocationIds, toBeSpent, remaining, available },
|
|
83
|
+
index
|
|
84
|
+
) => {
|
|
85
|
+
const budgetName = budget.name || ''
|
|
86
|
+
const allocationsList = allocationIds || ''
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div data-fs-budgets-row key={budget.id || index}>
|
|
90
|
+
<div data-fs-budgets-name>
|
|
91
|
+
<div data-fs-budgets-name-primary>{budgetName}</div>
|
|
92
|
+
<div data-fs-budgets-name-secondary title={allocationsList}>
|
|
93
|
+
{allocationsList}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<div data-fs-budgets-available>
|
|
97
|
+
{Number.isFinite(available)
|
|
98
|
+
? formatPrice(available, currencyCode)
|
|
99
|
+
: '—'}
|
|
100
|
+
</div>
|
|
101
|
+
<div data-fs-budgets-to-be-spent>
|
|
102
|
+
{toBeSpent !== 0
|
|
103
|
+
? formatPrice(toBeSpent, currencyCode)
|
|
104
|
+
: formatPrice(0, currencyCode)}
|
|
105
|
+
</div>
|
|
106
|
+
<div data-fs-budgets-remaining>
|
|
107
|
+
<strong>{formatPrice(remaining, currencyCode)}</strong>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</MyAccountCard>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export default MyAccountBudgetsCard
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './MyAccountBudgetsCard'
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
[data-fs-order-budgets-card] {
|
|
2
|
+
--fs-budgets-gap: var(--fs-spacing-3);
|
|
3
|
+
--fs-budgets-padding-y: var(--fs-spacing-2);
|
|
4
|
+
--fs-budgets-row-padding: var(--fs-spacing-3) 0;
|
|
5
|
+
--fs-budgets-font-size: var(--fs-text-size-2);
|
|
6
|
+
--fs-budgets-font-size-sm: var(--fs-text-size-1);
|
|
7
|
+
--fs-budgets-weight-regular: var(--fs-text-weight-regular);
|
|
8
|
+
--fs-budgets-weight-semibold: var(--fs-text-weight-semibold);
|
|
9
|
+
--fs-budgets-text: var(--fs-color-text);
|
|
10
|
+
--fs-budgets-text-secondary: var(--fs-color-text-secondary);
|
|
11
|
+
--fs-budgets-border-color: var(--fs-border-color-light);
|
|
12
|
+
--fs-budgets-cols-mobile: 2fr 1fr 1fr;
|
|
13
|
+
--fs-budgets-cols-desktop: 2fr 1fr 1fr 1fr;
|
|
14
|
+
|
|
15
|
+
[data-fs-budgets-table] {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
width: 100%;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[data-fs-budgets-table-header] {
|
|
22
|
+
display: grid;
|
|
23
|
+
grid-template-columns: var(--fs-budgets-cols-mobile);
|
|
24
|
+
gap: var(--fs-budgets-gap);
|
|
25
|
+
padding: var(--fs-budgets-padding-y) 0;
|
|
26
|
+
font-size: var(--fs-budgets-font-size);
|
|
27
|
+
font-weight: var(--fs-budgets-weight-regular);
|
|
28
|
+
color: var(--fs-budgets-text-secondary);
|
|
29
|
+
border-bottom: 1px solid var(--fs-budgets-border-color);
|
|
30
|
+
|
|
31
|
+
[data-fs-budgets-header-name] {
|
|
32
|
+
text-align: left;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[data-fs-budgets-header-available],
|
|
36
|
+
[data-fs-budgets-header-to-be-spent],
|
|
37
|
+
[data-fs-budgets-header-remaining] {
|
|
38
|
+
text-align: right;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@include media('>=tablet') {
|
|
43
|
+
grid-template-columns: var(--fs-budgets-cols-desktop);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
[data-fs-budgets-header-available] {
|
|
47
|
+
@include media('<tablet') {
|
|
48
|
+
display: none;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
[data-fs-budgets-table-body] {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
|
|
57
|
+
[data-fs-budgets-row] {
|
|
58
|
+
display: grid;
|
|
59
|
+
grid-template-columns: var(--fs-budgets-cols-mobile);
|
|
60
|
+
gap: var(--fs-budgets-gap);
|
|
61
|
+
padding: var(--fs-budgets-row-padding);
|
|
62
|
+
border-bottom: 1px solid var(--fs-budgets-border-color);
|
|
63
|
+
|
|
64
|
+
// Prevent long content from forcing the grid to overflow
|
|
65
|
+
> * {
|
|
66
|
+
min-width: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&:last-child {
|
|
70
|
+
border-bottom: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@include media('>=tablet') {
|
|
74
|
+
grid-template-columns: var(--fs-budgets-cols-desktop);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[data-fs-budgets-available] {
|
|
79
|
+
@include media('<tablet') {
|
|
80
|
+
display: none;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[data-fs-budgets-name] {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: var(--fs-spacing-0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[data-fs-budgets-name-primary] {
|
|
92
|
+
overflow: hidden;
|
|
93
|
+
font-size: var(--fs-budgets-font-size);
|
|
94
|
+
font-weight: var(--fs-budgets-weight-semibold);
|
|
95
|
+
line-height: 1.4;
|
|
96
|
+
color: var(--fs-budgets-text);
|
|
97
|
+
text-overflow: ellipsis;
|
|
98
|
+
white-space: nowrap;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
[data-fs-budgets-name-secondary] {
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
font-size: var(--fs-budgets-font-size-sm);
|
|
104
|
+
font-weight: var(--fs-budgets-weight-regular);
|
|
105
|
+
line-height: 1.4;
|
|
106
|
+
color: var(--fs-budgets-text-secondary);
|
|
107
|
+
text-overflow: ellipsis;
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
[data-fs-budgets-available],
|
|
112
|
+
[data-fs-budgets-to-be-spent],
|
|
113
|
+
[data-fs-budgets-remaining] {
|
|
114
|
+
font-size: var(--fs-budgets-font-size);
|
|
115
|
+
font-weight: var(--fs-budgets-weight-regular);
|
|
116
|
+
color: var(--fs-budgets-text);
|
|
117
|
+
text-align: right;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
[data-fs-budgets-remaining] {
|
|
121
|
+
strong {
|
|
122
|
+
font-weight: var(--fs-budgets-weight-semibold);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
[data-fs-budgets-to-be-spent] {
|
|
127
|
+
color: var(--fs-budgets-text-secondary);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -9,22 +9,29 @@ import {
|
|
|
9
9
|
import { useState } from 'react'
|
|
10
10
|
import MyAccountOrderActionModal from 'src/components/account/orders/MyAccountOrderDetails/MyAccountOrderActionModal'
|
|
11
11
|
import { useCancelOrder } from 'src/sdk/account/useCancelOrder'
|
|
12
|
+
import { useReorder } from 'src/sdk/account/useReorder'
|
|
13
|
+
import type { ServerOrderDetailsQueryQuery } from '@generated/graphql'
|
|
14
|
+
|
|
15
|
+
type Order = ServerOrderDetailsQueryQuery['userOrder']
|
|
12
16
|
|
|
13
17
|
interface MyAccountOrderActionsProps {
|
|
14
18
|
allowCancellation: boolean
|
|
15
19
|
orderId: string
|
|
16
20
|
customerEmail?: string
|
|
21
|
+
order: Order
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
export default function MyAccountOrderActions({
|
|
20
25
|
allowCancellation,
|
|
21
26
|
orderId,
|
|
22
27
|
customerEmail,
|
|
28
|
+
order,
|
|
23
29
|
}: MyAccountOrderActionsProps) {
|
|
24
30
|
const [isCancelOpen, setIsCancelOpen] = useState<boolean>(false)
|
|
25
31
|
const { pushToast } = useUI()
|
|
26
32
|
|
|
27
33
|
const { cancelOrder, loading } = useCancelOrder()
|
|
34
|
+
const { reorder } = useReorder()
|
|
28
35
|
|
|
29
36
|
const handleCancel = async () => {
|
|
30
37
|
const data = {
|
|
@@ -54,9 +61,8 @@ export default function MyAccountOrderActions({
|
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return null
|
|
64
|
+
const handleReorder = () => {
|
|
65
|
+
reorder(order)
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
return (
|
|
@@ -67,13 +73,20 @@ export default function MyAccountOrderActions({
|
|
|
67
73
|
<UIIcon name="DotsThree" data-fs-dropdown-icon />
|
|
68
74
|
</DropdownButton>
|
|
69
75
|
<DropdownMenu align="right">
|
|
76
|
+
<DropdownItem
|
|
77
|
+
type="button"
|
|
78
|
+
onClick={handleReorder}
|
|
79
|
+
data-fs-order-actions-item
|
|
80
|
+
data-fs-order-actions-item-reorder
|
|
81
|
+
>
|
|
82
|
+
Reorder
|
|
83
|
+
</DropdownItem>
|
|
70
84
|
{allowCancellation && (
|
|
71
85
|
<DropdownItem
|
|
72
86
|
type="button"
|
|
73
87
|
onClick={() => setIsCancelOpen(true)}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}}
|
|
88
|
+
data-fs-order-actions-item
|
|
89
|
+
data-fs-order-actions-item-cancel
|
|
77
90
|
>
|
|
78
91
|
Cancel order
|
|
79
92
|
</DropdownItem>
|
|
@@ -6,7 +6,9 @@ import { MyAccountDeliveryOptionAccordion } from './MyAccountDeliveryOptionAccor
|
|
|
6
6
|
import MyAccountOrderActions from './MyAccountOrderActions'
|
|
7
7
|
import MyAccountOrderedByCard from './MyAccountOrderedByCard'
|
|
8
8
|
import MyAccountPaymentCard from './MyAccountPaymentCard'
|
|
9
|
+
import MyAccountReorderButton from './MyAccountReorderButton'
|
|
9
10
|
import MyAccountSummaryCard from './MyAccountSummaryCard'
|
|
11
|
+
import MyAccountBudgetsCard from './MyAccountBudgetsCard'
|
|
10
12
|
|
|
11
13
|
import type {
|
|
12
14
|
ServerOrderDetailsQueryQuery,
|
|
@@ -55,11 +57,15 @@ export default function MyAccountOrderDetails({
|
|
|
55
57
|
</div>
|
|
56
58
|
</div>
|
|
57
59
|
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
<div data-fs-order-details-header-actions>
|
|
61
|
+
<MyAccountReorderButton order={order} />
|
|
62
|
+
<MyAccountOrderActions
|
|
63
|
+
allowCancellation={order.allowCancellation}
|
|
64
|
+
orderId={order.orderId}
|
|
65
|
+
customerEmail={order.clientProfileData?.email}
|
|
66
|
+
order={order}
|
|
67
|
+
/>
|
|
68
|
+
</div>
|
|
63
69
|
</header>
|
|
64
70
|
|
|
65
71
|
<main data-fs-order-details-content>
|
|
@@ -117,6 +123,13 @@ export default function MyAccountOrderDetails({
|
|
|
117
123
|
{moreInformationCustomFields?.length > 0 && (
|
|
118
124
|
<MyAccountMoreInformationCard fields={moreInformationCustomFields} />
|
|
119
125
|
)}
|
|
126
|
+
|
|
127
|
+
{order.budgetData && (
|
|
128
|
+
<MyAccountBudgetsCard
|
|
129
|
+
budgetData={order.budgetData}
|
|
130
|
+
currencyCode={order.storePreferencesData.currencyCode}
|
|
131
|
+
/>
|
|
132
|
+
)}
|
|
120
133
|
</main>
|
|
121
134
|
</div>
|
|
122
135
|
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Button } from '@faststore/ui'
|
|
2
|
+
import { useReorder } from 'src/sdk/account/useReorder'
|
|
3
|
+
import type { ServerOrderDetailsQueryQuery } from '@generated/graphql'
|
|
4
|
+
|
|
5
|
+
type Order = ServerOrderDetailsQueryQuery['userOrder']
|
|
6
|
+
|
|
7
|
+
export interface MyAccountReorderButtonProps {
|
|
8
|
+
order: Order
|
|
9
|
+
onClick?: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function MyAccountReorderButton({
|
|
13
|
+
order,
|
|
14
|
+
onClick,
|
|
15
|
+
}: MyAccountReorderButtonProps) {
|
|
16
|
+
const { reorder, loading } = useReorder()
|
|
17
|
+
|
|
18
|
+
const handleClick = async () => {
|
|
19
|
+
try {
|
|
20
|
+
await reorder(order)
|
|
21
|
+
onClick?.()
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error(error)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Button
|
|
29
|
+
variant="secondary"
|
|
30
|
+
data-fs-reorder-button
|
|
31
|
+
onClick={handleClick}
|
|
32
|
+
disabled={loading}
|
|
33
|
+
>
|
|
34
|
+
Reorder
|
|
35
|
+
</Button>
|
|
36
|
+
)
|
|
37
|
+
}
|
package/src/components/account/orders/MyAccountOrderDetails/MyAccountReorderButton/styles.scss
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
[data-fs-reorder-button] {
|
|
2
|
+
flex-shrink: 0;
|
|
3
|
+
|
|
4
|
+
&:hover:not(:disabled) {
|
|
5
|
+
--fs-button-secondary-bkg-color: var(--fs-button-primary-bkg-color);
|
|
6
|
+
--fs-button-secondary-text-color: var(--fs-button-primary-text-color);
|
|
7
|
+
--fs-button-secondary-bkg-color-hover: var(--fs-button-primary-bkg-color-hover);
|
|
8
|
+
--fs-button-secondary-bkg-color-active: var(--fs-button-primary-bkg-color-active);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -15,33 +15,35 @@
|
|
|
15
15
|
@import "./MyAccountPaymentCard/styles.scss";
|
|
16
16
|
@import "./MyAccountDeliveryOptionAccordion/styles.scss";
|
|
17
17
|
@import "./MyAccountOrderActions/styles.scss";
|
|
18
|
+
@import "./MyAccountReorderButton/styles.scss";
|
|
18
19
|
@import "./MyAccountStatusCard/styles.scss";
|
|
19
20
|
@import "./MyAccountMoreInformationCard/styles.scss";
|
|
20
21
|
@import "./MyAccountBuyingPolicyAlert/styles.scss";
|
|
22
|
+
@import "./MyAccountBudgetsCard/styles.scss";
|
|
21
23
|
|
|
22
24
|
// --------------------------------------------------------
|
|
23
25
|
// Design Tokens
|
|
24
26
|
// --------------------------------------------------------
|
|
25
27
|
|
|
26
28
|
// Default properties
|
|
27
|
-
--fs-order-details-padding
|
|
29
|
+
--fs-order-details-padding: 0 20px;
|
|
28
30
|
|
|
29
31
|
// Header
|
|
30
|
-
--fs-order-details-header-gap
|
|
31
|
-
--fs-order-details-header-padding
|
|
32
|
-
--fs-order-details-header-weight
|
|
33
|
-
--fs-order-details-header-size
|
|
34
|
-
--fs-order-details-header-line-height
|
|
32
|
+
--fs-order-details-header-gap: var(--fs-spacing-3);
|
|
33
|
+
--fs-order-details-header-padding: var(--fs-spacing-5) 0 var(--fs-spacing-4);
|
|
34
|
+
--fs-order-details-header-weight: var(--fs-text-weight-semibold);
|
|
35
|
+
--fs-order-details-header-size: var(--fs-text-size-4);
|
|
36
|
+
--fs-order-details-header-line-height: 1.33;
|
|
35
37
|
|
|
36
38
|
// Content
|
|
37
|
-
--fs-order-details-content-gap
|
|
39
|
+
--fs-order-details-content-gap: var(--fs-spacing-4);
|
|
38
40
|
|
|
39
41
|
// --------------------------------------------------------
|
|
40
42
|
// Structural Styles
|
|
41
43
|
// --------------------------------------------------------
|
|
42
44
|
|
|
43
|
-
@include media
|
|
44
|
-
--fs-order-details-padding
|
|
45
|
+
@include media(">=notebook") {
|
|
46
|
+
--fs-order-details-padding: 0;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
[data-fs-order-details-header] {
|
|
@@ -52,14 +54,14 @@
|
|
|
52
54
|
justify-content: space-between;
|
|
53
55
|
padding: var(--fs-order-details-header-padding);
|
|
54
56
|
|
|
55
|
-
@include media
|
|
56
|
-
--fs-order-details-header-gap
|
|
57
|
+
@include media(">=tablet") {
|
|
58
|
+
--fs-order-details-header-gap: var(--fs-spacing-2);
|
|
57
59
|
|
|
58
60
|
align-items: center;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
@include media
|
|
62
|
-
--fs-order-details-header-padding
|
|
63
|
+
@include media(">=notebook") {
|
|
64
|
+
--fs-order-details-header-padding: var(--fs-spacing-6) 0;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
[data-fs-order-details-header-title] {
|
|
@@ -70,11 +72,21 @@
|
|
|
70
72
|
|
|
71
73
|
[data-fs-order-details-header-back-button] {
|
|
72
74
|
flex-shrink: 0;
|
|
73
|
-
margin-top:
|
|
74
|
-
|
|
75
|
+
margin-top:
|
|
76
|
+
calc(
|
|
77
|
+
var(--fs-spacing-2) * -1
|
|
78
|
+
); // Align the back button with the title
|
|
79
|
+
|
|
80
|
+
margin-left:
|
|
81
|
+
calc(
|
|
82
|
+
var(--fs-spacing-2) * -1
|
|
83
|
+
); // Align the back button with the content
|
|
75
84
|
|
|
76
85
|
@include media(">=notebook") {
|
|
77
|
-
margin-top:
|
|
86
|
+
margin-top:
|
|
87
|
+
calc(
|
|
88
|
+
var(--fs-spacing-1) * -1
|
|
89
|
+
); // Align the back button with the title
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
92
|
|
|
@@ -98,6 +110,19 @@
|
|
|
98
110
|
@include truncate-title(2);
|
|
99
111
|
}
|
|
100
112
|
}
|
|
113
|
+
|
|
114
|
+
[data-fs-order-details-header-actions] {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: row;
|
|
117
|
+
gap: var(--fs-spacing-2);
|
|
118
|
+
align-items: center;
|
|
119
|
+
|
|
120
|
+
[data-fs-reorder-button] {
|
|
121
|
+
@include media("<tablet") {
|
|
122
|
+
display: none;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
101
126
|
}
|
|
102
127
|
|
|
103
128
|
[data-fs-order-details-content] {
|
|
@@ -105,7 +130,7 @@
|
|
|
105
130
|
flex-direction: column;
|
|
106
131
|
gap: var(--fs-order-details-content-gap);
|
|
107
132
|
|
|
108
|
-
@include media
|
|
133
|
+
@include media(">=notebook") {
|
|
109
134
|
display: grid;
|
|
110
135
|
grid-template-columns: repeat(2, 1fr);
|
|
111
136
|
}
|
|
@@ -125,5 +150,9 @@
|
|
|
125
150
|
[data-fs-delivery-option-accordion] {
|
|
126
151
|
grid-column: span 2;
|
|
127
152
|
}
|
|
153
|
+
|
|
154
|
+
[data-fs-order-budgets-card] {
|
|
155
|
+
grid-column: span 2;
|
|
156
|
+
}
|
|
128
157
|
}
|
|
129
158
|
}
|
package/src/constants.ts
CHANGED
package/src/pages/_document.tsx
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { Head, Html, Main, NextScript } from 'next/document'
|
|
2
2
|
import storeConfig from '../../discovery.config'
|
|
3
3
|
|
|
4
|
+
import { GTM_DEBUG_QUERY_STRING } from 'src/components/ThirdPartyScripts/GoogleTagManager'
|
|
4
5
|
import { WebFonts } from 'src/customizations/src/GlobalOverrides'
|
|
5
6
|
|
|
6
7
|
function Document() {
|
|
7
8
|
const direction = storeConfig.direction || 'ltr'
|
|
9
|
+
const gtmContainerId = storeConfig.analytics?.gtmContainerId
|
|
10
|
+
const includeGTM = typeof gtmContainerId === 'string'
|
|
11
|
+
const includeVTEX = storeConfig.platform === 'vtex'
|
|
12
|
+
const enableScriptsLogs = storeConfig.experimental?.enableScriptsLogs === true
|
|
13
|
+
const forwards = []
|
|
14
|
+
if (includeVTEX) forwards.push('sendrc')
|
|
8
15
|
|
|
9
16
|
return (
|
|
10
17
|
<Html dir={direction}>
|
|
@@ -19,6 +26,39 @@ function Document() {
|
|
|
19
26
|
/>
|
|
20
27
|
<meta name="storefront" content="fast_store" />
|
|
21
28
|
<WebFonts />
|
|
29
|
+
{/* Partytown config must be set before loading the library.
|
|
30
|
+
* We're setting the partytown config (forward property) dynamically based on the gtm_debug query string
|
|
31
|
+
* This helps users see the GTM events properly when using GTM preview. All it does is NOT forward dataLayer.push
|
|
32
|
+
* calls to partytown when the gtm_debug query string is present.
|
|
33
|
+
*
|
|
34
|
+
* This is not done in the component because the window var is not available yet.
|
|
35
|
+
*/}
|
|
36
|
+
<script
|
|
37
|
+
dangerouslySetInnerHTML={{
|
|
38
|
+
__html: `var partytown={
|
|
39
|
+
debug:${enableScriptsLogs},
|
|
40
|
+
logCalls:${enableScriptsLogs},
|
|
41
|
+
forward:[...${JSON.stringify(
|
|
42
|
+
forwards
|
|
43
|
+
)},!window.location.search.includes('${GTM_DEBUG_QUERY_STRING}=')&&${includeGTM}?'dataLayer.push':null].filter(Boolean)
|
|
44
|
+
}`,
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
{/* Only load Partytown when not in an iframe to prevent cross-origin errors.
|
|
48
|
+
* https://github.com/vtex/faststore/pull/3155
|
|
49
|
+
*/}
|
|
50
|
+
<script
|
|
51
|
+
dangerouslySetInnerHTML={{
|
|
52
|
+
__html: `
|
|
53
|
+
if (window.self === window.top) {
|
|
54
|
+
var partytownScript = document.createElement('script');
|
|
55
|
+
partytownScript.async = true;
|
|
56
|
+
partytownScript.src = '/~partytown/partytown.js';
|
|
57
|
+
document.head.appendChild(partytownScript);
|
|
58
|
+
}
|
|
59
|
+
`,
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
22
62
|
</Head>
|
|
23
63
|
<body className="theme">
|
|
24
64
|
<Main />
|
package/src/pages/api/preview.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
|
2
2
|
|
|
3
|
-
import { previewRedirects } from '../../../discovery.config'
|
|
4
|
-
import { contentService } from 'src/server/content/service'
|
|
5
3
|
import { isLocator } from 'src/server/cms'
|
|
4
|
+
import { contentService } from 'src/server/content/service'
|
|
5
|
+
import type { PreviewData } from 'src/server/content/types'
|
|
6
6
|
import {
|
|
7
7
|
isBranchPreview,
|
|
8
8
|
isContentPlatformSource,
|
|
9
9
|
} from 'src/server/content/utils'
|
|
10
|
-
import
|
|
10
|
+
import { previewRedirects } from '../../../discovery.config'
|
|
11
11
|
|
|
12
12
|
type Settings = {
|
|
13
13
|
seo: {
|
|
@@ -40,7 +40,7 @@ const setPreviewAndRedirect = (
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
if (!isBranchPreview(previewData as PreviewData)) {
|
|
43
|
-
options.path = redirectPath
|
|
43
|
+
options.path = redirectPath.split('?')[0]
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
res.setPreviewData(previewData, options)
|
|
@@ -257,6 +257,22 @@ const query = gql(`
|
|
|
257
257
|
email
|
|
258
258
|
phone
|
|
259
259
|
}
|
|
260
|
+
budgetData {
|
|
261
|
+
budgets {
|
|
262
|
+
id
|
|
263
|
+
name
|
|
264
|
+
balance {
|
|
265
|
+
remaining
|
|
266
|
+
}
|
|
267
|
+
allocations {
|
|
268
|
+
id
|
|
269
|
+
linkedEntity {
|
|
270
|
+
id
|
|
271
|
+
}
|
|
272
|
+
reservations
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
260
276
|
}
|
|
261
277
|
accountProfile {
|
|
262
278
|
name
|
|
@@ -339,10 +355,12 @@ export const getServerSideProps: GetServerSideProps<
|
|
|
339
355
|
globalSectionsFooter,
|
|
340
356
|
})
|
|
341
357
|
|
|
358
|
+
const order = orderDetails.data.userOrder
|
|
359
|
+
|
|
342
360
|
return {
|
|
343
361
|
props: {
|
|
344
362
|
globalSections: globalSectionsResult,
|
|
345
|
-
order
|
|
363
|
+
order,
|
|
346
364
|
accountName: orderDetails.data.accountProfile.name,
|
|
347
365
|
isRepresentative,
|
|
348
366
|
},
|