E-commerce Order Management Dashboard with Hasura and GraphQL
25
January
2022
Tutorial

E-commerce Order Management Dashboard with Hasura and GraphQL

E-commerce Order Management Dashboard with Hasura and GraphQL
Vihar Kurama
0
 minutes ↗
#
dashboard
#
graphql
#
open-source
#
developer-tools
Tutorial

GraphQL is a query language for APIs and a server-side runtime for executing queries using the system you define for your data. It provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

Today, developers spend a lot of time building internal applications, dashboards, and admin panels with GraphQL APIs as backend. But guess what? It’s now possible for you to write customizable applications with the ability to quickly prototype and deploy in a few minutes. With Appsmith, a low code app builder, you can build entirely customizable internal tools without spending too much time or effort.

In this blog, I am going to be building an e-commerce order management dashboard.

To build this app, we will connect Appsmith with a GraphQL API and build an interface that will fetch information from a database. We will use Hasura to create, manage, and customize GraphQL APIs.

Hasura is an open-source service that gives you production-grade GraphQL & REST APIs on your data instantly. It allows you to develop and deploy GraphQL APIs in minutes. At the core, Hasura helps you build APIs with a simple to use GraphQL composer and a GraphQL server that is stateless and blazing fast.

What exactly are we building?

By the end of the tutorial, we will have a fully customizable e-commerce order management dashboard! Typically, such dashboards enable the app users to:

  • Manage the entire product catalogue
  • View sales, track all details of total and recent orders
  • Send email to customers

Note: We will be using data from Hasura Super App, which can be found here. You can directly migrate the data here to your Hasura instance in just a few steps listed here: Moving from local development to staging and going production with Hasura.

Alternatively, you can connect to the instance we created for you to test and play with GraphQL APIs on Appsmith. These details of the instance are disclosed in the next section :)

All right, let's dive in!

Connect to Hasura on Appsmith with GraphQL

We will be connecting to the Hasura instance via the REST API datasource on Appsmith. For this, we will need the GraphQL API end-point and Admin Secret key from Hasura Dashboard. If you're using your instance, this is how your dashboard looks like, where you can copy the mentioned details.

hasura_dashboard.png
If you want to know more about the data schema and customize the relations between tables, you can always use Hasura cloud explorer.

Now, let's quickly take a look at all the tables that are available on Hasura Super App Dashboard in brief:

  • user: This table contains a list of all the customers who signed up for the Hasura super app.
  • address: The address tables contain all the user delivery addresses that will be further linked to the order.
  • admin: Details of all the super-admin who have access to all the dashboards
  • order: The order table contains all the order information a user places
  • order_product: This table contains a list of products that are included in the order
  • order_status: Contains details of order delivery status
  • product: Details of all the products on the e-commerce store
  • product_review: Reviews of products that the customers gave

Awesome, now that we had a glance at our tables, let's build the app! First up, we'll need an account on Appsmith Cloud. You can create it here for free if you don't have one. After we log in, we will be redirected to our dashboard to make a new Appsmith; this can be under any organization of your choice.

Now, to connect Hasura APIs, follow the below steps:

  • Click on the + icon next to datasources and choose Create new API under the Create New tab.
  • Rename the query to getProducts by double-clicking on the existing one.
  • Set the query type to POST, and paste the following URL:

https://subtle-platypus-36.hasura.app/v1/graphql

  • Under the headers pane, add the following key-values:

content-type: application/jso
x-hasura-admin-secret: <YOUR_SECRET_KEY>


  • Lastly, navigate to the Body property under the API pane, set the body type to JSON, and paste the following:
{{
JSON.stringify({
    variables: null,
    query: `
    query {
        product(limit: 300) {
            id
            brand
            category_display_name
            created_at
            description
            name
            image_urls
        }
}
`})
}}


Now, we can test this GraphQL query by clicking on the RUN button to the top-right of the application; with this, we should see all the products list from the backend in the response body.

Following is the screenshot:

GraphQL.png

Here, inside the body pane, we write the GraphQL query to fetch all the products; this is similar to how we do it on a regular GraphiQL playground.

Now let's bind this data onto the table widget.

  • For this, click on the + icon next to widgets and drag and drop a table widget onto the canvas.
  • Select the table on the canvas; this will open the property pane on the right sidebar; now, under table data, we bind the query using the moustache syntax:

