Build an inventory management app with Azure Static Web Apps with + React, part 2
Tags: staticwebapps, webdev, javascript, tutorial
Published: 2022-05-11 21:57:24

---
title: Build an inventory management app with Azure Static Web Apps with + React, part 2
published: true
series: swareact
description: in this second part, you will build out your React app, add routing and styling and deploy your changes to Azure.
tags: staticwebapps, webdev, javascript, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tc5o6krm510oqbmpnuuq.jpg
---

This is part of #30DaysOfSWA.

> In this part, we will keep working on our inventory management system authored in React.

## Recap, from part I

What we have so far is a React we scaffolded in Snowpack. We've also managed to deploy it to Azure using Azure Static Web Apps service.

## What now - let's build the actual app

Ok, we have a React app but not really an inventory management system at this point. So, what do we need?

- A header
- A menu
- A main area
- Static data

## Select styling approach

I like to start with the CSS, for this I will use styled-components library, it just resonates with my way of thinking. Here's what CSS can look like expressed as a styled component:

```CSS
const Menu = styled.ul`
  list-style: none;
  padding: 0;
`;
```

Instead of a `ul` element, you can now type `Menu` and use that in your JSX.

## Routing

We need routing, to support the fact that we will use a menu with links that will show us different parts of our app.

For this we will use React Router.

1. Add these lines to your *package.json*:

   ```json
   "react-router": "6.3.0",
   "react-router-dom": "6.3.0", 
   ```

   Next, let's install these:

1. Run `npm install`:

   ```console
   npm install
   ```

   Now you will have the libraries needed to add routing to your app.

### Setup routing

You need to instruct your app at high-level to use routing. We therefore start with *index.jsx*.

1. Change *index.jsx* ensure it looks like so:

    ```javascript
    import React from "react";
    import ReactDOM from "react-dom";
    import { BrowserRouter } from "react-router-dom";
    
    import "./index.css";
    import App from "./App";
    
    ReactDOM.render(
      <React.StrictMode>
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </React.StrictMode>,
      document.getElementById("root")
    );
    ```

Above, we use `BrowserRouter` and encapsulates the `App` component.

1. Change the `App` component in `App.jsx` to look like so:

    ```javascript
    export default function App() {
      return (
        <div>
          
          <Routes>
            <Route path="/" element={<Layout />}>
              <Route index element={<Home />} />
              <Route path="about" element={<About />} />
              <Route path="products/:id" element={<Product />} />
              <Route path="products" element={<ProductList />} />
              <Route path="dashboard" element={<Dashboard />} />
              <Route path="*" element={<NoMatch />} />
            </Route>
          </Routes>
        </div>
      );
    }
    ```

Above, we have setup the routes and which elements should handle a route request. `path` defines the route pattern, and `element` is the component that will handle the request.

We haven't created these components yet, but we will :)

We need to create a layout component; it will constitute of our menu and an area where content is loaded as soon as we select a link.

1. Add the following component `Layout`:

    ```javascript
    function Layout() {
      return (
        <Overview>
          <Header>Welcome to Inventory management system!</Header>
          <Navigation>
            <Menu>
              <Item>
                <NavLink to="/" className={({ isActive }) => (isActive ? 'active' : 'inactive')}  >Home</NavLink>
              </Item>
              <Item>
                <NavLink to="/about" className={({ isActive }) => (isActive ? 'active' : 'inactive')} >About</NavLink>
              </Item>
              <Item>
                <NavLink to="/products" className={({ isActive }) => (isActive ? 'active' : 'inactive')} >Products</NavLink>
              </Item>
              <Item>
                <NavLink to="/dashboard" className={({ isActive }) => (isActive ? 'active' : 'inactive')} >Dashboard</NavLink>
              </Item>
              <Item>
                <NavLink to="/nothing-here" className={({ isActive }) => (isActive ? 'active' : 'inactive')} >Nothing here</NavLink>
              </Item>
            </Menu>
          </Navigation>
    
          <hr />
          <Content>
            <Outlet />
          </Content> 
          
        </Overview>
      );
    }
    ```

1. Now add some styling above all components:

    ```css
    const Header = styled.h1`
      display: block;
      background: DarkRed;
      color: Wheat;
      width: 100%;
      grid-row: 1;
      padding: 20px 10px;
      font-size: 16px;
      grid-column-start: 1;
      grid-column-end: 3;
      margin: 0;
    `;
    
    const Navigation = styled.nav`
      width: 200px;
      background: DarkSlateGrey;
      grid-row:2;
      grid-column: 1;
    `;
    
    const Content = styled.div`
      grid-row:2;
      grid-column: 2;
      padding: 20px;
    `;
    
    const Overview = styled.div`
      display: grid;
      grid-template-rows: 60px 100%;
      grid-template-columns: 200px 100%;
      width: 100vw;
      height: 100vh;
    `;
    
    const Menu = styled.ul`
      list-style: none;
      padding: 0;
    `;
    const Item = styled.li`
     margin: 10px 0px;
     
     a {
       padding: 10px 5px;
       display: block;
       color: white;
       text-decoration: none;
     }
    `;
    ```

    We use a grid system for our header, left menu and main content area.

