This article will walk you through the process of creating a Trello clone using react and Strapi. We'll go over how to create a new Strapi project, how to construct Strapi collections, and how to expose and connect your Strapi API to the front-end.
NB: Strapi recommends 14.x version node js
We'll be creating a Trello clone, which is a project management tool that organizes your work into boards. Trello shows what is being worked on, who is working on it, and where the task is in the process all at the same time. Below is a screenshot of what our final project will look like:
These are the software you need to have installed.
Before starting with creating our application front-end with React.js, let's get a basic understanding of what react is:
What is React.js:
React is a JavaScript library designed for creating quick and interactive user interfaces for web and mobile apps. It is an open-source, component-based front-end library that is exclusively responsible for the application's view layer. The view layer here refers to how the program looks and feels in Model View Controller (MVC) architecture. You can visit https://reactjs.org/ for more information.
Now that we understand what React is, and how it works, follow the instructions below to set up the React front-end for our application:
First, create a new directory for our project, we’ll name this directory trello-clone
:
1 mkdir trello-clone && cd trello-clone
Next, run the command below to create the react app:
1 npx create-react-app front-end
Running this command will initially ask for permission to install create-react-app and its associated packages on a temporary basis. Once finished, you can start the app by running:
1 cd front-end
2 npm start
This should open up a URL (http://localhost:3000), with the following output:
Next, for the drag and drop feature, we will be using a react package - react-sortable.js, which was created specifically for this purpose.
react-sortable
is a react binding for Sortable, Sortable is a JavaScript library for creating reorderable drag-and-drop lists. It has all of the standard sortings, delaying, swapping, inverting, and other features. All touch current browsers and touch devices are supported.
To install react-sortable
, run the command:
1 npm install --save react-sortablejs sortablejs
If you follow this process react-sortable
should install just fine. And finally, for sending requests to our Strapi API, axios
should work just fine for that.
Let's get a quick overview of what Axios is and what it does before installation. Axios is a promise-based HTTP client for the browser and Node.js. Axios makes it simple to send asynchronous HTTP requests to REST endpoints and perform CRUD operations. It can be used in plain JavaScript or with a library such as Vue or React.
To install Axios
, run the command below:
1 npm install axios
Strapi is an open-source content management system (CMS) that allows you to create customizable APIs for any front-end application. Strapi is really simple to use since it allows you to create versatile APIs with unique features that you'll enjoy. To keep things structured, you can build custom content kinds and relationships between the content types. It also features a media library where you can save your image and music files. Strapi provides a great deal of flexibility. Whether you want to see the finished outcome quickly or learn more about the product.
To setup Strapi for our project, first, change your directory from front-end to the root directory (/trello-clone
), and run the command below to create a new Strapi project:
1 npx create-strapi-app back-end
Running the command above will prompt you for your preferred installation method; select Quick Start to proceed. You will also be asked if you want to use a template, as seen in the screenshot; in this case, reply with no, and Strapi will complete the installation in no time.
After the whole installation process, the Strapi app should automatically launch in your browser displaying the following page.
OR
Copy http://localhost:1337
link from your command prompt cmd
and paste it into your browser.
click on open the administration
Fill in your preferred details on this page and click the ready to start button to proceed. We are now ready to begin.
In this phase, we will learn how to create a collection-type and its content, and as seen in the screenshot attached at the beginning of the article, our Trello clone will have the following rows:
To do this, click on Content-Type Builder (can be found on the dashboard sidebar), afterward click the Create new collection type link, as seen in the screenshot below:
You should see a modal box like the one below; fill in the display name as Tasks and then click the Continue button to complete the creation of our collection:
When you click the Continue button, you will be prompted to add a new field to the newly created collection; here, pick the field type as Idea, choose long text and click add another field. You will do the same for Todo, Progress, and Published. Then click finish.
The Tasks collection type should look like the image below.
Next, we head over to Settings, navigate to Roles and click on the Public. We then scroll down to Permissions, click on Task, and click on select all to allow all activities for the application.
Click on Save.
We've installed all of the packages required for our application's front-end, and all that remains is to begin adding functionality at this point. To restart the application, open the front-end folder in your favorite text editor and enter the following command on your command prompt cmd
:
1 npm start
Now, open up src/index.html
, and add a link to bootstrap cdn in the head section like below:
1 import './App.css';
2 import Board from "./components/Board";
3 function App() {
4 return (
5 <div className="App p-3" >
6 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
7 <Board />
8 </div>
9 );
10 }
11 export default App;
Next, in our front-end src
directory, create a new folder called components. Inside this folder, create a new file called Board.js
and paste the following code into it:
1 import { ReactSortable } from "react-sortablejs";
2 import { useState, useEffect } from "react";
3 import axios from "axios";
4
5 const Board = () => {
6 const [tasks, settasks] = useState([]);
7
8 const [ideas, setideas] = useState([]);
9 const [todo, settodo] = useState([]);
10 const [inprogress, setinprogress] = useState([]);
11 const [published, setpublished] = useState([]);
12
13 const [newTask, setnewTask] = useState("");
14
15 const addTask = async () => {
16
17 };
18
19 const getTasks = async () => {
20
21 };
22
23 useEffect(() => {
24 getTasks();
25 }, []);
26
27 return (
28 <>
29 <div className="container mt-5 mb-5">
30 <div
31 className="row"
32 style={{
33 height: "80vh",
34 }}
35 >
36 <div className="col mx-2 px-2 py-3 bg-light border rounded">
37 <h6>Idea</h6>
38 <div
39 style={{
40 minHeight: "500px",
41 }}
42 >
43
44 </div>
45 <div>
46 <textarea
47 rows={"1"}
48 cols={30}
49 style={{ float: "left", borderBlockColor: "#007bff" }}
50 value={newTask}
51 ></textarea>
52 <button
53 type="button"
54 style={{ float: "right", marginTop: "2px" }}
55 class="btn btn-primary btn-sm"
56 onClick={addTask}
57 >
58 Add Task
59 </button>
60 </div>
61 </div>
62 <div className="col mx-2 px-2 py-3 bg-light border rounded">
63 <h6>Todo</h6>
64
65 </div>
66 <div className="col mx-2 px-2 py-3 bg-light border rounded">
67 <h6>In Progress</h6>
68 </div>
69 <div className="col mx-2 px-2 py-3 bg-light border rounded">
70 <h6>Published</h6>
71 </div>
72 </div>
73 </div>
74 </>
75 );
76 };
77
78 export default Board;
In the above code, we created a simple 4 column grid system with bootstrap, and with the react useState()
hook, we created all of the data we will need in our application, and we also defined two methods addTask
and getTasks
, which do nothing for now; in the following section, we will add the necessary functionalities to make these functions work as expected.
Now, open up src/App.js
and import the just created board component so that the full code will look like below:
1 import Board from "./components/Board";
2
3 function App() {
4 return (
5 <div
6 className="App p-3"
7 style={{
8 background: "linear-gradient(to right, #0062cc, #007bff)",
9 }}
10 >
11 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/c ss/bootstrap.min.css" />
12 <Board />
13 </div>
14 );
15 }
16
17 export default App;
At this stage, you should see the following output displayed in your browser:
Connecting front-end to Strapi
To enable the drag and drop functionality, and fetch all of our tasks from strapi API, first import the following components in our components/Board.js
file:
1 import { ReactSortable } from "react-sortablejs";
2 import { useState, useEffect } from "react";
3 import axios from "axios";
In this same file, update the getTasks
function so that the full code is the same as the one below:
No let create a function that will fetch out the list of item in each category that we have in our database, to do this is pretty simple by using the following code:
1 const getTasks = async () => {
2 let Tasks = await axios.get("http://localhost:1337/api/tasks");
3 console.log(Tasks.data.data);
4 // return;
5 settasks(Tasks.data.data);
6 // For todos
7 let Todos = tasks.filter((res) => {
8 return res.category === "todo";
9 });
10 settodo(Todos);
11 // For ideas
12 let Ideas = tasks.filter((res) => {
13 return res.category === "idea";
14 });
15 setideas(Ideas);
16 //For in progress
17 let inprogress = tasks.filter((res) => {
18 return res.category === "In Progress";
19 });
20 setinprogress(inprogress);
21 //published
22 let published = tasks.filter((res) => {
23 return res.category === "published";
24 });
25 setpublished(published);
26 };
From the above code, we use the axios.get
function *to fetch tasks from the strapi database by passing in the API url to the strapi endpoint. we then use settasks(Tasks.data.data)
to hold the list of all the tasks ( all categories) that were fetched from strapi.
We then used `tasks.filter((res)*`) to return the list of tasks in each category.
Adding new tasks to Strapi
Now let's add a new task to the database, each new that we add will be on the idea category until it's dragged to the next category. The following code will add a new task to the database.
1const addTask = async () => {
2 let res = await axios
3 .post("http://localhost:1337/api/tasks", {
4 Category: "idea",
5 task: newTask,
6 })
7 .catch((err) => alert("Error occured"));
8 getTasks();
9 };
From the code above, axios.post()
is used to add tasks to the database,by passing in the strapi endpoint url along with the database fields value to be added. getTasks()
is then used to reload the list of tasks from the database which contained the new added tasks.
Finally, update the component markup section with the code below:
1 <div className="container mt-5 mb-5">
2 <div
3 className="row"
4 style={{
5 height: "80vh",
6 }}
7 >
8 <div className="col mx-2 px-2 py-3 bg-light border rounded">
9 <h6>Idea</h6>
10 <div
11 style={{
12 minHeight: "500px",
13 }}
14 >
15 <ReactSortable
16 list={tasks}
17 setList={setideas}
18 groupp={"group-1"}
19 group={{ name: "group-1", put: true }}
20 >
21 {tasks
22 .filter((task) => task.category == "idea")
23 .map((filteredTask) => (
24 <div
25 className="card p-3 border rounded mt-2"
26 key={filteredTask.id}
27 >
28 {filteredTask.task}
29 </div>
30 ))}
31 </ReactSortable>
32 </div>
33 <div>
34 <textarea
35 rows={"1"}
36 cols={30}
37 style={{ float: "left", borderBlockColor: "#007bff" }}
38 value={newTask}
39 onChange={(event) => setnewTask(event.target.value)}
40 ></textarea>
41 <button
42 type="button"
43 style={{ float: "right", marginTop: "2px" }}
44 class="btn btn-primary btn-sm"
45 onClick={addTask}
46 >
47 Add Task
48 </button>
49 </div>
50 </div>
51 <div className="col mx-2 px-2 py-3 bg-light border rounded">
52 <h6>Todo</h6>
53
54 <ReactSortable list={tasks} setList={settodo} groupp={"group-1"}>
55 {tasks
56 .filter((task) => task.category == "todo")
57 .map((filteredTask) => (
58 <div
59 className="card p-3 border rounded mt-2"
60 key={filteredTask.id}
61 >
62 {filteredTask.task}
63 </div>
64 ))}
65 </ReactSortable>
66 </div>
67 <div className="col mx-2 px-2 py-3 bg-light border rounded">
68 <h6>In Progress</h6>
69 <ReactSortable
70 list={tasks}
71 setList={setinprogress}
72 grouppp={"group-1"}
73 >
74 {tasks
75 .filter((task) => task.category == "In Progress")
76 .map((filteredTask) => (
77 <div
78 className="card p-3 border rounded mt-2"
79 key={filteredTask.id}
80 >
81 {filteredTask.task}
82 </div>
83 ))}
84 </ReactSortable>
85 </div>
86 <div className="col mx-2 px-2 py-3 bg-light border rounded">
87 <h6>Published</h6>
88 <ReactSortable
89 list={tasks}
90 setList={setpublished}
91 groupppp={"group-1"}
92 >
93 {tasks
94 .filter((task) => task.category == "Published")
95 .map((filteredTask) => (
96 <div
97 className="card p-3 border rounded mt-2"
98 key={filteredTask.id}
99 >
100 {filteredTask.task}
101 </div>
102 ))}
103 </ReactSortable>
104 </div>
105 </div>
106 </div>
From the above codes we use ReactSortable to drag a task from one category to other and it has three attributes: list={tasks}: contain the list of all the tasks that we fetch earlier from the database. setList={setpublished}: it contains the list of tasks for a specified category from the database. groupp={"group-1"} :All tasks are assigned to the same group..
Then to list each task from each category we use tasks.filter((task) to do that.
And at this point, we are done with creating our Trello app ….
Since our application data relies on Strapi, we’ll need to start our Strapi server as our application won’t start without it, open a new terminal window and change the directory to where our Strapi app is created, and start the app by running:
1 npm run develop
This is what you will get if you drag and drop an item from one category to another.
If you follow the process of this tutorial, your Trello clone app should be working just fine.
Wow, congratulations. We've completed this tutorial and have successfully created a Trello clone application using React.js and Strapi as our backend. We were able to retrieve and create tasks, as well as enable drag and drop functionality, by utilizing the sortable. After finishing this tutorial, you should be able to create a Trello app and even add more features.