diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-payment.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-payment.jsx
index 1aa971fc85..dbe743b1ae 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-payment.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-payment.jsx
@@ -233,11 +233,13 @@ const Payment = ({
})
}
+ const [showRegistrationNotice, setShowRegistrationNotice] = useState(false)
const handleRegistrationSuccess = useCallback(
async (newBasketId) => {
if (newBasketId) {
activeBasketIdRef.current = newBasketId
}
+ setShowRegistrationNotice(true)
setShouldSavePaymentMethod(true)
try {
const values = paymentMethodForm?.getValues?.()
@@ -563,7 +565,7 @@ const Payment = ({
isBillingAddress
/>
)}
- {isGuest && (
+ {(isGuest || showRegistrationNotice) && (
)}
@@ -610,7 +613,8 @@ const Payment = ({
- {selectedBillingAddress && (
+ {(selectedBillingAddress ||
+ (effectiveBillingSameAsShipping && selectedShippingAddress)) && (
-
+
)}
- {isGuest && (
+ {(isGuest || showRegistrationNotice) && (
)}
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address.jsx
index e9962ad9f2..0f1020d4dc 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-shipping-address.jsx
@@ -24,13 +24,9 @@ import {
import {useCurrentCustomer} from '@salesforce/retail-react-app/app/hooks/use-current-customer'
import {useCurrentBasket} from '@salesforce/retail-react-app/app/hooks/use-current-basket'
import {useToast} from '@salesforce/retail-react-app/app/hooks/use-toast'
-import {Text, Button, Box} from '@salesforce/retail-react-app/app/components/shared/ui'
+import {Text} from '@salesforce/retail-react-app/app/components/shared/ui'
import {isPickupShipment} from '@salesforce/retail-react-app/app/utils/shipment-utils'
import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config'
-import {useSelectedStore} from '@salesforce/retail-react-app/app/hooks/use-selected-store'
-import useNavigation from '@salesforce/retail-react-app/app/hooks/use-navigation'
-import usePickupShipment from '@salesforce/retail-react-app/app/hooks/use-pickup-shipment'
-import {STORE_LOCATOR_IS_ENABLED} from '@salesforce/retail-react-app/app/constants'
const submitButtonMessage = defineMessage({
defaultMessage: 'Continue to Shipping Method',
@@ -68,11 +64,6 @@ export default function ShippingAddress() {
const hasMultipleDeliveryShipments = deliveryShipments.length > 1
- const storeLocatorEnabled = getConfig()?.app?.storeLocatorEnabled ?? STORE_LOCATOR_IS_ENABLED
- const {selectedStore} = useSelectedStore()
- const {navigate} = useNavigation()
- const {updatePickupShipment} = usePickupShipment(basket)
-
// Prepare a shipping methods query we can manually refetch after address updates
const shippingMethodsQuery = useShippingMethodsForShipment(
{
@@ -86,29 +77,6 @@ export default function ShippingAddress() {
}
)
- const switchToPickup = async () => {
- try {
- if (!selectedStore?.inventoryId) {
- navigate('/store-locator')
- return
- }
- const refreshed = await currentBasketQuery.refetch()
- const latestBasketId = refreshed?.data?.basketId || basket.basketId
- await updatePickupShipment(latestBasketId, selectedStore)
- await currentBasketQuery.refetch()
- goToStep(STEPS.PICKUP_ADDRESS)
- } catch (_e) {
- toast({
- title: formatMessage({
- defaultMessage:
- 'We could not switch to Store Pickup. Please try again or choose a different store.',
- id: 'shipping_address.error.switch_to_pickup_failed'
- }),
- status: 'error'
- })
- }
- }
-
const submitAndContinue = async (address) => {
setIsLoading(true)
try {
@@ -314,24 +282,12 @@ export default function ShippingAddress() {
onBackToSingle={() => setIsMultiShipping(false)}
/>
) : (
- <>
- {storeLocatorEnabled && (
-
-
-
- )}
-
- >
+
)}
{(hasMultipleDeliveryShipments || isAddressFilled) && (
diff --git a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.jsx b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.jsx
index 537807bc48..be1c55989e 100644
--- a/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.jsx
+++ b/packages/template-retail-react-app/app/pages/checkout-one-click/partials/one-click-user-registration.jsx
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
-import React, {useRef} from 'react'
+import React, {useRef, useState} from 'react'
import {FormattedMessage} from 'react-intl'
import PropTypes from 'prop-types'
import {
@@ -13,6 +13,8 @@ import {
Stack,
Text,
Heading,
+ Badge,
+ HStack,
useDisclosure
} from '@salesforce/retail-react-app/app/components/shared/ui'
import OtpAuth from '@salesforce/retail-react-app/app/components/otp-auth'
@@ -28,7 +30,8 @@ export default function UserRegistration({
isGuestCheckout = false,
isDisabled = false,
onSavePreferenceChange,
- onRegistered
+ onRegistered,
+ showNotice = false
}) {
const {data: basket} = useCurrentBasket()
const {isGuest} = useCustomerType()
@@ -41,6 +44,7 @@ export default function UserRegistration({
: `${appOrigin}${passwordlessConfigCallback}`
const {isOpen: isOtpOpen, onOpen: onOtpOpen, onClose: onOtpClose} = useDisclosure()
const otpSentRef = useRef(false)
+ const [registrationSucceeded, setRegistrationSucceeded] = useState(false)
const handleOtpClose = () => {
otpSentRef.current = false
@@ -85,6 +89,7 @@ export default function UserRegistration({
await onRegistered(basket?.basketId)
}
handleOtpClose()
+ setRegistrationSucceeded(true)
} catch (_e) {
// Let OtpAuth surface errors via its own UI/toast
}
@@ -96,6 +101,49 @@ export default function UserRegistration({
return null
}
+ // After successful registration (local) or when parent instructs to show, render notice
+ if (registrationSucceeded || showNotice) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+
return (
<>
{
expect(authorizePasswordlessLogin.mutateAsync).toHaveBeenCalledTimes(1)
})
+ test('shows account creation notification after successful OTP verification', async () => {
+ const user = userEvent.setup()
+ setup()
+ // Enable registration to trigger OTP
+ await user.click(screen.getByRole('checkbox', {name: /Create an account/i}))
+ // Verify OTP (mocked)
+ const otpButton = await screen.findByTestId('otp-verify')
+ await user.click(otpButton)
+ // Notification should appear after registration succeeds
+ await waitFor(() => {
+ expect(screen.getByTestId('sf-account-creation-notification')).toBeInTheDocument()
+ })
+ // Optional: assert key content
+ expect(screen.getByText(/Account Created/i)).toBeInTheDocument()
+ // Use aria-label to avoid ambiguity with body text containing 'verified'
+ expect(screen.getByLabelText(/Verified/i)).toBeInTheDocument()
+ })
+
+ test('renders account creation notification when showNotice prop is true', async () => {
+ render(
+
+
+
+ )
+ expect(screen.getByTestId('sf-account-creation-notification')).toBeInTheDocument()
+ expect(screen.getByText(/Account Created/i)).toBeInTheDocument()
+ })
+
test('calls loginPasswordless with OTP code and register flag', async () => {
const user = userEvent.setup()
const {loginPasswordless} = setup()
diff --git a/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json b/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json
index 09c5ebd179..5ca13ec67b 100644
--- a/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json
+++ b/packages/template-retail-react-app/app/static/translations/compiled/en-GB.json
@@ -161,6 +161,24 @@
"value": "Addresses"
}
],
+ "account_creation_notification.body": [
+ {
+ "type": 0,
+ "value": "We’ve created and verified your account using the information from your order. Next time you check out, just enter the code we send to log in — no password needed."
+ }
+ ],
+ "account_creation_notification.title": [
+ {
+ "type": 0,
+ "value": "Account Created"
+ }
+ ],
+ "account_creation_notification.verified": [
+ {
+ "type": 0,
+ "value": "Verified"
+ }
+ ],
"account_detail.title.account_details": [
{
"type": 0,
diff --git a/packages/template-retail-react-app/app/static/translations/compiled/en-US.json b/packages/template-retail-react-app/app/static/translations/compiled/en-US.json
index 09c5ebd179..5ca13ec67b 100644
--- a/packages/template-retail-react-app/app/static/translations/compiled/en-US.json
+++ b/packages/template-retail-react-app/app/static/translations/compiled/en-US.json
@@ -161,6 +161,24 @@
"value": "Addresses"
}
],
+ "account_creation_notification.body": [
+ {
+ "type": 0,
+ "value": "We’ve created and verified your account using the information from your order. Next time you check out, just enter the code we send to log in — no password needed."
+ }
+ ],
+ "account_creation_notification.title": [
+ {
+ "type": 0,
+ "value": "Account Created"
+ }
+ ],
+ "account_creation_notification.verified": [
+ {
+ "type": 0,
+ "value": "Verified"
+ }
+ ],
"account_detail.title.account_details": [
{
"type": 0,
diff --git a/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json b/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json
index 6253a229eb..0240fc733f 100644
--- a/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json
+++ b/packages/template-retail-react-app/app/static/translations/compiled/en-XA.json
@@ -377,6 +377,48 @@
"value": "]"
}
],
+ "account_creation_notification.body": [
+ {
+ "type": 0,
+ "value": "["
+ },
+ {
+ "type": 0,
+ "value": "Ẇḗḗ’ṽḗḗ ƈřḗḗȧȧŧḗḗḓ ȧȧƞḓ ṽḗḗřīƒīḗḗḓ ẏǿǿŭŭř ȧȧƈƈǿǿŭŭƞŧ ŭŭşīƞɠ ŧħḗḗ īƞƒǿǿřḿȧȧŧīǿǿƞ ƒřǿǿḿ ẏǿǿŭŭř ǿǿřḓḗḗř. Ƞḗḗẋŧ ŧīḿḗḗ ẏǿǿŭŭ ƈħḗḗƈķ ǿǿŭŭŧ, ĵŭŭşŧ ḗḗƞŧḗḗř ŧħḗḗ ƈǿǿḓḗḗ ẇḗḗ şḗḗƞḓ ŧǿǿ ŀǿǿɠ īƞ — ƞǿǿ ƥȧȧşşẇǿǿřḓ ƞḗḗḗḗḓḗḗḓ."
+ },
+ {
+ "type": 0,
+ "value": "]"
+ }
+ ],
+ "account_creation_notification.title": [
+ {
+ "type": 0,
+ "value": "["
+ },
+ {
+ "type": 0,
+ "value": "Ȧƈƈǿǿŭŭƞŧ Ƈřḗḗȧȧŧḗḗḓ"
+ },
+ {
+ "type": 0,
+ "value": "]"
+ }
+ ],
+ "account_creation_notification.verified": [
+ {
+ "type": 0,
+ "value": "["
+ },
+ {
+ "type": 0,
+ "value": "Ṽḗḗřīƒīḗḗḓ"
+ },
+ {
+ "type": 0,
+ "value": "]"
+ }
+ ],
"account_detail.title.account_details": [
{
"type": 0,
diff --git a/packages/template-retail-react-app/translations/en-GB.json b/packages/template-retail-react-app/translations/en-GB.json
index 059e413a15..6830915e50 100644
--- a/packages/template-retail-react-app/translations/en-GB.json
+++ b/packages/template-retail-react-app/translations/en-GB.json
@@ -80,6 +80,15 @@
"account_addresses.title.addresses": {
"defaultMessage": "Addresses"
},
+ "account_creation_notification.body": {
+ "defaultMessage": "We’ve created and verified your account using the information from your order. Next time you check out, just enter the code we send to log in — no password needed."
+ },
+ "account_creation_notification.title": {
+ "defaultMessage": "Account Created"
+ },
+ "account_creation_notification.verified": {
+ "defaultMessage": "Verified"
+ },
"account_detail.title.account_details": {
"defaultMessage": "Account Details"
},
diff --git a/packages/template-retail-react-app/translations/en-US.json b/packages/template-retail-react-app/translations/en-US.json
index 059e413a15..6830915e50 100644
--- a/packages/template-retail-react-app/translations/en-US.json
+++ b/packages/template-retail-react-app/translations/en-US.json
@@ -80,6 +80,15 @@
"account_addresses.title.addresses": {
"defaultMessage": "Addresses"
},
+ "account_creation_notification.body": {
+ "defaultMessage": "We’ve created and verified your account using the information from your order. Next time you check out, just enter the code we send to log in — no password needed."
+ },
+ "account_creation_notification.title": {
+ "defaultMessage": "Account Created"
+ },
+ "account_creation_notification.verified": {
+ "defaultMessage": "Verified"
+ },
"account_detail.title.account_details": {
"defaultMessage": "Account Details"
},