From 05f2e55b9b501af3d07ecf1f57b0f98d136e33d6 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Tue, 7 Jan 2025 15:13:24 -0500 Subject: [PATCH 01/14] add radio buttons for each store --- .../store-locator-modal/stores-list.jsx | 137 ++++++++++-------- 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index d417af448d..fac6a14d99 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -5,7 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import React from 'react' +import React, {useState} from 'react' import {useIntl} from 'react-intl' import PropTypes from 'prop-types' @@ -15,78 +15,87 @@ import { AccordionButton, AccordionIcon, AccordionPanel, - Box + Box, + Radio, + RadioGroup } from '@salesforce/retail-react-app/app/components/shared/ui' const StoresList = ({storesInfo}) => { const intl = useIntl() + const [selectedStore, setSelectedStore] = useState('') - return storesInfo?.map((store, index) => { - return ( - - - {store.name ? {store.name} : ''} - - {store.address1} - - - {store.city}, {store.stateCode ? store.stateCode : ''} {store.postalCode} - - {store.distance !== undefined ? ( - <> -
+ return ( + + {storesInfo?.map((store, index) => { + return ( + + + + {store.name ? {store.name} : ''} - {store.distance} {store.distanceUnit}{' '} - {intl.formatMessage({ - id: 'store_locator.description.away', - defaultMessage: 'away' - })} + {store.address1} - - ) : ( - '' - )} - {store.phone !== undefined ? ( - <> -
- {intl.formatMessage({ - id: 'store_locator.description.phone', - defaultMessage: 'Phone:' - })}{' '} - {store.phone} + {store.city}, {store.stateCode ? store.stateCode : ''}{' '} + {store.postalCode} - - ) : ( - '' - )} - {store?.storeHours ? ( - <> - {' '} - - - {intl.formatMessage({ - id: 'store_locator.action.viewMore', - defaultMessage: 'View More' - })} - - - - -
- {' '} - - ) : ( - '' - )} - - - ) - }) + {store.distance !== undefined ? ( + <> +
+ + {store.distance} {store.distanceUnit}{' '} + {intl.formatMessage({ + id: 'store_locator.description.away', + defaultMessage: 'away' + })} + + + ) : ( + '' + )} + {store.phone !== undefined ? ( + <> +
+ + {intl.formatMessage({ + id: 'store_locator.description.phone', + defaultMessage: 'Phone:' + })}{' '} + {store.phone} + + + ) : ( + '' + )} + {store?.storeHours ? ( + <> + {' '} + + + {intl.formatMessage({ + id: 'store_locator.action.viewMore', + defaultMessage: 'View More' + })} + + + + +
+ {' '} + + ) : ( + '' + )} + + + ) + })} + + ) } StoresList.propTypes = { From 1247e540028983ab37d7928a7db49f732c15a9f4 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Tue, 7 Jan 2025 16:17:40 -0500 Subject: [PATCH 02/14] save store data in loca storage --- .../store-locator-modal/stores-list.jsx | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index fac6a14d99..b1e4560876 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -20,12 +20,32 @@ import { RadioGroup } from '@salesforce/retail-react-app/app/components/shared/ui' +// Hooks +import useMultiSite from '@salesforce/retail-react-app/app/hooks/use-multi-site' + const StoresList = ({storesInfo}) => { const intl = useIntl() + const {site} = useMultiSite() const [selectedStore, setSelectedStore] = useState('') + const handleChange = (storeId) => { + setSelectedStore(storeId) + const store = storesInfo.find((store) => store.id === storeId) + window.localStorage.setItem( + `store_${site.id}`, + JSON.stringify({ + id: storeId, + name: store.name, + inventoryId: store.inventoryId || null, + postalCode: store.postalCode, + latitude: store.latitude, + longitude: store.longitude + }) + ) + } + return ( - + {storesInfo?.map((store, index) => { return ( From 6cf11ec671b5c5aba009725ce1091648b2eef83c Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Thu, 9 Jan 2025 13:24:38 -0500 Subject: [PATCH 03/14] align radio button to store name --- .../store-locator-modal/stores-list.jsx | 124 +++++++++--------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index b1e4560876..d46b31cefc 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -16,6 +16,7 @@ import { AccordionIcon, AccordionPanel, Box, + HStack, Radio, RadioGroup } from '@salesforce/retail-react-app/app/components/shared/ui' @@ -49,68 +50,73 @@ const StoresList = ({storesInfo}) => { {storesInfo?.map((store, index) => { return ( - - - {store.name ? {store.name} : ''} - - {store.address1} - - - {store.city}, {store.stateCode ? store.stateCode : ''}{' '} - {store.postalCode} - - {store.distance !== undefined ? ( - <> -
- - {store.distance} {store.distanceUnit}{' '} - {intl.formatMessage({ - id: 'store_locator.description.away', - defaultMessage: 'away' - })} - - - ) : ( - '' - )} - {store.phone !== undefined ? ( - <> -
- - {intl.formatMessage({ - id: 'store_locator.description.phone', - defaultMessage: 'Phone:' - })}{' '} - {store.phone} - - - ) : ( - '' - )} - {store?.storeHours ? ( - <> - {' '} - - + + + + {store.name ? {store.name} : ''} + + {store.address1} + + + {store.city}, {store.stateCode ? store.stateCode : ''}{' '} + {store.postalCode} + + {store.distance !== undefined ? ( + <> +
+ + {store.distance} {store.distanceUnit}{' '} {intl.formatMessage({ - id: 'store_locator.action.viewMore', - defaultMessage: 'View More' + id: 'store_locator.description.away', + defaultMessage: 'away' })} - -
- -
- {' '} - - ) : ( - '' - )} - + + ) : ( + '' + )} + {store.phone !== undefined ? ( + <> +
+ + {intl.formatMessage({ + id: 'store_locator.description.phone', + defaultMessage: 'Phone:' + })}{' '} + {store.phone} + + + ) : ( + '' + )} + {store?.storeHours ? ( + <> + {' '} + + + {intl.formatMessage({ + id: 'store_locator.action.viewMore', + defaultMessage: 'View More' + })} + + + + +
+ {' '} + + ) : ( + '' + )} + + ) })} From f42ed1c72fc3a4a88d9481798d8f197a31dd1a41 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Thu, 9 Jan 2025 13:36:04 -0500 Subject: [PATCH 04/14] keep selected store selected --- .../components/store-locator-modal/stores-list.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index d46b31cefc..fb5f0dd16d 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -27,20 +27,20 @@ import useMultiSite from '@salesforce/retail-react-app/app/hooks/use-multi-site' const StoresList = ({storesInfo}) => { const intl = useIntl() const {site} = useMultiSite() - const [selectedStore, setSelectedStore] = useState('') + const storeInfoKey = `store_${site.id}` + const [selectedStore, setSelectedStore] = useState( + JSON.parse(window.localStorage.getItem(storeInfoKey))?.id || '' + ) const handleChange = (storeId) => { setSelectedStore(storeId) const store = storesInfo.find((store) => store.id === storeId) window.localStorage.setItem( - `store_${site.id}`, + storeInfoKey, JSON.stringify({ id: storeId, - name: store.name, + name: store.name || null, inventoryId: store.inventoryId || null, - postalCode: store.postalCode, - latitude: store.latitude, - longitude: store.longitude }) ) } From 48299f666823856126a5f417e5933239eb7fabee Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Thu, 9 Jan 2025 14:10:01 -0500 Subject: [PATCH 05/14] ensure the description of the store is described when radio button is selected --- .../app/components/store-locator-modal/stores-list.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index fb5f0dd16d..a6f82a9d12 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -51,8 +51,8 @@ const StoresList = ({storesInfo}) => { return ( - - + + {store.name ? {store.name} : ''} {store.address1} From 469ec2c2869cff7a2397f745e24ed7c16ebbf3fc Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Thu, 9 Jan 2025 15:17:52 -0500 Subject: [PATCH 06/14] add unit tests --- .../store-locator-modal/stores-list.test.jsx | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.test.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.test.jsx index 6d00517745..a326ef38c0 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.test.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.test.jsx @@ -8,9 +8,10 @@ import React from 'react' import StoresList from '@salesforce/retail-react-app/app/components/store-locator-modal/stores-list' import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils' -import {waitFor, screen} from '@testing-library/react' +import {waitFor, screen, fireEvent} from '@testing-library/react' import userEvent from '@testing-library/user-event' import {Accordion} from '@salesforce/retail-react-app/app/components/shared/ui' +import mockConfig from '@salesforce/retail-react-app/config/mocks/default' const mockSearchStoresData = [ { @@ -73,10 +74,9 @@ const mockSearchStoresData = [ distance: 81.1, distanceUnit: 'km', id: '00021', - inventoryId: 'inventory_m_store_store13', latitude: 49.4077, longitude: 8.6908, - name: 'Heidelberg Tech Mart', + name: 'Store with no inventoryId', phone: '+49 6221 123456', posEnabled: false, postalCode: '69117', @@ -104,18 +104,26 @@ describe('StoresList', () => { ) + expect(screen.queryAllByRole('radio')).toHaveLength(mockSearchStoresData.length) + await waitFor(async () => { - const aStoreName = screen.getByText(/Wiesbaden Tech Depot/i) - const aStoreAddress = screen.getByText(/Kirchgasse 12/i) - const aStoreCityAndPostalCode = screen.getByText(/Wiesbaden, 65185/i) - const aStoreDistance = screen.getByText(/0.74 km away/i) - const aStorePhoneNumber = screen.getByText(/49 611 876543/i) - - expect(aStoreName).toBeInTheDocument() - expect(aStoreAddress).toBeInTheDocument() - expect(aStoreCityAndPostalCode).toBeInTheDocument() - expect(aStoreDistance).toBeInTheDocument() - expect(aStorePhoneNumber).toBeInTheDocument() + mockSearchStoresData.forEach((store) => { + const storeName = screen.getByText(store.name) + const storeAddress = screen.getByText(store.address1) + const storeCityAndPostalCode = screen.getByText( + `${store.city}, ${store.postalCode}` + ) + const storeDistance = screen.getByText( + `${store.distance} ${store.distanceUnit} away` + ) + const storePhoneNumber = screen.getByText(`Phone: ${store.phone}`) + + expect(storeName).toBeInTheDocument() + expect(storeAddress).toBeInTheDocument() + expect(storeCityAndPostalCode).toBeInTheDocument() + expect(storeDistance).toBeInTheDocument() + expect(storePhoneNumber).toBeInTheDocument() + }) }) }) @@ -169,4 +177,23 @@ describe('StoresList', () => { expect(positions).toEqual([...positions].sort((a, b) => a - b)) }) }) + + test('Can select store', async () => { + renderWithProviders( + + + + ) + + await waitFor(async () => { + const {id, name, inventoryId} = mockSearchStoresData[1] + const radioButton = screen.getByDisplayValue(id) + fireEvent.click(radioButton) + + const expectedStoreInfo = {id, name, inventoryId} + expect(localStorage.getItem(`store_${mockConfig.app.defaultSite}`)).toEqual( + JSON.stringify(expectedStoreInfo) + ) + }) + }) }) From 8bd458ec49272dbae15981675c69cf45d8562ad6 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Thu, 9 Jan 2025 15:17:57 -0500 Subject: [PATCH 07/14] lint --- .../app/components/store-locator-modal/stores-list.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index a6f82a9d12..4fca780f82 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -40,7 +40,7 @@ const StoresList = ({storesInfo}) => { JSON.stringify({ id: storeId, name: store.name || null, - inventoryId: store.inventoryId || null, + inventoryId: store.inventoryId || null }) ) } @@ -51,7 +51,11 @@ const StoresList = ({storesInfo}) => { return ( - + {store.name ? {store.name} : ''} From 672845601ac73bb425bf43b3de8fb869c52b3caa Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Fri, 10 Jan 2025 10:51:32 -0500 Subject: [PATCH 08/14] fix margin --- .../app/components/store-locator-modal/stores-list.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index 4fca780f82..a93ce22b67 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -50,10 +50,10 @@ const StoresList = ({storesInfo}) => { {storesInfo?.map((store, index) => { return ( - + From 5faed18d378a65e234d5f98f2e9dddae5f425d4e Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Fri, 10 Jan 2025 10:59:14 -0500 Subject: [PATCH 09/14] fix margin so that if there is a view more or isn't the bottom margin is the same --- .../app/components/store-locator-modal/stores-list.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index a93ce22b67..2de0638f61 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -50,7 +50,7 @@ const StoresList = ({storesInfo}) => { {storesInfo?.map((store, index) => { return ( - + { {' '} {intl.formatMessage({ From 868d129f6ee0353c26cbfbe5aeaf1a7f53a5e3b7 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Fri, 10 Jan 2025 13:18:20 -0500 Subject: [PATCH 10/14] fix bug with window being undefined in the store-locator page --- .../app/components/store-locator-modal/stores-list.jsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index 2de0638f61..9e6aac3e04 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -5,7 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import React, {useState} from 'react' +import React, {useEffect, useState} from 'react' import {useIntl} from 'react-intl' import PropTypes from 'prop-types' @@ -28,9 +28,11 @@ const StoresList = ({storesInfo}) => { const intl = useIntl() const {site} = useMultiSite() const storeInfoKey = `store_${site.id}` - const [selectedStore, setSelectedStore] = useState( - JSON.parse(window.localStorage.getItem(storeInfoKey))?.id || '' - ) + const [selectedStore, setSelectedStore] = useState('') + + useEffect(() => { + setSelectedStore(JSON.parse(window.localStorage.getItem(storeInfoKey))?.id || '') + }, [storeInfoKey]) const handleChange = (storeId) => { setSelectedStore(storeId) From d73464de2015b16ddea5bd31b5fcc0e3cae4c428 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Wed, 15 Jan 2025 10:04:12 -0500 Subject: [PATCH 11/14] simplif null checks in store-lists --- .../components/store-locator-modal/stores-list.jsx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index 9e6aac3e04..98c3cde03b 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -59,7 +59,7 @@ const StoresList = ({storesInfo}) => { aria-describedby={`store-info-${store.id}`} > - {store.name ? {store.name} : ''} + {store.name && {store.name}} {store.address1} @@ -67,7 +67,7 @@ const StoresList = ({storesInfo}) => { {store.city}, {store.stateCode ? store.stateCode : ''}{' '} {store.postalCode} - {store.distance !== undefined ? ( + {store.distance !== undefined && ( <>
@@ -78,10 +78,8 @@ const StoresList = ({storesInfo}) => { })} - ) : ( - '' )} - {store.phone !== undefined ? ( + {store.phone && ( <>
@@ -92,10 +90,8 @@ const StoresList = ({storesInfo}) => { {store.phone} - ) : ( - '' )} - {store?.storeHours ? ( + {store.storeHours && ( <> {' '} { /> {' '} - ) : ( - '' )}
From abbb3b676e15085900f6dffc476d9a7dd8244093 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Thu, 16 Jan 2025 10:26:49 -0500 Subject: [PATCH 12/14] update changelog --- packages/template-retail-react-app/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/template-retail-react-app/CHANGELOG.md b/packages/template-retail-react-app/CHANGELOG.md index 297d4770ea..8359c9429b 100644 --- a/packages/template-retail-react-app/CHANGELOG.md +++ b/packages/template-retail-react-app/CHANGELOG.md @@ -1,6 +1,7 @@ ## v5.1.0-dev (TBD) - Fixed failing checkout tests [#2195](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2195) +- Allow store to be selectable in StoreLocator [#2187](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2187) - [BUG] Fixed "getCheckboxProps is not a function" when rendering checkout page in generated app.[#2140](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2140) - Replace transfer basket call with merge basket on checkout [#2138](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2138) From a6022539b505a61a0ef8933f936de1c7798fe9ae Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Fri, 17 Jan 2025 14:14:17 -0500 Subject: [PATCH 13/14] use sx instead of style --- .../app/components/store-locator-modal/stores-list.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index 98c3cde03b..19270ee868 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -96,7 +96,7 @@ const StoresList = ({storesInfo}) => { {' '} {intl.formatMessage({ From 33a631ff240963c4f317c2fe285d62ebfb8f6ca6 Mon Sep 17 00:00:00 2001 From: Jinsu Ha Date: Tue, 21 Jan 2025 13:24:24 -0500 Subject: [PATCH 14/14] change marginTop of radio button from 1.5px to 1px --- .../app/components/store-locator-modal/stores-list.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx index 19270ee868..a3fbd0a289 100644 --- a/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx +++ b/packages/template-retail-react-app/app/components/store-locator-modal/stores-list.jsx @@ -55,7 +55,7 @@ const StoresList = ({storesInfo}) => {