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)