1. Finally, add some styling to *index.css*:

   ```css
   li>a.active {
      font-weight: bold;
      border-right: solid 10px red;
    }
   ```

   This will ensure that a selected menu item has visual indicator when a specific link has been chosen.

## Create components

Now, we need to create the components we mentioned when we configured routing in *App.jsx*.

Create a *Pages* directory and create the following:

1. Create *About.jsx* with the following content:

   ```javascript
    import * as React from "react";

    function About() {
      return (
        <div>
          <h2>About</h2>
        </div>
      );
    }
    
    export default About;
   ```

1. Create *Dashboard.jsx* with the following content:

   ```javascript
    import * as React from "react";

    function Dashboard() {
      return (
        <div>
          <h2>Dashboard</h2>
        </div>
      );
    }
    
    export default Dashboard;
   ```

1. Create *Home.jsx* with the following content:

   ```javascript
    import * as React from "react";

    function Home() {
      return (
        <div>
          <h2>Home</h2>
        </div>
      );
    }
    
    export default Home;
   ```

1. Create *NoMatch.jsx* with the following content:

   ```javascript
    import * as React from "react";

    import { Link } from "react-router-dom";
    
    function NoMatch() {
      return (
        <div>
          <h2>Nothing to see here!</h2>
          <p>
            <Link to="/">Go to the home page</Link>
          </p>
        </div>
      );
    }
    
    export default NoMatch;
   ```

1. Create *Product.jsx* with the following content:

   ```javascript
    import * as React from "react";

    import { useParams, Link } from "react-router-dom";
    
    function Product() {
      let { id } = useParams();
    
      return (
        <React.Fragment>
          <div>Product item {id}</div>
          <div>
            <Link to="/products">Back to product list</Link>
          </div>
    
        </React.Fragment>
    
      );
    }
    
    export default Product;
   ```

1. Create *ProductList.jsx* with the following content:

   ```javascript
    import * as React from "react";

    import styled from "styled-components";
    import { Link } from "react-router-dom";
    
    const ProductsContainer = styled.div`
      display:flex;
      width: 100%;
      flex-orientation: row;
      flex-wrap: wrap;
      width: 800px;
    `;
    
    const ProductQuantity = styled.div`
      font-size: 40px;
      grid-row:1;
      color: white;
    `;
    
    const ProductName = styled.div`
      grid-row:2;
      color: white;
    `;
    
    const ProductItem = styled.div`
      padding: 20px 10px;
      box-shadow: 0 0 5px grey;
      margin: 5px;
      background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 10%, rgba(0,212,255,1) 100%);
      a {
        color: white;
      }
    
      width: 200px;
      height: 100px;
      display: grid;
      grid-template-rows: 50% 50%;
    }
    `;
    
    const products = [{
      id: 1,
      name: "Nuts",
      quantity: 30
    },
    {
      id: 2,
      name: "Bolts",
      quantity: 20
    },
    {
      id: 3,
      name: "Screw drivers",
      quantity: 5
    },
    {
      id: 4,
      name: "Hammers",
      quantity: 5
    }]
    
    function ProductList() {
      const data = products.map(p => <ProductItem>
        <ProductQuantity>{p.quantity}</ProductQuantity>
        <ProductName>
         <Link to={`/products/${p.id}`}>
          {p.name}
          </Link>
        </ProductName>
    
      </ProductItem>);
      return (
        <ProductsContainer>{data}</ProductsContainer>
      );
    }
    
    export default ProductList;
   ```

### Try out the app

At this point, you have built out the app, let's look.

1. Run `npm start`:

   ```console
   npm start
   ```

   ![an app with a left menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9mb0tckokqinsptr6zwo.png)

## Deploy

Our app is already connected to Azure Static Web Apps, and this is the beautiful part, all we need to deploy our changes is to run some git commands.

1. Run the following git commands to push your changes to Azure:

   ```console
   git add .
   git commit -m "new changes"
   git push
   ```

1. Now go to your repo on GitHub and the **Actions**, once it finished, in 1-2 minutes, you will see your app deployed on Azure. 

## Inspect your changes

Go to your app online to ensure changes are there. 

1. A way to find the URL is to go via Visual Studio Code, and the Azure extension > Azure Static Web Apps and right-click your app and select **Browse Site**. 

1. Try clicking **Products** in the left menu, now reload the page, you got a 404 right?

   This is because of how routing is setup in your app. Don't worry, we can fix this:

1. Create *staticwebapp.config.json* and give it the following content:

   ```json
   
      "navigationFallback": {
        "rewrite": "/index.html"
      }
    }
   ```

   What you are saying here is let Azure Static Web Apps handle routes to /Products and /About etc and redirect it to *index.html*. Your React will now how to deal with these routes from here.

1. Add and push your changes:

   ```console
   git add .
   git commit -m "adding navigation fallback"
   git push
   ``` 

   If you verify your deploy this time, it doesn't fail if you navigate to /products and reload, does it?  :) 

## Solution

Have a look at this repo [repo](https://github.com/softchris/snowpack-demo)

## Summary

Congrats, you managed to build a React app and deploy your changes to Azure and using Azure Static Web Apps.

In the third part we will add an API, because right now we have static products list and that's great for prototyping but not for a real app.