{{ getproducts.data.data.product }}

  • And just like that, we should see all the data from the query binded onto the table.
  • Note that all the columns are not required for us. Hence, we can hide them by clicking on the eye-icon on the column name under the columns property.

Adding a New Product to Database

Doing a simple READ operation using Hasura's GraphQL API is easy now; let's look at how we can do a WRITE operation by building a form on Appsmith. Follow the below steps:

  • First, let's drag and drop a new button widget on the canvas; the idea is to open a modal and show a form to create a new product on the e-com store.
  • Next, add a text widget and a few form widgets on the modal by dragging and dropping them onto the modal from the widgets section.
  • We can also set the form's label by updating the label property from the form's property pane.

Following is a screenshot of how the form should look like:

form.png

Now, update the form names to the following to access them in the query:

You can update the widget names from the property pane by double-clicking on the existing one.
  • Name: getName
  • Description: getDescription
  • Category: getCategory
  • Brand: getBrand
  • Price: getPrice
  • ProductID: getID

Now, add a new button, update its label to Add Product, and set its onClick property to "Run a query" and choose Create a new API. This will create a new API datasource under the datasources section. Now, follow the below steps to create a new query that lets us post new data onto PostgresDB on Hasura.

  • Rename the query to addProduct
  • Update the URL to:

https://subtle-platypus-36.hasura.app/v1/graphql


  • Set the method type to POST, and copy the headers x-hasura-admin-secret, content-type from getProducts query to here.
  • Update the query body to the following:

{
    "query": {{JSON.stringify(`
    mutation ($object: insert_product_insert_input!) {
        insert_product_one(object: $object) {
    id
            brand
            category_display_name
            description
            price
            name
        }
    }
    `)}},
    "variables": {
        "object": {{
          JSON.stringify({
    id: getID.text,
            brand: getBrand.text,
            category_display_name: getCategory.text,
            description: getDescription.text,
            price: getPrice.text,
            name: getName.text,
        })}}
    }
}


Here, we have an object consisting of a query key that holds the GraphQL query and a variables key with all the variables that need to be posted to the database.

In the query, we have a mutation that lets us modify the server-side data. We'll send the object that references the data querying inside the mutation. The insert_product_one allows us to post one object to the database. Inside this query, we can add the attributes we need to post. Next, we've associated the variables to the object from the created UI input widgets. The .text on the input widget name helps us get the text written inside the input.

That's all, and our query is now ready! We can test this out by opening the form and creating a new product on our e-commerce store.

Add Stats on Dashboard

In this section, we will be showing some statistics on our dashboard; for this, let's drag and drop three stat box widgets onto the canvas. Following is a screenshot of how it looks like:

CleanShot 2022-01-17 at 10.28.11@2x.png

As we can see, these stat box widgets compute the total products, total categories, and unique brands. The data here is computed directly from the Hasura instance, using JavaScript. Following is how it works:

On the first stat box widget, select the text-widget and paste the following in the Text property:

{{getproducts.data.data.product.length}}

This small JS code will return the array's length from the getproducts query, displaying the total products.

Similarly, update the other two stat box widgets with the following JS code:

To compute Total Categories, we use an IIFE function and filter the getproducts query using its category_display_name attribute :

{{
function(){
    const filterProducts = getproducts.data.data.product.map(item => item.category_display_name)
  .filter((value, index, self) => self.indexOf(value) === index)
    return filterProducts.length
}()
}}


To compute Unique Brands, we use an IIFE function and filter the getproducts query using its brand attribute :


{{
function(){
    const filterProducts = getproducts.data.data.product.map(item => item.brand)
  .filter((value, index, self) => self.indexOf(value) === index)
    return filterProducts.length
}()
}}


There we go; we now have our dashboard up and running! Not just that, Appsmith allows us to create charts on top of Hasura data. Let's learn more about it in the next section.

Charting on Appsmith on Hasura Data

To get started, let's rename the page as Recent Orders; the idea is to create a chart that shows daily sales. Drag and drop a new chart widget onto the page from the widgets section.

