DEV Community

Cover image for SneakerShop Tutorial : Home Screen βœ¨πŸ‘Ÿβœ¨
Majuran SIVAKUMAR
Majuran SIVAKUMAR

Posted on • Edited on

SneakerShop Tutorial : Home Screen βœ¨πŸ‘Ÿβœ¨

Hello team πŸ‘‹, I hope you are all doing well!

In our last post, we made some great progress by configuring our project and successfully navigating between screens.

In today's post, we have some amazing things to showcase on our home screen!


HomeScreen


Home Screen 🏠

For the home screen, I want:

  • A simple header with the project name and a shopping bag icon displaying the number of products in the cart.
  • A button to navigate to Filter screen
  • A product list that includes a picture, model name, brand name, and price.

To populate this data, I created a JSON file that mocks an API fetch.

// /api/index.js
import { data } from "./data.json";

export const getProducts = () => Promise.resolve(data)
Enter fullscreen mode Exit fullscreen mode

The mock data object is like :

{
  "data": [
    {
      "id": 11,
      "brand": "Nike Sportswear",
      "model": "AIR FORCE 1",
      "imageUrl": "https://img01.ztat.net/article/spp-media-p1/b83f2fe8dfd14010b0f07f919710380d/64888efd8c034688aa9c7677151fba44.jpg",
      "price": 119.95,
      "description": "Duis consequat dui nec nisi volutpat eleifend. Donec ut dolor. Morbi vel lectus in quam fringilla rhoncus.",
      "color": [
        {
          "name": "White",
          "hex": "#ffffff"
        }
      ]
    },
    {
      "id": 9,
      "brand": "Nike Sportswear",
      "model": "DUNK RETRO SE DC",
      "imageUrl": "https://img01.ztat.net/article/spp-media-p1/d5bf785592bb477db8d8208c984dfc86/eee0aab7b764448ca86050955de6ee02.jpg",
      "price": 109.95,
      "description": "Duis consequat dui nec nisi volutpat eleifend. Donec ut dolor. Morbi vel lectus in quam fringilla rhoncus.",
      "color": [
        {
          "name": "Gray",
          "hex": "#808080"
        }
      ]
    },
// .... 
// I let you mock the data as you need
  ]
}
Enter fullscreen mode Exit fullscreen mode

The Home Screen becomes :

// /screens/HomeScreen.js
import React, { useEffect } from "react";
import { useNavigation } from "@react-navigation/native";
import { Text, SafeAreaView, View, ScrollView, TouchableOpacity, Image} from "react-native";
import { ShoppingBagIcon, AdjustmentsIcon } from "react-native-heroicons/outline";
import { useSelector, useDispatch } from "react-redux";

import { getProducts } from "../api";
import { nbItemsInCart } from "../store/features/cart/cartSlice";
import { selectNbOfFilters, selectProducts, setProducts } from "../store/features/products/productsSlice";

const HomeScreen = () => {
    // πŸ‘‰ get informations from store
  const products = useSelector(selectProducts);
  const itemsInCart = useSelector(nbItemsInCart);
  const filterItems = useSelector(selectNbOfFilters);
  const dispatch = useDispatch();
  const { navigate } = useNavigation();

  useEffect(() => {
    /* πŸ‘‰ Fetch data from api on init  */ 
    async function getData() {
      const datas = await getProducts();
      dispatch(setProducts(datas));
    }
    getData();
  }, []);

  const goToDetails = (item) => navigate("Detail", item);
  const goToCart = () => navigate("Cart");
  const goToFilter = () => navigate("Filter");

  return (
    <SafeAreaView className="bg-white">
      {/* πŸ‘‰ HEADER */}
      <View className="relative flex-row justify-between px-5 py-2">
        <Text className="uppercase text-xl font-bold">Sneakershop</Text>
        <TouchableOpacity onPress={goToCart}>
          <ShoppingBagIcon color="black" size="32" strokeWidth={1.5} />

          {/* πŸ‘‰ SHOW NUMBER OF ITEM IN CART */}
          {!!itemsInCart && (
            <View className="absolute bg-red-400 px-1 rounded-full bottom-0 right-0">
              <Text className="text-white text-xs font-bold">
                {itemsInCart}
              </Text>
            </View>
          )}
        </TouchableOpacity>
      </View>
      <View className="flex-row justify-between px-5 py-2 mb-2">
        <Text className="text-lg font-bold">Products</Text>
        <View className="flex-row justify-between">
{/* πŸ‘‰ Filter button to go to Filter Screen */}
          <TouchableOpacity
            className="relative border border-slate-400 p-1"
            onPress={goToFilter}
          >
            <AdjustmentsIcon color="black" size="30" strokeWidth="1.5" />
{/* πŸ‘‰ Show number of filter applied */}
            {!!filterItems && (
              <View className="absolute bg-slate-900 px-1 rounded-full -bottom-1 -right-1">
                <Text className="text-white text-xs font-bold">
                  {filterItems}
                </Text>
              </View>
            )}
          </TouchableOpacity>
        </View>
      </View>
{/* πŸ‘‰ ScrollView to show products */}
      <ScrollView className="h-full bg-white">
        <View className="flex flex-row flex-wrap justify-between pb-32 px-0.5">
{/* Map on products to show a product card*/}
          {products.map((item) => (
            <TouchableOpacity key={item.id} onPress={() => goToDetails(item)}>
              <View className="flex w-48 h-60 pb-4 bg-white">
                <View className="flex-1 bg-slate-200">
                  <Image
                    className="flex-1"
                    resizeMode="cover"
                    source={{
                      uri:
                        item.imageUrl +
                        "?imwidth=1080&filter=packshot&imformat=jpeg",
                    }}
                  ></Image>
                </View>
                <View className="p-1">
                  <Text className="uppercase text-s font-bold">
                    {item.model}
                  </Text>
                  <Text className="capitalize">{item.brand}</Text>
                  <Text className="text-xs text-slate-500 mt-1">
                    {item.price} €
                  </Text>
                </View>
              </View>
            </TouchableOpacity>
          ))}

          {products.length === 0 && <Text>No results</Text>}
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

export default HomeScreen;
Enter fullscreen mode Exit fullscreen mode

Next πŸ”œ

I'm really excited about the progress we're making and can't wait to see what we will accomplish next.

Now that our Home Screen is done, we are going to start the FilterScreen in next post πŸ”œ

Hopefully you enjoyed the article as wellβ€”if so, please let me know in the comment section below! πŸ’¬


Source code πŸ‘¨β€πŸ’»

Feel free to checkout the source code there πŸ‘‰ Github

Top comments (0)