In the previous lesson we handled submission in formik form. In this lesson, our primary focus will be on presenting cart items within the checkout page.
Here's a breakdown of what we aim to achieve:
- Incorporate a dedicated section within the checkout page to exhibit products added to the cart, accompanied by their total price and any applicable discounts.
- Implement the functionality to persist user information provided through form in local storage.
Our initial step involves showcasing the details of each product. To accomplish this, we'll create a Product.jsx
file within the Checkout
directory.
The Product.jsx
file will house the Product
component responsible for displaying product images, names, and prices in card format within the checkout items section. This component will access the product quantity from useCartItemsStore
based on the product's slug, renaming it as selectedQuantity
. The quantity will be displayed as a tag at the top-right corner of the product image.
Let's add the following contents to the Product.jsx
:
Next, we aim to display the total price and any applicable discounts below the product details. For this purpose, we'll create a reusable component called PriceEntry
to exhibit charges and their respective costs. To create the file for this component, run the following command:
The PriceEntry.jsx
file will contain the presentation logic for the PriceEntry
component:
Now, let's consolidate all these components into a new component named Items.jsx
. Begin by creating a Items.jsx
file within the Checkout
directory. Run the following command from the project root to generate this file:
Within the newly created file, we will define the Items
component. This component will use useCartItemsStore
to fetch the slugs of the cart items. These slugs will then be used to retrieve product details using the useFetchCartProducts
hook. Additionally, the cartTotalOf
function will be utilized to display the subtotal and total payable amount.
Add the translation keys subtotal
, deliveryCharges
and totalPayablePrice
to the en.json
file.
To enhance the user experience, we will relocate the submit button from index.jsx
to Items.jsx
.
Next, we'll invoke the Items
component inside the Checkout
component, passing along the isSubmitDisabled
prop.
Let's also update the isLoading
logic to accommodate the delay in fetching cart products. We will also add a logic to redirect the user to the home page if cartItems
is empty.
Now, we will introduce a functionality allowing users to optionally preserve their form information by storing it in local storage. First, we will define two utility functions in src/utils/storage.js
to aid the implementation of our feature: setToLocalStorage
and getFromLocalStorage
.
Generate the storage.js
file by executing the following command:
The setToLocalStorage
function enables the storage of serialized data under a specific key in the local storage. If the provided value isn't null
, it's transformed into a string using JSON.stringify()
and stored in the designated key. If the value is null
, the corresponding key is removed from local storage using removeItem()
.
The getFromLocalStorage
function retrieves stored data from the local storage based on the provided key. It attempts to parse the stored value using JSON.parse()
. If the parsing succeeds, it returns the parsed value; otherwise, it returns null
. This function is enclosed in a try...catch block to handle parsing errors gracefully.
We will also add a key to the constants.js
file to facilitate storing and retrieving data.
Now, let's add the feature to retain user information provided via form. This is achieved through the utilization of the Checkbox
component, accessed via the checkboxRef
reference.
During form submission, when the checkbox is marked, the form data is preserved by storing it in local storage, against the key CHECKOUT_LOCAL_STORAGE_KEY
, using the setToLocalStorage
function. Conversely, if the checkbox is left unchecked, no data is stored, and dataToPersist
is set to null
.
If there is previously stored data in local storage for the checkout form, the getFromLocalStorage
function retrieves this data, holding it in the checkoutFormData
variable. This retrieved data is then employed as the initial values for the checkout form. The purpose of checkoutFormData
is to ensure that if a user has previously completed the checkout form and chosen to save that information, the form will load with their saved data upon revisiting the page.
Finally, we'll include the saveInformationForNextTime
translation key in the en.json
file.
That concludes the implementation of the checkout page. Let's commit the new changes:
You can verify the changes here.