This will show you a column chart with some pre-defined data; let's update this by creating our new query that fetches all the sales data:

  • Click on the + icon next to datasources and choose Create a new API.
  • Set the query type to POST, and update the URL to [https://subtle-platypus-36.hasura.app/v1/graphql](https://subtle-platypus-36.hasura.app/v1/graphql)
  • Under the headers pane, add the following key-values:
content-type: application/json
x-hasura-admin-secret: YOUR_SECRET_KEY


  • Lastly, navigate to the Body property under the API pane, set the body type to JSON, and paste the following:


This query will return a bit complex JSON; we will see something like:

{ "data": { "order": [ { "order_products": [ { "product": { "order_products": [ { "quantity": 2 } ] }, "created_at": "2021-02-22T18:16:17.776779+00:00" } ] }, … }

Here, order_products are nested in an array; hence, to process this and put it on a chart widget, we create a new JS object, allowing us to write full code on Appsmith and utilize its widgets. Confused? Follow the below steps:

  • Click on the + icon next to JS Objects, or use the JSObject1
  • Update myFunc1 to the following:

myFun1: () => {

  const data = _.compact(salesGraph.data.data.order.map((row) => 
  {
        const quantity = _.get(row, 'order_products[0].product.order_products[0].quantity');
        const created_at = moment(_.get(row, 'order_products[0].created_at')).format("LL");

        // if any of those in undefined
        if (!quantity || !created_at) return undefined;

        return {
      x: created_at,
             y: quantity,
    }
  }))
    return data.slice(1, 20)
    },

Here, we do a simple ordering using the _.compact method from lodash to aggregate the total number of sales done on a particular date. We return these in a special {x: value, y: value} format, which is accepted by the chart widget.

Now, let's head back to the chart widget and use this JS Object:

Update the series data property with the following:

{{JSObject1.myFun1()}}

Boom! There you go, we have all our sales aggregated based on the date on a beautiful chart widget. Following is how it looks like:

CleanShot 2022-01-17 at 11.17.25@2x.png

We also extended this app to show all the sales and orders on stat boxes and list widgets. Here's the link to the complete application!

If you liked this tutorial, and are planning to build this, let me know. I’d love to help you make it as complex as you’d like.

Write to me at vihar@appsmith.com.


October Roundup: Widget Improvements, New Appsmith functions, and ARM Architecture Support
2
November
2021
Monthly Round-up

October Roundup: Widget Improvements, New Appsmith functions, and ARM Architecture Support

October Roundup: Widget Improvements, New Appsmith functions, and ARM Architecture Support
Vihar Kurama
0
 minutes ↗
#
announcement
#
applications
#
app-development
#
community
#
crud
Monthly Round-up

We’re back again this month with updates from the last 30 days. We like to work hard! We’ve shipped many features, fixed bugs, and launched Hacktoberfest with a series of fun events. You can check them out here.

Widget, UI, and UX Improvements

#1 Menu Buttons on Table Widget 

Tables on Appsmith are one of the most loved widgets, and yes, we’ve upgraded them again! We can use menu buttons inside the table widget on any particular column to create menus and customize them. Open the column settings from the table’s property pane and set the column type to the menu button to see them in action! And just like that, we should be able to see a menu button on our table. Additionally, you can add more items to this by configuring the Menu Items property. That’s not all, and you can further customize the items to have icons, border radius, box shadows, and more!

#2 A New Sparkling White UI

Notice anything new? Yes, we have improved our whole design system to help developers focus more on their application editing on Appsmith. Right from searching through apps on the dashboard to building them using queries and widgets, everything is white! 

#3 Option to Hide/Unhide Properties from Property Pane

At Appsmith, we consistently focus on adding new properties and features to widgets, and sometimes it can get a bit overwhelming to see all of these at the same time! To make it less cumbersome, we’ve added an option to hide and unhide a few properties. Developers can concentrate on what’s important. To use this feature, toggle the dropdown arrow inside the property pane. You will see an option to collapse the various options within the pane. For example, in the picture below, only the header option has been made visible.

New Appsmith Functions!

You can bid goodbye to refresh buttons! Developers had to use refresh buttons on Appsmith Appsmith to be able tore-run the queries. We recognized this pain point. Now there’s a cool new feature to periodically run APIs and DB queries. You can configure these by using the  setInterval and clearInterval functions!

The setInterval function executes a trigger callback at a given interval. Here’s how you can use it while dynamically binding queries onto widgets:

setInterval(callbackFunction: Function, interval: number, id?: string)
// setInterval(() => { Query1.run() }, 10000, "myTimer");

The clearInterval function stops executing the trigger callback started with the setInterval method.

clearInterval(id: string)// clearInterval("myTimer");

Appsmith Deployments

#1 Helm Chart Support

Helm charts are now added for Appsmith deployments on Kubernetes deployments. These include application deployments with basic default support. Additionally, developers can add custom configuration for persistent volume data, custom ingress controller and secure with TLS certificate

#2 Support for Deploying Appsmith on ARM Architecture 

Previously, many developers had reported issues regarding docker-based installation of Appsmith on ARM architectures. Now, we had rectified them and had added extensive support for M1 MacBook users.  Following are the changes that we made to the scripts for docker installation:

  • We heavily refactored Dockerfile to build the image that is able to support both AMD64 and ARM64 architecture
  • We have updated docker.env.sh with additional environment variables and renamed the existing MongoDB credential variables
  • We added a document to build an image for multiple architectures using Docker buildx

Quit Buggin! Cheers to our Updated Debugging Experience

We have improved the debugging experience by adding hint and errors messages for different cases when working on queries and binding them onto widgets. To make these messages more efficient, we added a new attribute named readableError to the ActionExecutionResult object, returned to the client post after actions are executed. With this, we should be able to understand and solve complex errors quickly. Not just that, we have seen many APIs failing because of using duplicate headers or query parameters, so we have added a few hint messages to help you debug faster.


We’ve got a host of other bug fixes and updates too, be sure to check out our release notes here

See you next month with more updates! Do follow us on Twitter, Youtube, and Linkedin to stay up to date.  

Building an Admin Panel with Appsmith
29
April
2021
Tutorial

Building an Admin Panel with Appsmith

Building an Admin Panel with Appsmith
Confidence Okoghenun
0
 minutes ↗
#
admin
#
dashboard
#
developer-tools
#
tools
Tutorial


Admin panels are an important part of every organization. They are necessary to serve customers better and run business processes smoothly. They help reduce management and people overhead significantly. But on the other hand, they take a lot of time to build and are troublesome and expensive to maintain. As a result, it is not the choice of project for most developers.

Thankfully, there are a lot of options available to developers today to build complex admin panels and dashboards fairly easily while making maintenance easier. An example of such a framework that we have explored, React-admin. We’ve written an article on how to use it. It’s better than building an admin panel from scratch, but it is still cumbersome to move from a simple admin panel to an admin panel that behaves like an internal app.

And that’s one of the reasons why we built Appsmith. Building Admin panels and internal apps should be easy and, more importantly, fun. Appsmith offers a drag and drop interface for creating UI elements and provides the option to write code wherever you may need to. You can build dashboards a hundred times faster on Appsmith, and that’s not an exaggeration.

For this article, I’d like you to imagine it's 2005. Netflix doesn’t stream video yet. You run a local DVD store, and you need software to manage your rentals. You’re the only developer in the organization. How do you go about building one that is fast, scalable and easily maintainable? In this article, I’m going to show you how to build an admin panel using Appsmith to manage DVD rentals for your store.

The app would have two pages. The first page would have a table listing all registered members of the store. The second page will have a table that holds all rental records. From here, new rental entries can be created, and existing rentals can be updated i.e from borrowed to returned. We would also be able to click on a customer from the first page and then taken them to the rentals page to see his rental history.

Before we begin, I’d like to give you a quick overview of the dataset we’ll be making use of. We’ll be using a modified version of the Sakila dataset. The database of choice is MongoDB on MongoDB Atlas and here’s the schema for each collection

// Customer collection
{
  "store_id": String,
  "first_name": String,
  "last_name": String,
  "email": String,
  "address_id": String,
  "activebool": Boolean,
  "create_date": Date,
  "last_update": Date,
  "active": Number
}
// Film collection
{
  "title": String,
  "description": String,
  "release_year": Number,
  "language_id": String,
  "rental_duration": Number,
  "rental_rate": Number,
  "length": Number,
  "replacement_cost": Number,
  "rating": String,
  "last_update": Date,
  "special_features": String,
  "fulltext": String
}
// Rental collection
{
  "status": String,
  "rental_date": Date,
  "film_title": String,
  "customer_email": String,
  "return_date": Date,
  "staff_id": String,
  "last_update": Date
}

That’s the overview of everything. Now let us get started!

Oh, snap! I almost forgot. Here are some of the core Appsmith concepts we’re going to cover:

  • How to connect Appsmith directly to your database (eliminates the need for an API server)
  • How to create data-driven widgets
  • How to perform CURD operations
  • How to securely share your application (no auth required)
  • How to deploy your application

We can get started now!

Connecting to your data source

It’s quite important that our application is linked to a persisted data source because admin panels are almost always data-driven applications. This data can come from an API, a database, or a Google sheets table as we have the freedom to use any of these on Appsmith. We’ll be with the database route.

Create an Appsmith account if you do not have one yet and let’s begin to smith our application 😁

As highlighted earlier, our application would be based on a MongoDB database. Don’t despair if you would like to follow along and do not have a ready-to-go database. Here’s a database connection you can make use of. Mind you, it’s read-only (don’t forget to say thank you)

Username: article_reader

Password: 0HkfXpxVpvvSvUOx

Connection url: cloud.r4vra.mongodb.net

Database name: movie_store

Alright, we’ve removed all hurdles from the track, now let’s start racing!

Go ahead to create a new application from your Appsmith dashboard and give it a fancy name. Next, let’s connect to the mongo database. Click on the DB Queries button on the left panel on the page and select MongoDB from the list of supported databases. Now go in and supply the database credentials to the from, also give this data source a descriptive name i.e. movie_store or movie_store_db. I think I’ll go with movie_store. And lastly, hit the big green save button.

1-connecting to mongodb.png

Awesome! We’ve connected the application to the database. We can now do some querying and build data-driven widgets. Let’s move on to the next section.

Creating data-driven widgets

We now have a database connected to the application. The next thing we need to do is to create a widget that can be used to create, update and display data from the database. To achieve this, we need a way to fetch data from the database. This can be done on Appsmith by writing database queries.

Rolle up your sleeves because we’re going to be writing our first DB query! Click on the DB Queries section again, and you’ll see a button to create a new query on the MongoDB movie_store data source. Give the query a name i.e. get_customers, and select a read template from the list because we’re going to be reading documents from the Customer collection.

The get_customer query should find all customers in the Customer collection, sort them by email and return a fixed limit of customers. Your query should look like this.

// Customer collection
{
  "find": "Customer",
  "sort": {
    "email": 1
  },
  "limit": 10
}

Configure your query and hit the run button, and you’ll get a list of 10 customers. Sweet!

It would be much readable to display this data in a table. So let’s do exactly that. Click on the Add widget button just below the query editor, and you’ll get a new table widget on the canvas that has been automatically linked to the get_customers query. An alternative way would be to click on the Widgets section and drag a table widget to the canvas. Then, data from the query can be bound to the widget via the Table Data property on the widget’s configuration menu using moustache syntax.

// Customer collection
{{get_customers.data}}
It’s important you give the table a descriptive name. Consider changing the name from Table1 to customers_table
2-writing binding for customer table.png

Go ahead to customize the table by re-ordering the columns and hiding columns you don’t like. We’ll also need to paginate the table, so on the table’s config menu, turn on Server Side Pagination and configure the onPageChange action (in the Actions subsection of the menu) to execute a DB query and then select the get_customers query.

We’ll need to update the query and add a skip property that calculates a skip based on the current table page number to simulate pagination. The moustache syntax would be very handy in this case to perform quick evaluations, so let’s make use of it. Your updated get_customer query should look like mine.

{
  "find": "Customer",
  "sort": {
    "email": 1
  },
  "skip": {{(customers_table.pageNo - 1) * 10}},
  "limit": 10
}

As you may have noticed, we are accessing the table’s page number from within the {{}} through the object bearing the widget’s name (customers_table in this case). You can learn more about writing Javascript in Appsmith here.

Click on the page number on the table widget now fetches new records. We’ve been able to query the database, bind data to a widget and perform customization on the widget. Good job!

Now, we’re going to create a new page to manage rentals. Click on the plus button on the Pages section of the left-hand panel and create a new page. Call this the Rentals page and update the name of the home page to Customers. On this new page, you’re going to be building a table to display rentals like we just did for the Customers page. You’ll need a query (should be named get_rentals) and a table widget (should be named rentals_table) for this. Your query to get rentals should look like this.

{
  "find": "Rental",
  "sort": {
    "_id": 1
  },
  "skip": {{(rentals_table.pageNo - 1)*10}},
  "limit": 10
}

Where rentals_table is the name of your table widget on the Rentals page.

Good luck!

Creating new rentals

After completing the table on the Rentals page, the next feature we need to build in is the ability to create new rental records.

Here’s the game plan: We’re going to build a form that takes as input the status, rental data, film title, customer email, and return date. This form would be housed within a modal widget that would be triggered by clicking on a ‘Create new rental’ button. Now, you have a good overview, let’s get started!

On the Rentals page, head to the widget’s section and drag in a modal widget. In the modal’s config menu, update the name to create_rental_modal and set the Modal type to Form Modal. Now you see we have more space to work with.

With create_rental_modal open, drag in three dropdown widgets and two date picker widgets. The name of the first dropdown widget should be updated to customer_dropdown. Following this convention, go ahead and rename the other two dropdowns to film_dropdown and status_dropdown. For the two date pickers, their names should similarly be updated to rental_datepicker and return_datepicker. You should drag in a few text widgets to label these inputs.

4-create rental modal.png

We need a button on the UI to trigger the opening up of the modal. Let’s drag a button from the widgets section to the canvas. Give this button a new label i.e Create New Rental, and set the onClick action to Open Modal, then select create_rental_modal. Clicking on the button now opens up the modal.

Nice! We’ve completed the UI for the crate form. Now let’s wire it up with some queries.

The first query we’ll be writing for the create form would get all registered customers from the DB. We would use the returned data to build the options for the customer_dropdown. This query would be similar to the get_customers query from the Customers page.

Go ahead and create a new query named all_customers. It should be configured as shown below

{
  "find": "Customer",
  "sort": {
    "email": 1
  }
}

Now, we can use the data returned from this query to build the options of the customer_dropdown. Open up the create_new_rental modal and head to the config menu of the customer_dropdown. Now replace the content of the Options section with the snippet shown below.

{{all_customers.data.map(c => ({label: c.email, value: c.email}))}}

This returns an array of objects whose label and value are the email addresses of the customers from the all_customers query. You can play around with the dropdown and see that the options generated from the query. Sweet 🤩

Now you’re going to do the same thing for the film_dropdown. Create an all_films query and use the title field of each document to build the options for the dropdown. Your query should look like this.

{
  "find": "Film",
  "sort": {
    "title": 1
  }
}

Cool! For the status_dropdown, we can simply hard code the Options with this simple JSON array.

[
  { "label": "borrowed", "value": "borrowed" },
  { "label": "delayed", "value": "delayed" },
  { "label": "lost", "value": "lost" },
  { "label": "returned", "value": "returned" }
]
Don’t forget to set a default option for each dropdown widget The rental_datepicker and return_datepicker widgets do not require further configuration, and they are good to go. The last thing we need to do is to write a query that would create a new document on the ‘Rental’ collection using the data from the input widgets. Alright, go ahead and create a new query called create_rental and configure it this way.
{
  "insert": "Rental",
  "documents": [
    {
      "staff_id": "{{appsmith.user.email}}",
      "status": "{{status_dropdown.selectedOptionValue}}",
      "customer_email": "{{ customer_dropdown.selectedOptionValue }}",
      "film_title": "{{ film_dropdown.selectedOptionValue }}",
      "rental_date": "{{ rental_datepicker.selectedDate }}",
      "return_date": "{{ return_datepicker.selectedDate }}",
      "last_update": "{{moment().format()}}"
    }
  ]
}

Now we can go back to configure the big green Confirm button on the modal to run this query when it is clicked. We also want to close the modal and refresh the rental table when the button is clicked. Because what we want to do is a complex chain of actions, we can write some JavaScript to achieve this. Click on the JS button just beside the onClick button of the Confirm button and supply the bellow code snippet.

{
{create_rental.run(
  ()=> {
      closeModal("create_rental_modal");
    get_rentals.run();
  }
)}
}

Great Job! Go ahead, give it a spin and create a few new rentals.

Updating a rental

The flow for updating a rental is quite similar to that of creating a rental. We’ll need a modal that would be opened by clicking on a button. The modal would only contain form elements for updating the status and return date of the rental.

The only difference here is that we want the rental in question to be the one selected from the table. To do this, we need to head back to the config menu for the rentals_table and create a new column by clicking on the Add a new column button. Click on the gear icon of the newly created column and set the column name to Update. Also, set the Column type to button and set its Lebel property to Update. For its onClick action, it should be configured to open up the update_rental_modal which you’re going to build on your own.

And that all you need. Oh, you’ll also need to write a update_rental query too. It should look somewhat like this.

{
  "update": "Rental",
  "updates": [
    {
      "q": {
        "_id": "{{rentals_table.selectedRow._id}}"
      },
      "u": { 
        "$set": {
      "status": "{{ update_status_dropdown.selectedOptionValue }}", 
          "return_date": "{{update_return_date_datepicker.selectedDate}}",
          "last_update": "{{moment().format()}}"
     } 
      }
    }
  ]
}

Now you have everything you need to know. Go ahead and build the update flow.

Putting it all together

You’ve done a good job making it this far. I’m so proud of you that I’m going to leave the gif below. 🤗

We’ve been able to accomplish most of what we set out to do. We have a table on the Customers page to view all customers. On the Rentals page, we can view all rentals, create a new rental or update existing rentals. It was no small feat we accomplished.

I’ll like us to add one more feature. Let’s make it such that clicking on a customer on the customers_table takes us to the Rentals page, and then we can view all rentals made only by that customer.

We’ll need column buttons for each row like we did for the update flow. In this case, the onClick action of the custom column buttons would perform a navigation to the Rentals page and pass the selected customers’ email from the table as query params. Use the below snippet in the Query Params configuration for the navigation.

{{{customer_email: customers_table.selectedRow.email}}}

And lastly, we need to update the get_rentals query in the Rentals page to filter by customer_email coming in as a query param. We also add a fallback just in case no email is passed.

{
  "find": "Rental",
  "sort": {
    "customer_email": 1
  },
    "filter": {
    "customer_email": {
      "$regex": "{{appsmith.URL.queryParams.customer_email || ""}}"
      }
    },
 "skip": {{(rentals_table.pageNo - 1) * 10}},
  "limit": 10
}

And that’s it! You’ve completed the app. 🥳️🎉🎉

Sharing and deploying the app

It’s quite easy to hand off your application to the team that would make use of it i.e customer support. You don’t have to worry about an authentication/authorization flow; Appsmith does all the work for you.

There’s a SHARE button on the top right side of the page. You can easily use it to invite users to the application and set roles i.e app viewer or developer. No hassle is required!

Clicking on the ‘DEPLOY’ button to the right of the share button will publish all changes made in the editor to the hosted version of the application. Isn’t that cool?

Wrapping up

We set out to build an admin panel, and we’ve seen how we can do it very easily using Appsmith. Going this route will drastically reduce the development time and resources put into maintaining the app.

If you found this tutorial helpful, please consider giving us a star on Github.

Cover Photo Credits: Photo by Serpstat from Pexels

Build Tools for Your Fitness Start-up
27
August
2021
Tutorial

Build Tools for Your Fitness Start-up

Build Tools for Your Fitness Start-up
Vishnupriya Bhandaram
0
 minutes ↗
#
open-source
#
developer
#
development
#
developer-tools
Tutorial

This week, we’re back to feature apps made by Appsmith’s newest team members! Each new team member has to make an app on Appsmith as part of the hazing welcoming ritual! 😬 We’re a fully remote distributed organization with colleagues in more than five countries, and this is a fun and educational way of onboarding new members onto the team. And of course, it makes sense for people working on making Appsmith better to use it, understand it, and know the framework’s shortcomings. These apps made during the onboarding process can range from functional to fun or straight-up silly!

This week, we’re featuring our colleague Ashit Rath’s app. Ashit is a Sr. Frontend Engineer from Bhubaneswar in India. He has experience in building scalable web applications, and he loves to travel. You can follow his work here.

Ashit decided to make a simple food nutrition app to list items, and it would show you the nutrition details. Ashit’s recipe analyzer is an excellent example of the range of applications you can make on Appsmith.

During the app-making process, Ashit found the following things great about Appsmith:

  • Composing UI widgets was very intuitive
  • Adding API data source was super easy
  • Good performance overall

In the next part of the blog, Ashit has listed the steps to build the recipe analyzer.

Getting Started

This short tutorial uses the cloud version of Appsmith. However, you can always export and import Appsmith apps to different environments (cloud, self-hosted, local). The recommended way to use Appsmith is via Docker; follow the documentation here for detailed instructions if you want to build locally.

  • Create a new account or sign in with an existing account, redirecting it to our dashboard.
  • Click on Create New under your organization, and this will create a new Appsmith application.
  • Rename the application to GitHub Organisation Dashboard (or any name you’d like) by simply double-clicking on the existing one.
  • On the left, find the entity explorer; this is where you can manage all the widgets and data sources of the entire application.

There are three parts to building this Recipe Analyzer app:

  1. API for nutritional data
  2. Connecting the form to get the data from API
  3. Crunching numbers to show the nutrition

API for nutritional data

‍ The API that we have used here comes from Edamam. They have a robust API for any kind of food/recipe/ingredient level search.

Sign up for their Nutrition Analysis API as a Developer account to try out without a subscription. The Developer account might give out less information than it should, but it should be fine for our use case.

Once signed up, we need to generate the API key from here.

  1. Click the "Create New Application",
  2. Select "Nutrition Analysis API"
  3. Fill out the form and hit "Create Application"
  4. Once the application has been created; you would be greeted with the application API details page. Keep "Application Keys" and "Application ID" in place. We would need it in the next step.

Connecting the form to get the data from API

‍ We have the API key from the previous step, so now we will use that to make API calls to Edamam for our searches.

Now head over to Appsmith to create a data source.

  1. Create a new Datasource by clicking the + button on the sidebar.
  2. Click "Create new" for a new data source
  3. Click "Create new API"
  4. Change the API Name to nutrition_api, it would be "Api1" by default.
  5. Click on the "GET", a dropdown should open up and select "POST".
  6. Add the following to the URL bar; replace with the "Application ID" and with the "Application Keys" that we got from the previous step

https://api.edamam.com/api/nutrition-details?app_id=<application id>&app_key=<application key>

This should create our data source for fetching the nutrition data.

Let's create a new input and connect it to the data source to fetch.

  1. Add a new text widget and name it as FoodInput
  2. Resize the text widget according to need and add the following to the Placeholder property
1 cup rice

1/2 cup dal

100gm chicken
  1. Now add a new button widget; on clicking this, we need to trigger an API request (to the API we added in the previous section).
  2. Open the button widget properties and scroll down to Actions section; there would be an onClick property. Click the JS and a blank text box should open up
  3. Add the following lines to the text box opened in the previous step
{{

(function () {

        if (FoodInput.text.trim()) {

            const foodInputArray = FoodInput.text.split("\\n")

            storeValue('foodInputArray', foodInputArray)

            const onSuccess = () => {}

            const onFailure = (response) => {

                showAlert('Invalid quantity or name.', 'warning')

            }

            nutrition_api.run(onSuccess, onFailure)

        } else {

            showAlert('Please enter something to analyze', 'warning')

        }

})()

}}

This code basically takes the FoodInput text, modifies into proper API request format (array of string), stores the value in global storage using (setValue) and triggers the nutrition_api (nutrition_api.run)

That's it; we have connected our API and our form to send requests and get our awesome nutrition data!.

Crunching numbers to show nutrition values

Now we create the part where we display the data from Edamam and show it in a neat format.

All of the data points are calculated in a similar fashion, so we will demonstrate the only one just to get the idea behind it.

Let's consider Total Fat, the value for it can be derived by having the following code in the text property.

{{(function() {

    if (!nutrition_api.data.totalNutrients?.FAT?.quantity) return "-";



    return parseFloat(nutrition_api.data.totalNutrients.FAT.quantity).toFixed(2) + nutrition_api.data.totalNutrients.FAT.unit

})()}}

This first checks if totalNutrients.FAT.quantity exists or not; if not, then we display "-.” If it exists, then parse the value and append the unit to it

So "10.12520" becomes 10.12 gm (gm comes from nutrition_api.data.totalNutrients.FAT.unit)

Similarly, the Total Fat Daily Percentage can be displayed using the same logic.

{{(function() {

    if (!Api1.data?.totalDaily?.FAT?.quantity) return "-";



    return parseInt(Api1.data.totalDaily.FAT.quantity) + "%"

})()}}

We build the whole UI by adding similar code but changing the key from FAT to whatever macro/micronutrient is required to be shown.

Wasn’t that simple?

This recipe analyzer can be used as part of the many tools a fitness company/studio can give its members. We took the recipe analyzer a few steps further and envisioned the various other things to help a fledgling fitness studio tech up.

See the screenshots below to get a better idea:

Screenshot 2021-08-25 at 1.37.50 PM.png
You can make a fully automated system to keep track of progress for clients, with our modal widget, you can automate payment collections etc. Just connect your data source to get started!
Screenshot 2021-08-25 at 1.38.52 PM.png
Connect your database from Airtable or Google Sheets and start building!

For a detailed tutorial on how to build dashboards and admin panels, follow this link.


Have you made something using Appsmith? Write to me (vishnupriya@appsmith.com), and I would love to feature you on our blog! If you’re interested in building an app on Appsmith, sign up today . We have docs, tutorials, and live help on our vibrant Discord community to help you along the way. So go ahead, put your ideas out there!