Build an inventory management app with Azure Static Web Apps with + React, part 2

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 …


This content originally appeared on DEV Community and was authored by Chris Noring

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:

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:
   "react-router": "6.3.0",
   "react-router-dom": "6.3.0", 

Next, let's install these:

  1. Run npm install:
   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:

    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:

    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:

    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>
      );
    }
    
  2. Now add some styling above all components:

    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.

  3. Finally, add some styling to index.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:
    import * as React from "react";

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

    export default About;
  1. Create Dashboard.jsx with the following content:
    import * as React from "react";

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

    export default Dashboard;
  1. Create Home.jsx with the following content:
    import * as React from "react";

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

    export default Home;
  1. Create NoMatch.jsx with the following content:
    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:
    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:
    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:
   npm start

an app with a left menu

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:
   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.

  2. 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:

      "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:
   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

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.


This content originally appeared on DEV Community and was authored by Chris Noring


Print Share Comment Cite Upload Translate Updates
APA

Chris Noring | Sciencx (2022-05-11T21:57:24+00:00) Build an inventory management app with Azure Static Web Apps with + React, part 2. Retrieved from https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/

MLA
" » Build an inventory management app with Azure Static Web Apps with + React, part 2." Chris Noring | Sciencx - Wednesday May 11, 2022, https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/
HARVARD
Chris Noring | Sciencx Wednesday May 11, 2022 » Build an inventory management app with Azure Static Web Apps with + React, part 2., viewed ,<https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/>
VANCOUVER
Chris Noring | Sciencx - » Build an inventory management app with Azure Static Web Apps with + React, part 2. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/
CHICAGO
" » Build an inventory management app with Azure Static Web Apps with + React, part 2." Chris Noring | Sciencx - Accessed . https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/
IEEE
" » Build an inventory management app with Azure Static Web Apps with + React, part 2." Chris Noring | Sciencx [Online]. Available: https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/. [Accessed: ]
rf:citation
» Build an inventory management app with Azure Static Web Apps with + React, part 2 | Chris Noring | Sciencx | https://www.scien.cx/2022/05/11/build-an-inventory-management-app-with-azure-static-web-apps-with-react-part-2/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.