Repos that we’ll change
Whitelabel: https://github.com/rbilabs/intl-whitelabel-app
RBI Sanity Shared Schemas: https://github.com/rbilabs/rbi-sanity-shared-schemas
Whitelabel CMS: https://github.com/rbilabs/intl-whitelabel-cms
Solution overview
All the solution is based on the AddOn (add extras items) that already exists in the Whitelabel code! To make this work for our case will develop a generic feature that is based on some parts of the “Add extra” feature. We’ll use the useFeatureMenuAddOn
and the useCartAddOns
to make it easy and reduce the complexity of dealing with the cart orchestration:
We’ll use the AddOn document from Sanity and add a new toggle and object block (for service modes). This will make our feature generic and independent from the bag solution (take a look at the Sanity task for more details).
With this suggestion of implementation, we’re getting free all the order flow:
Receipt already implemented for extra items:
The implementation for the added extra item to the “Your cart” section
A modal to edit the extra item
The item added to the cart on the home page
The original “Add extra” feature working (that will give us what was shown above for free):
Figma and behavior
Figma was not made following the application consistency. I talked with our designers and we’ll follow the Upsell feature visual and behavior. Example of the Upsell behavior (visual styles and add/remove from the cart):
Layout position for desktop:
Your new sections and items will be above the “Add to Order” section. If the “Add to Order” is not enabled our feature will be in her place
Task summary
RBI Sanity Shared Schemas/Whitelabel CMS:
Task 1: Add a new toggle to show the addOn section as cart items and add service modes selection
Whitelabel:
Task 1: Create a new feature flag (
enable-add-on-as-cart-item
)This flag will condition the exhibition of the new item in the cart.
Task 2: Update types and graphql after changes in the CMS repo
Task 3: Refactor
UpsellItem
comp to be a generic item for the cartThis item will be used in Upsell and in our new AddOnsItemsContainer
Task 4: Create the new component for AddOnsItemsContainer
Task 5: Add the AddOnsItemsContainer to the cart-content
Tasks breakdown
RBI Sanity Shared Schemas
Task 1: Add a new toggle to show the addOn section as cart items and add service modes selection
Motivation: the toggle will help us on the FE logic to show in the cart (as cart items) only sections that have this toggle set as TRUE. Besides that, we’ll need to give to the user the power to choose in what service mode they want to show the items. If nothing is selected the section items will be available for all service modes.
For the field “Show section items in cart”:
Base interface:
{ title: 'Show section items in cart', description: 'All the items from this section will be available directly in the cart. The section name will be the header title', name: 'showSectionItemsOnCart', type: 'boolean', initialValue: false, hidden: () => ctx.isUS validation: ... }
The
hidden
key will be important to not show the toggle for the US marketUse the validation field and add logic to show an error in Sanity if this toggle is false but has some service mode selected
For the “Service Modes” toggles:
Base interface:
{ title: 'Service Modes', description: 'If nothing is selected the section items will be available for all services mode. If select one or more options then the items will be shown just for these options', name: 'sectionItemsServiceModes', type: 'object', fields: [ { title: 'Pick Up', name: 'pickUpServiceMode', type: 'boolean', }, ... and so on ], hidden: hideIfNoShowSectionItemsOnCart, }
We need to use the
hidden
key here to hide this section if the toggle is off.
Suggested “name” for the others: driveThruServiceMode
, curbsideServiceMode
, dineInServiceMode
, tableServiceMode
.
Tips:
To test this locally we’ll need to follow the steps in the Shared Schemas repo:
I really recommend that after opening the PR we ask Posk, Mitchell (Deactivated) for a Code Review. He’ll help us to see if all is good with our changes!
Task objectives (DOD-like):
Add the new toggle and service modes section in the Shared Schemas repo and test locally with the Whitelabel cms
We’ll add the toggle in the following file: https://github.com/rbilabs/rbi-sanity-shared-schemas/blob/main/src/schemas/menu/documents/add-on-section.tsx
Open the PR and make the merge
After the update of the package Shared Schemas, update the package.json in the Intl-whitelabel-cms repo. Run the cms locally to see if the toggle will be shown in the AddOn Section (without using the yarn link). Open the PR for the Whitelabel cms.
Whitelabel
Task 2: Update the graphql after changes in the CMS repo
Update the package.json with the new version for the Intl-whitelabel-cms
Add the new interfaces in the
add-on-section.graphql
Path:
src/queries/sanity/fragments/add-on-section.graphql
fragment AddOnSectionFragment on AddOnSection { ... showSectionItemsOnCart sectionItemsServiceModes { pickUpServiceMode driveThruServiceMode curbsideServiceMode dineInServiceMode tableServiceMode } }
yarn run apollo:generate
Clear the generated file just with the needed changes
Update the Interface for the
use-feature-menu-add-on.tsx
Path:
src/hooks/use-feature-menu-add-on.tsx
export interface IAddOnSection { ..., showSectionItemsOnCart: boolean, sectionItemsServiceModes: { pickUpServiceMode: boolean, driveThruServiceMode: boolean, curbsideServiceMode: boolean, dineInServiceMode: boolean, tableServiceMode: boolean, } }
Task 3: Refactor UpsellItem comp to be a generic item for the cart
We’ll refactor the UpsellItem to be a generic cart item component and with this, we’ll be able to use this comp in the Upsell itself and also in our new component.
file: src/pages/cart/upsell/upsell-item.tsx
Motivation:
UI reuse and consistency
Our component and the Upsell will be dealing with items from Sanity. This
UpsellItem
already has all the logic to show important info from an item (like calories, price, and other info). Less complexity to think about
Architecture changes:
Before
After
Task objectives (DOD-like):
Change the
upsell-item.tsx
em rename all the references of the word "upsell" to be "cart"... Ex:cart-item.tsx
(instead ofupsell-item.tsx
)Move necessary styles to the new folder cart-item
Adjust the interface of the comp in a way that the param for the item is optional now
Remember: to adjust the logic that executes the addToCard to pass the item only if received
Motivation: This is necessary because for our new component, we’ll not need to pass the item but we need to maintain this for the upsell logic.
Remember to adjust the
data-testid
that already exists and the unit testsAdjust the
upsell.stories
to use the new cart-item thereGood to have: remove the use of
React.FC
from there and type in the right way
Task 4: Create the new component for AddOnsItemsContainer
This component will be responsible to render the cart-item
and also holding the integration with the hooks that we'll need (the container will also be responsible for the business requirements).
Used Hooks: useCartAddOns
and useFeatureMenuAddOn
Used Components: cart-item.tsx
from task 2.
This component will also have the tags and the styles to be able to render the title and item like the upsell that we have today:
Architecture:
Task objectives (DOD-like):
Create the new
AddOnItemsContainer
Use and integrate into the component the
useFeatureMenuAddOn
and theuseCartAddOns
hooksAdjust the UI of the component to show the items and title as shown above in the “Add to Order” example
Condition to show the section only if
showSectionItemsOnCart
is TRUECondition to hide the section item if:
Section item was added in cart (cartEntries) and doesn’t have items after adding the last item
Hide the item after adding it to the cart (your cart). We’ll need to look at the
cartEntries
prop valueCondition to show section if service mode from sanity is null/undefined OR the selected service mode is equal to the checked ones from Sanity
Map the sections that have
showSectionItemsOnCart
= TRUE and pass the mapped value to theinitialSelections
inuseCartAddOns
(we can also use theupdateQuantityForItem
but I think that this path will be more complex)Extend the
handleAddToCart
to receive theupdatedItem
as a param and add a new logic to not add all theinitialSelections
when we click to add a specific item to the cart
Implement the unit tests
Task 5: Add the AddOnsItemsContainer to the cart-content
This is an integration task.
The AddOnsItemsContainer will be added to the cart-content.tsx
component.
File: src/pages/cart/cart-content.tsx
Test file: src/pages/cart/tests/cart-content.test.tsx
CSS Grid and items position:
Files:
Content style:
src/pages/cart/content/index.ts
JavaScript logic to mount grid-template-areas:
src/pages/cart/content/styles.ts
Challenge:
Adjust the JavaScript logic to be dynamic based on the number of sections that will be shown in the cart
We’ll have a new item in the grid-template-areas but we don’t know how many items can be there. This will depend on what the user has chosen in Sanity configurations.
Task objectives (DOD-like):
Add the new comp in the
cart-content.tsx
Condition the new component based on the feature flag created in Task 1
Add a new integration test on the cart-content test
Adjust the CSS GRID to be dynamic based on the sections configured to be shown in the cart as items
Adjust the unit test on
src/pages/cart/content/tests/content.test.tsx
Behavior acceptance
Only sections with
showSectionItemsOnCart
= TRUE on Sanity should be shown in the cartThis will not remove the item from the original “+ Add extras” feature
If the feature flag is OFF all the feature will be OFF
If the user did not select any service mode on Sanity we’ll show the section and item for all the available service modes. If the user selects one or more service modes on Sanity we’ll only show the feature for that options
The item should have the same style as the Upsell feature (title and button styles)
When we click to add an item the item should be sent to the “Your cart” section with 1x in the quantity and after that should not be shown in the cart as an item as before
If we click on the “remove” button on the added item in the “Your cart” section the item should be removed from the “Your cart” section and appear again in the cart section
If the section has only one item remaining the entire section should be hidden/removed from the screen
If the rendered section has only one item the visual should be as described above on task 4. If have more than one item the items should be presented horizontally with a scroll as the upsell feature
For this new feature, we are using a good part of the “AddOn” feature which means:
We don't need to deal with item updates after adding the first time on the cart. Your only objective here is to add the first item successfully)
We can’t edit directly the item quantity (as in the upselll feature) because of the way that the “AddOn” feature works. The items will be considered “extra items” by the application and to be able to edit the item we need to click on the “edit” button and change the quantity in the extra modal
All the logic for the “reordering”, “receipt”, “receipt email”, and etc, are already implemented by the “AddOn” feature… we're getting it for free 😃
Add Comment