🗄️ Using the CRM Template

806

Getting Started

Hey 👋

Welcome on our Weweb CRM template documentation.

The idea behind this template was to create a rather simple, yet customizable CRM using Weweb (as the frontend) and Xano (as the backend).

Here’s a quick summary video on how this app works 👇

Please know that all the data used in the CRM is fake, except company names that are copyrighted. The person names, emails, and company data are all invented and doesn’t exist.

Also, when you sign up, some data is generated for you so that you can “play” with the template.

⚠️ This data is deleted every Sunday at 01:01:01 PM GMT+2.

Data Structure

The CRM data structure revolves around 5 models:

  • user
  • company
  • contact
  • deal
  • note

Each of them having their own table and API endpoints.

Here’s a quick video showcasing the data structure and the Xano backend:

ℹ️ We used the REST API in Weweb instead of the Xano plugin most of the time to make the template more pedagogical. Of course, you could use it in your app to go even faster.

To get up to speed quickly, here's a Xano snippet to copy the CRM's backend.

User

The user table is responsible for storing the end users of the app, that means you and me.

It’s composed of these fields:

id: integer the primary key

created_at: timestamp storing the record’s creation date and time

name: text the name of the user

email: text the email of the user

password: password the password hash of the user’s password

picture: image the user’s profile picture

role: text the user’s role that grants him/her rights

Here’s what it looks like in Xano 👇

Weweb CRM template

Every time a user signs up to the CRM app, his/her data is stored inside this table. And when he/she wants to log in, the app validates the user’s existence and password validity against this table.

Company

The company table stores… companies 😆 (like Airbnb, Google or Weweb 😉)

Every CRM revolves around deals that are tied to a contact and a company. That’s why we have to store companies in a separate table, as some deals can be linked to the same company.

Here are the table fields:

id: integer the primary key

created_at: timestamp storing the record’s creation date and time

name: text the name of the company

domain: text the web domain of the company’s website

logo: text the URL of the company’s logo

location: text the location of the company’s headquarters

industry: text the company’s industry type

number_of_employees: text the company’s headcount range

user_id: integer the foreign-key linking the company to the user’s table

Here’s what it looks like in Xano 👇

Weweb CRM template

As you can see, this table is linked to the user one through a foreign-key so that we’re able to restrict the display of companies (both in Weweb and Xano) to the current user (meaning a user can only see and edit the companies he’s attached to).

Contact

A contact is the person attached to a deal, that’s also part of a company. In the case of a CRM, that’s the person you’re “trying to close” on a deal.

It’s composed of those fields:

id: integer the primary key

created_at: timestamp storing the record’s creation date and time

name: text the name of the contact

picture: image the profile picture of the contact

email: text the contact’s email address

job_title: text the contact’s job title in his/her company

company_id: integer the foreign key linking the contact to his/her company

user_id: integer the foreign key linking the contact to the user’s table

Here’s what it looks like in Xano 👇

Weweb CRM template

You can see that the contacts are linked to companies, by storing the API key here, as a contact only have one company, but a company can be linked to multiple contacts.

Deal

Maybe the most important table in the CRM, the deals are all the commercial opportunities that a CRM stores. They’re linked to contacts and companies.

A deal is composed of those fields:

id: integer the primary key

created_at: timestamp storing the record’s creation date and time

name: text the name of the deal

contact_id: integer the foreign key linking the deal to his/her contact

company_id: integer the foreign key linking the deal to his/her company

status: text the current status of the deal that we’ll use to filter deals in the right column in the Weweb kanban (eg: qualified, closing, lost, etc)

description: text the deal description

order: integer the order deals are displayed in their column in the Weweb kanban

user_id: integer the foreign key linking the deal to the user’s table

Here’s what it looks like in Xano 👇

Weweb CRM template

As you can see, a deal is linking both to a contact (and can theoretically have multiple contacts, even if it’s not the case in our data) and a company. That’s why it has 2 foreign keys linking to these tables.

Screens

Signup, Login, Reset and Forgot Password

Signup, login and reset password pages are basically pages containing one form, which on submit sends back the data to Xano to either signup, login or reset the user password:

Weweb CRM template
⚠️ Make sure to send a profile picture. Otherwise, the signup won’t work.

A note on Reset and Forgot Password flow

When a user forgot his/her password, he’ll basically land on the Forgot Password page, where he’ll type his email.

When doing so, it’ll trigger an API call to Xano which will send an email (in this example, through customer.io) to the user which a URL.

When clicking on the email’s URL, the user will land on the Reset Password page concatenated with a querystring variable magic_link, which will be used inside the Reset Password workflow to sign-in the user without his password (both in Weweb and Xano), then reset his email on Xano-side.

Deals

Here’s a summary of the main elements on this screen 👇

Weweb CRM template

Let’s begin with the first element, which is common to all screens (reusable section), the Sidebar.

It’s a simple vertical flexbox made of links to other pages and a div which contains the logged-in user’s details:

Weweb CRM template

Kanban

Then, the most important element is the Kanban. This element is bound the the Deal collection but also using data from the Contacts and Companies collections, as shown here:

Weweb CRM template

The Kanban is made of Stacks that are determined by the status column inside each Deal.

When moving an item, the Kanban will trigger a workflow which will:

  • Update the moved deal status and order by using the Event to and newIndex parameters
  • Updating each other deal’s order in the current stack by sending the updated list to Xano

Then are dropdowns and search bar that are used to filter and search the Deal collection:

Weweb CRM template

Finally, there is the Add new deal button which, on click, triggers a workflow that opens a modal (by settings its display variable to true), enabling you to create a deal:

Weweb CRM template

When submitting the form, it’ll POST a new deal to Xano and close the modal by setting the modal’s display variable to false.

Contacts and Companies screens

Datagrid

The only difference with the deals screen is that we replaced the Kanban with a Datagrid element:

Weweb CRM template

Also, this element and the dropdown/search are now bound to the Contacts collection.

When updating or deleting a contact inside the datagrid, it’ll POST or DELETE the contact in Xano and refetch the contacts collection.

For companies, it’s the same, but everything is bound to the Company collection:

Weweb CRM template

User Management

Workflows

API

💡 It’s actually considered a best practice inside Weweb to store all your API requests inside global workflows that you call from your app’s elements. So that you only have to maintain/edit them once.

First is a folder called API, which is this app API management center:

Weweb CRM template

It references all the Xano’s API endpoints that you can also find here: https://xc0b-vcze-d4we.n7.xano.io/admin/

Every time we’ll need to update or delete a contact, company, deal, etc from the Weweb app, the element triggering the workflow will actually call these global workflows.

Components

Next is a folder called Components that contains all the workflows to trigger the display of elements such as the sidebar or the alerts:

Weweb CRM template

Variables

Deals, Contacts and Companies

In these folders, you’ll find the variables that are used to display specific data from deals, contacts or companies when the UI needs it.

As an example, the selectedDeal variable is used to store the currently clicked on deal that should appear in the modal:

Weweb CRM template

API

API contains the API’s base URL, which is used to construct collections or global workflows URLs without having to always retype the URL in full.

Weweb CRM template

Here’s an example on how it’s used in a collection:

Weweb CRM template

Components

Components variables are used to store the component current state, that you shouldn’t modify directly but use their attached workflows:

Weweb CRM template

Querystring

Querystring variables are used to pass data after the ? sign in a URL. There’s only one in this project, magic_link, which is used for the reset password:

Weweb CRM template