Build a Decentralized Freelancer Marketplace with React, Solidity, and CometChat
Tags: dapp, web3, react, tutorial
Published: 2023-09-20 22:16:46

What you will be building, see the [live demo at sepolia test net](https://play-to-earn-three.vercel.app/) and the [git repo](https://github.com/Daltonic/dappworks).

![Chatting with client](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695212182243_Dappwork+Chat.gif)

![Bid placements](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695211319658_Dappworks+bidding.gif)

![Accepting Applicants](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695211560342_DappWorks+Accepting+Aplications.gif)

![Paying out worker](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695211820405_Paying+out+worker.gif)


Learn how to build a decentralized freelance marketplace like Upwork using React, Solidity, and CometChat.

In this step-by-step tutorial, we'll teach you:

- How to build React interfaces for job listing
- How to create solidity smart contracts for job managment
- How to integrate CometChat for one-on-one real-time communication
- How to make the marketplace decentralized and annoymous

Whether you're a seasoned developer or new to Web3, this tutorial will give you the skills to create your own freelance marketplace. Let's get started!


## Prerequisites

You will need the following tools installed to build along with me:

- Node.js
- Yarn
- MetaMask
- React
- Solidity
- [CometChat SDK](https://try.cometchat.com/oj0s7hrm5v78)
- Tailwind CSS

I recommend watching the videos below to learn how to set up your MetaMask for this project.

{% embed https://www.youtube.com/watch?v=qnudOwva0fM %}



## Installing Dependencies

Clone the starter kit and open it in VS Code using the command below: 


    git clone https://github.com/Daltonic/tailwind_ethers_starter_kit dappworks
    cd dappworks

Next, update the `package.json` with the snippet below.


{% gist https://gist.github.com/covelitein/99839042684ca244c24a6a45736f9138 %}


Please run the command `yarn install` in your terminal to install the dependencies for this project.


## Configuring CometChat SDK

To configure the [**CometChat SDK**](https://try.cometchat.com/oj0s7hrm5v78), please follow the steps provided below. Once completed, make sure to save the generated keys as environment variables for future use.

**STEP 1:**
Head to [**CometChat**](https://try.cometchat.com/daltonic) Dashboard and create an account.

![Register a new CometChat account if you do not have one](https://paper-attachments.dropboxusercontent.com/s_7D1A1D37F80B0518526730B73F3D0FC0AFE5FAF04B436DD20141EBE7A3684566_1692168014160_cometchat1.png)


**STEP 2:**
Log in to the [**CometChat**](https://try.cometchat.com/daltonic) dashboard, only after registering.


![Log in to the CometChat Dashboard with your created account](https://paper-attachments.dropboxusercontent.com/s_7D1A1D37F80B0518526730B73F3D0FC0AFE5FAF04B436DD20141EBE7A3684566_1692168070940_cometchat2.png)


**STEP 3:**
From the dashboard, add a new app called **Play-To-Earn****.**

![Create a new CometChat app - Step 1](https://paper-attachments.dropboxusercontent.com/s_7D1A1D37F80B0518526730B73F3D0FC0AFE5FAF04B436DD20141EBE7A3684566_1692168196068_cometchat4.png)

![Create a new CometChat app - Step 2](https://paper-attachments.dropboxusercontent.com/s_7D1A1D37F80B0518526730B73F3D0FC0AFE5FAF04B436DD20141EBE7A3684566_1692168247756_cometchat5.png)


**STEP 4:**
Select the app you just created from the list.

![Select your created app](https://paper-attachments.dropboxusercontent.com/s_7D1A1D37F80B0518526730B73F3D0FC0AFE5FAF04B436DD20141EBE7A3684566_1692168307217_cometchat6.png)


From the Quick Start copy the `APP_ID`, `REGION`, and `AUTH_KEY`, to your `.env` file. See the image and code snippet.

![Copy the the APP_ID, REGION, and AUTH_KEY](https://paper-attachments.dropboxusercontent.com/s_7D1A1D37F80B0518526730B73F3D0FC0AFE5FAF04B436DD20141EBE7A3684566_1692168367367_cometchat7.png)


Replace the `REACT_COMET_CHAT` placeholder keys with their appropriate values.


    REACT_APP_COMETCHAT_APP_ID=****************
    REACT_APP_COMETCHAT_AUTH_KEY=******************************
    REACT_APP_COMETCHAT_REGION=**

The `.env` file should be created at the root of your project.


## Configuring the Hardhat script

Navigate to the root directory of the project and open the "`hardhat.config.js`" file. Replace the existing content of the file with the provided settings.


{% gist https://gist.github.com/covelitein/e494add9d15cd497678fe7fe135ea57e %}


This code configures Hardhat for your project. It includes importing necessary plugins, setting up networks (with localhost as the default), specifying the Solidity compiler version, defining paths for contracts and artifacts, and setting a timeout for Mocha tests.


## The Smart Contract File

The following steps will guide you through the process of creating the smart contract file for this project:


1. Create a new folder named `contracts` inside the `src` folder.
2. Create a new file named `Dappworks``.sol` inside the `contracts` folder.
3. Copy the provided codes below and paste it into their respective files and save.

By following these steps, you will have successfully set up the necessary directory structure and created the `Dappworks``.sol` file, which will serve as the foundation for implementing the logic of the smart contract.


{% gist https://gist.github.com/Daltonic/9469656d751e3396e25d6e33e67578fe %}


The DappWorks smart contract is designed to facilitate a decentralized job marketplace, where users can create job listings, place bids on jobs, and manage the entire job lifecycle. Let's explore the key components and functionalities of this contract.


1. **Contract Inheritance and Libraries:**
    - The contract inherits from the `Ownable` and `ReentrancyGuard` contracts, which provide access control and protection against reentrancy attacks.
    - It imports several libraries from the OpenZeppelin framework, including `Counters` for managing counters, `SafeMath` for secure mathematical operations, and `Ownable` and `ReentrancyGuard` for access control and reentrancy protection.
        
2. **State Variables:**
    - The contract includes several state variables to manage job listings, freelancers, and bids. These include counters, structs, and mappings to store relevant data.
        
3. **Structs:**
    - The contract defines several structs, including `JobStruct`, `FreelancerStruct`, and `BidStruct`, to structure and store information about jobs, freelancers, and bids.
        
4. **Modifiers:**
    - The contract defines a modifier called `onlyJobOwner(uint id)` that restricts certain functions to the owner of a specific job listing.
        
5. **Functions:**
    - The contract includes various functions for managing job listings and bids, including:
        - `addJobListing`: Allows users to create a new job listing by providing a title, description, and tags. Users must also attach ether as a prize for the job.
        - `deleteJob`: Allows the owner of a job listing to delete it and receive the prize.
        - `updateJob`: Allows the owner of a job listing to update its details.
        - `bidForJob`: Allows users to place bids on job listings.
        - `acceptBid`: Allows the owner of a job listing to accept a specific bid from a freelancer, assigning the job to them.
        - `dispute`: Allows the owner of a job listing to initiate a dispute.
        - `revoke`: Allows the contract owner to revoke an assignment during a dispute.
        - `resolved`: Allows the contract owner to mark a dispute as resolved.
        - `payout`: Allows the owner of a job listing to pay the assigned freelancer, deducting a platform fee.
        - Various getter functions to retrieve information about jobs, bidders, freelancers, and more.
            
6. **Internal Functions:**
    - The contract includes internal functions for handling time and making payments.
7. **Events:**
    - The contract emits events to log various actions and state changes.
8. **Constructor:**
    - The contract does not have a constructor, indicating that it can be deployed as is.

Overall, this smart contract is designed to facilitate the creation, management, and completion of job listings on the Ethereum blockchain. Users can create job listings, place bids, and assign jobs to freelancers. It also includes features for dispute resolution and a platform fee for job payouts. 

🚀 Blockchain has real use cases, [**Join Dapp Mentors Academy for $8.44/month**](https://dappmentors.org/membership) to learn all you can.


![Dapp Mentors Academy](https://paper-attachments.dropboxusercontent.com/s_A669F6C723766110FAA73EBE4FA93F72A0924D07056B57BA53C0E19195292853_1692355875217_Screenshot+2023-08-18+at+11.50.50+AM.png)


[**Subscribe to Dapp Mentors Academy**](https://dappmentors.org/membership) today and get exclusive access to over 40 hours of web3 content, including courses on NFT minting, blockchain development, and more!


## The Test Script

The DappWorks test script is thoughtfully crafted to thoroughly evaluate and confirm the functionalities and behaviors of the DappWorks smart contract. Here's an organized breakdown of the primary tests and functions encompassed within the script:


{% gist https://gist.github.com/Daltonic/cd239d36a2578a755cb44adbb1518b93 %}

1. **Setup and Initialization:**
    - The script imports required libraries and defines a utility function `**toWei**` to convert ether amounts to wei.
    - It defines a test suite using Mocha's `**describe**` function and sets up initial variables and contract instances in the `**beforeEach**` hook.
        
2. **Job Creation Tests:**
    - The script includes several test cases to verify the creation and management of job listings.
    - `**should confirm fetching job listings**`: Checks if a job listing can be retrieved and confirms that there is one job listing.
    - `**should confirm fetching a single job listing**`: Retrieves a specific job listing and verifies its properties.
    - `**should confirm updating of job**`: Tests updating the details of a job listing and checks if the changes are reflected correctly.
    - `**should confirm job deletion**`: Adds and then deletes a job listing, verifying that the job listing count becomes zero.
    - `**should confirm bidding for job**`: Tests placing a bid on a job listing and confirms that there is one bidder.
    - `**should confirm accepting job bid**`: Places a bid, accepts the bid, and confirms the assignment of the job to a freelancer.
    - `**should confirm disputing a job**`: Initiates a dispute for a job listing and verifies that the job is marked as disputed.
    - `**should confirm revoking a disputed job**`: Places a bid, accepts the bid, disputes the job, and then revokes it. Checks if the job is listed again and the freelancer's assignment is revoked.
    - `**should confirm resolving a disputed job**`: Initiates a dispute and then resolves it, ensuring that the job is no longer marked as disputed.
    - `**should confirm payout of a job**`: Places a bid, accepts the bid, and performs a payout, confirming that the job is marked as paid out.

Each test case uses Chai's `**expect**` assertion to verify the expected outcomes of various contract interactions. The test script thoroughly tests the functionality of the `DappWorks` smart contract, covering job creation, bidding, assignment, dispute handling, payout, and more.


{% gist https://gist.github.com/covelitein/613b69aad4a16dedaec600d0cd445884 %}


By running `**yarn hardhat test**` on the terminal will test out all the essential function of this smart contract.


## The Deployment Scripts

The DappWorks deployment script is responsible for deploying the DappWorks smart contract to the Ethereum network using the Hardhat development environment. Here's an overview of the script:

**Key Components and Functionality**

- Imports the `ethers` and `fs` dependencies.
- Defines an asynchronous `main()` function to deploy the contract.
- Gets the contract factory for `DappWorks`.
- Deploys the contract and stores the contract instance in the `contract` variable.
- Waits for the deployment to complete.
- Extracts the contract address and stores it in the `address` variable.
- Writes the address to a JSON file in the `src/abis/` directory.
- Handles any errors that may occur during execution.
- Invokes the `main()` function.
- Logs the deployed contract address to the console if the deployment is successful.
    

The DappWorks deployment script simplifies the deployment of the DappWorks smart contract and generates a JSON file, `**contractAddress.json**`, containing the deployed contract's address. This file can be used for further integration and interaction with the deployed contract within the project.

To utilize this script, create a folder named "scripts" in the root directory of your project if it doesn't already exist. Inside the "scripts" folder, create a JavaScript file named `**deploy.js**`, and then copy and paste the provided deployment script into this file.


{% gist https://gist.github.com/covelitein/9cac21f0ffaa36027f9cf5def1b9e339 %}


Next, run the `**yarn hardhat run scripts/deploy.js**` to deploy the smart contract into the network on a terminal.


![Activities of Deployment on the Terminal](https://paper-attachments.dropboxusercontent.com/s_95E5B376EA7D56400134387A4ABCBB8612C903A22CB8FFB5FE3936C174654F13_1681314007681_0RFvAh6Q.png)


If you require additional assistance with setting up Hardhat or deploying your Fullstack DApp, I recommend watching this informative video that provides guidance and instructions.


{% embed https://www.youtube.com/watch?v=6lIq8MCfaGE %}

## Developing the Frontend

To start developing the frontend of our application, we will create a new folder called `components` inside the `src` directory. This folder will hold all the components needed for our project. 

For each of the components listed below, you will need to create a corresponding file inside the `src/components` folder and paste its codes inside it.


## Header Component
![Header Component](https://paper-attachments.dropboxusercontent.com/s_5AF4E60A448E7CCBDCFC6460D3BD09B65DCB276698B51E9AB83E331FDEC3FB9B_1695117555683_screenshoteasy+-+2023-09-19T073913.223.png)


The DappWorks header component is a central part of the user interface. It features the DappWorks logo, navigation links for easy access to various app sections, and a wallet connection button. The mobile-friendly design includes a toggle button for a compact menu. This component enhances user navigation and wallet integration.


{% gist https://gist.github.com/covelitein/ebee1b48843427770a25b94d2e520c5c %}



## Job Listing Card Component
![Job listing card Freelancer view](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695216813369_Screenshot+2023-09-20+at+2.33.27+PM.png)

![Job listing card Owner view](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695217489019_Screenshot+2023-09-20+at+2.44.41+PM.png)


The `JobListingCard` component renders a card displaying information about a job listing, including the title, price, tags, and description. Users can interact with the card to place bids or manage job management tasks. The component handles user interactions and provides visual feedback through toast notifications. It also checks the user's account status to determine the appropriate actions to display on the card.


{% gist https://gist.github.com/Daltonic/a1a04c46b478951c20db99400f899a54 %}



{% embed https://www.youtube.com/watch?v=JxkC2QtZBkw %}


Watch my new YouTube tutorial to learn how to integrate RainbowKit's multi-wallet connector into your dApp to improve the quality and user experience.

## CreateJob Component
![Create Job Component](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695216965187_Screenshot+2023-09-20+at+2.36.00+PM.png)


The CreateJob component  enables users to create job listings through a user-friendly modal interface. Users input job details, including title, prize, skills, and description. The component supports up to five featured skills, provides modal controls, and offers transaction feedback via toast notifications. It seamlessly integrates with global state management for a smooth user experience.


{% gist https://gist.github.com/covelitein/646dfb750dd1f800cb36f844b37f4e5f %}



## DeleteJob Component
![Delete Job component](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695217116683_Screenshot+2023-09-20+at+2.38.32+PM.png)


The DeleteJob component is responsible for displaying a confirmation modal when users attempt to delete a job listing. It provides clear visual cues, including a trash icon, a confirmation message, and warning about irreversible actions. Users can either cancel or proceed with the deletion, with toast notifications providing feedback on the outcome of the transaction.


{% gist https://gist.github.com/covelitein/6e594f2c52ee26214b416e090b873226 %}



## UpdateJob Component
![Update Job Component](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695217259876_Screenshot+2023-09-20+at+2.40.55+PM.png)


The UpdateJob component is responsible for displaying a modal that allows users to update an existing job listing. It retrieves the job details, pre-fills the form fields, and provides an interface for users to make changes. Upon submission, it triggers the update process on the blockchain and displays toast notifications to indicate the outcome of the transaction.


{% gist https://gist.github.com/covelitein/b815acbdaf030106e760ff60a4c8c9f2 %}



## JobListingOwnerActions Component
![Owner Actions](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695218255009_Screenshot+2023-09-20+at+2.57.30+PM.png)

![Completed State](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695218331999_Screenshot+2023-09-20+at+2.58.41+PM.png)


This component renders a set of actions that an owner of a job listing can perform. It displays information about the job listing, including the title, price, tags, and description. Depending on the status of the job listing, it allows the owner to perform actions such as updating, deleting, viewing bidders, paying, and chatting with a freelancer. The component also handles different visual representations based on the state of the job listing, such as showing a "Completed" status when the job has been paid out.


{% gist https://gist.github.com/Daltonic/2b3a13c8896fab10c48d33348d9b3a1f %}



## JobBid Component
![Job Bid Component](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695225762678_Screenshot+2023-09-20+at+5.02.37+PM.png)

![Job Bid Component](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695226613280_Screenshot+2023-09-20+at+5.16.48+PM.png)


This component displays information about a job listing for potential bidders. It renders the job title, price (in Ethereum), tags, and job description. Additionally, it provides a "Chat with freelancer" button that allows users to initiate a chat with the owner of the job listing. It serves as a preview of the job for individuals interested in bidding on it.


{% gist https://gist.github.com/covelitein/2ec985aff09f1b14f9d3e49237fed973 %}



## ApplicantsCard Component
![Bidding Applicants](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695226823294_Screenshot+2023-09-20+at+5.15.21+PM.png)


This component display information about applicants or bidders for a job listing. It shows the bidder's truncated Ethereum account address, along with buttons for initiating a chat with the bidder and accepting their bid. The "Chat" button links to a chat page with the bidder, and the "Accept" button allows the job owner to accept the bidder's offer. It provides a user-friendly interface for managing job applications.


{% gist https://gist.github.com/covelitein/a4248324a52b32e032cb2427576a41c8 %}



## Payout Components
![The payout component](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695227276979_Screenshot+2023-09-20+at+5.27.48+PM.png)


The `Payout` component is used to facilitate the payout process for a job listing. It displays a modal dialog with an option to initiate a payment. Users can either proceed with the payout or cancel it. Upon initiating the payout, it communicates with the blockchain using the `payout` function and displays toast notifications to inform the user about the transaction status. This component provides a user-friendly interface for handling payouts for completed jobs.


{% gist https://gist.github.com/covelitein/06fedb94859895417ff62b685e46736b %}


**Want to learn how to build an Answer-To-Earn DApp with Next.js, TypeScript, Tailwind CSS, and Solidity?** [**Watch this video now!**](https://youtu.be/Ubom39y5jX8)


{% embed https://www.youtube.com/watch?v=Ubom39y5jX8 %}


This video is a great resource for anyone who wants to learn how to build decentralized applications and earn ethers. 

Now that we have covered all the components in this application, it is time to start coupling the various pages together. Let's start with the homepage.

To begin developing the pages of our application, we will create a new folder called `pages` inside the `src` directory. This folder will hold all the pages needed for our project. 

For each of the pages listed below, you will need to create a corresponding file inside the `src/pages` folder, just as you did before with the components.


## Home Page
![The Home Page](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695227507098_Screenshot+2023-09-20+at+5.31.42+PM.png)


The `Home` page combines other components, including `Header`, `Hero`, and `CreateJob`, to create the user interface for the home page. The `Header` typically contains navigation links and branding, the `Hero` section might display introductory content or visuals, and the `CreateJob` section allows users to create new job listings. Overall, this component assembles these parts to create the complete homepage of the application.


{% gist https://gist.github.com/covelitein/87f77c7ba0f8c93921e41b8e8b817b7c %}



## MyProjects Page
![My Projects Page](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695227731021_Screenshot+2023-09-20+at+5.35.27+PM.png)


The `MyProjects` page is where users can manage their own job listings and take various actions on them. It includes components such as `Header` for navigation, `JobListingOwnerActions` to display and manage job listings, `UpdateJob` for updating job details, `DeleteJob` for deleting job listings, and `Payout` for initiating payments. Users can view their posted jobs, edit or delete them, and initiate payouts to freelancers. If no jobs are posted, it displays a message indicating that no jobs are available.


{% gist https://gist.github.com/covelitein/e023e124fd0de692322838ca1430f166 %}



## MyJobs Page
![My Jobs Page](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695227908422_Screenshot+2023-09-20+at+5.38.23+PM.png)


The `MyJobs` component is where users can view the tasks or jobs that have been assigned to them. It includes a `Header` for navigation and a list of `JobBid` components that display information about each assigned task. If there are assigned tasks, it shows them with their details; otherwise, it displays a message indicating that there are no assigned tasks for the user.


{% gist https://gist.github.com/Daltonic/09a94830ea974a6649cb3602a9b22862 %}



## MyBids Page
![My Bids Page](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695228095215_Screenshot+2023-09-20+at+5.41.30+PM.png)


The `MyBids` page is where users can view the jobs they have applied for by placing bids. It includes a `Header` for navigation and a list of `JobBid` components that display information about each job the user has bid on. If there are jobs the user has bid on, it shows them with their details; otherwise, it displays a message indicating that the user hasn't bid on any jobs yet.


{% gist https://gist.github.com/Daltonic/cd5fd8d3600407e4af98b99d077e4cb8 %}



## ViewBidders Page
![Bidders Page](https://paper-attachments.dropboxusercontent.com/s_5AF4E60A448E7CCBDCFC6460D3BD09B65DCB276698B51E9AB83E331FDEC3FB9B_1695157751683_screenshoteasy+-+2023-09-19T074753.918.png)


The `ViewBidders` page is where users can view the list of applicants for a specific job listing. It utilizes the `useParams` hook to extract the job ID from the URL, fetches the list of bidders and job details from the blockchain, and displays them. Depending on whether there are applicants or if the position is filled or vacant, it displays relevant information such as applicants' cards or status messages. It also includes a `Header` component for navigation.


{% gist https://gist.github.com/covelitein/e86b934f0c739036f2624e6f8e126293 %}



## Authenticate Page
![Authentication Page](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695230250330_Screenshot+2023-09-20+at+6.17.26+PM.png)


The `Authenticate` page is   for user authentication for chatting within the application. It allows users to either log in or sign up for chat functionality using the CometChat service. Upon successful authentication, it displays a success message and navigates the user to the chat messages page. It also includes a `Header` component for navigation and provides feedback to the user through toast notifications.


{% gist https://gist.github.com/covelitein/5b323f31b35e8e4b186993daee2b1cec %}



## RecentConversations Page
![Recent Conversation Page](https://paper-attachments.dropboxusercontent.com/s_624970531A2FE2D99B640E5096CB9639468B70879BF9D00F76486BDC72F83E7C_1695230191608_Screenshot+2023-09-20+at+6.16.26+PM.png)


The "RecentConversations" page in the DappWorks app displays a list of recent chat conversations. It fetches and displays these conversations, allowing users to click on a conversation to navigate to the chat interface with that user. Each conversation displays the user's name and a unique Identicon for easy identification. If there are no recent chats, a message notifies the user. This page provides a convenient way to access and manage recent chat interactions.


{% gist https://gist.github.com/covelitein/579e94cf4a5bf489cad32201a807a7e3 %}



## Chats Page
![The Chat Page](https://paper-attachments.dropboxusercontent.com/s_5AF4E60A448E7CCBDCFC6460D3BD09B65DCB276698B51E9AB83E331FDEC3FB9B_1695158961082_screenshoteasy+-+2023-09-19T075126.445.png)


The `Chats` page is responsible for managing and displaying chat messages between users. It retrieves and displays messages based on the selected user, allows users to send messages, and automatically updates the chat in real-time. Users can see their own messages on the right side and messages from the other user on the left side, with profile icons and message content. The component also includes a `Header` for navigation and maintains a scrolling chat container for easy viewing of messages.


{% gist https://gist.github.com/covelitein/039caf1ec6fb79cf6928627710209472 %}



## The Blockchain Service

This script is a JavaScript module that interacts with a blockchain smart contract using the Ethereum blockchain. It provides functions for various actions related to the blockchain and stores or retrieves data from the blockchain. Note that you will have to create a file called `blockchain.jsx` within the `src >> services` folder and paste the code below inside.


{% gist https://gist.github.com/Daltonic/9f69b20f66d9b49d2c90debcf3d8aeda %}


**Here's an overview of what this script does:**

1. It imports necessary dependencies, including contract ABI (Application Binary Interface), contract addresses, and Ethereum-related libraries.
2. Defines utility functions like `toWei` and `fromWei` to convert between Ether and Wei.
3. Defines a function `getEthereumContract` to establish a connection to the Ethereum blockchain and retrieve a contract instance.
4. `isWalletConnected` checks if a user's Ethereum wallet (e.g., MetaMask) is connected and handles account changes and chain changes.
5. Functions like `connectWallet`, `addJobListing`, `updateJob`, `deleteJob`, `bidForJob`, `acceptBid`, `dispute`, `resolved`, `revoke`, `payout`, `bidStatus`, `getBidders`, `getFreelancers`, `getAcceptedFreelancer`, `getJobs`, `getMyJobs`, `getJob`, `getMyBidJobs`, `getMyGigs`, and `loadData` are defined to interact with the smart contract for various actions such as creating jobs, bidding, accepting bids, and more.
6. `structuredJobs`, `structuredBidder`, and `structuredFreelancers` functions format data retrieved from the blockchain into structured objects for easier management and display.

Overall, this script acts as an interface between the front-end application and the Ethereum blockchain, allowing users to perform actions and retrieve data related to jobs and bids on the blockchain. It integrates with a smart contract using the contract's ABI and address. See the script above. 

Please ensure that you update the environment variables to look like this:


    REACT_APP_COMETCHAT_APP_ID=****************
    REACT_APP_COMETCHAT_AUTH_KEY=******************************
    REACT_APP_COMETCHAT_REGION=**
    REACT_APP_RPC_URL=http://127.0.0.1:8545


## The Chat Service

This script is a JavaScript module that provides functionality for integrating and interacting with the CometChat Pro service within a web application. CometChat Pro is a chat and messaging platform that allows developers to add real-time chat features to their applications. Like with the previous service you will have to create another file called `chat.jsx` within the `src >> services` folder and paste the code below inside.


{% gist https://gist.github.com/covelitein/76af89be61f44450498220da9bcb4572 %}


**Here is a breakdown of how this script works:**

1. It imports the CometChat library (`CometChat`) and a function (`getGlobalState`) from a custom store.
    
2. It defines constants (`CONSTANTS`) for the CometChat application settings, including the App ID, region, and authentication key. These settings are typically stored in environment variables for security.
    
3. The `initCometChat` function initializes CometChat with the provided application settings. It subscribes to user presence updates and sets the region. Initialization is done asynchronously, and any errors encountered during initialization are caught and logged.
    
4. The `loginWithCometChat` function performs user login with CometChat. It takes the user's unique identifier (UID) and authentication key as parameters, attempts to log in, and returns a promise that resolves to the user object upon successful login or rejects with an error in case of failure.
    
5. The `signUpWithCometChat` function creates a new user on CometChat. It also takes the user's UID and authentication key as parameters, sets the user's name, and returns a promise that resolves to the newly created user upon success or rejects with an error in case of failure.
    
6. The `logOutWithCometChat` function logs the current user out of CometChat. It returns a promise that resolves upon successful logout or rejects in case of an error.
    
7. The `isUserLoggedIn` function checks if a user is currently logged in to CometChat and returns a promise that resolves to the logged-in user or rejects with an error.
    
8. The `getUser` function retrieves user information from CometChat based on the provided UID. It returns a promise that resolves to the user object or rejects with an error.
    
9. The `getMessages` function fetches messages for a specific user (UID) from CometChat. It sets a message limit and returns a promise that resolves to an array of text messages or rejects with an error.
    
10. The `sendMessage` function sends a text message to a specified receiver (receiverID) through CometChat. It returns a promise that resolves to the sent message or rejects with an error.
    
11. The `getConversations` function retrieves a list of conversations from CometChat. It sets a conversation limit and returns a promise that resolves to the list of conversations or rejects with an error.
    
12. The `listenForMessage` function sets up a listener to receive incoming text messages in real-time. It takes a listenerID (typically a user's UID) and returns a promise that resolves to the received message or rejects with an error.

Overall, this script enables the integration of CometChat Pro features into a web application, including user management, message retrieval, sending messages, and real-time message listening. It abstracts the CometChat functionality into convenient functions for use within the application.

Excellent! Now, let's work on the `store` file, which serves as a state management library.


## The Store File

This script provides a central state management system for a React application using the `react-hooks-global-state` library. It also includes utility functions for text truncation and date formatting. You will have to create a file called `index.jsx` within the `src >> store` folder and paste the code below inside.


{% gist https://gist.github.com/covelitein/af525c04ae5c5610da6a8e9b48c6072d %}


**Here's an overview of what this script does:**

1. It imports the `createGlobalState` function from the `react-hooks-global-state` library.
    
2. It uses the `createGlobalState` function to create a global state container with initial state values. This global state container is then deconstructed into three functions: `setGlobalState`, `useGlobalState`, and `getGlobalState`.
    - `setGlobalState`: A function used to set or update global state values. It takes a key and a new value as arguments.
    - `useGlobalState`: A custom hook that allows components to access and subscribe to global state values. It returns the current value associated with a specified key and automatically updates the component when that value changes.
    - `getGlobalState`: A function that retrieves the current value associated with a specified key from the global state.
        
3. It defines a `truncate` function that takes a text string, start and end character counts, and a maximum length as arguments. This function truncates the text and adds ellipses (...) in the middle if the text exceeds the specified maximum length. It's used for shortening text for display.
    
4. It defines a `formatDate` function that takes a timestamp as an argument and returns a formatted date string in the format "Month Day, Year." This function is used for formatting timestamps into more human-readable date strings.
    
5. It defines a `timestampToDate` function that takes a timestamp as an argument and returns a formatted date string in the format "Month Day, Year Hour:Minute." This function is used for formatting timestamps into more detailed date and time strings.

Overall, this script serves as a global state management solution for a React application, allowing different components to share and access state data easily. It also provides utility functions for common text and date formatting operations.

## The Index files

The `index.jsx` file is the entry point for the application. It initializes the CometChat service, sets up dependencies, and renders the React application using the `App` component within a `BrowserRouter`. It creates a root element for rendering and sets up the necessary configurations for the application to start running.

To use this code, you will need to replace the code below inside of the `index.jsx`  and `index.css` files in the `src` folder of your project.


{% gist https://gist.github.com/covelitein/0fce1ceb8686eb85216ad9dc1b9ef4f9 %}

{% gist https://gist.github.com/covelitein/5b2802e7166befcb0ed5751cf4ef5c1d %}


Now you are officially done with the build, just execute the following commands to have the application running on the browser.


- Terminal #1: `**yarn hardhat node**`
- Terminal #2: `**yarn hardhat run scripts/deploy.js**` and then `**yarn start**`

Congratulations on building a Web3 Upwork clone with React, Solidity, and CometChat! 🚀
Your achievement is a testament to your prowess in combining these cutting-edge technologies to craft an innovative and engaging application. By harnessing React for the frontend, Solidity for your smart contracts, and integrating CometChat for real-time communication, you've showcased a versatile skill set in both blockchain development and interactive user experiences.

Your Web3 Upwork clone stands as a remarkable project, bringing together the power of blockchain, modern web development, and real-time communication to create a platform that empowers users and facilitates collaboration in a decentralized manner.

Keep up the great work, and continue exploring the endless possibilities of technology! Your journey in the world of Web3 development is bound to lead to even more exciting and impactful projects in the future.

[**Here is a link to the CometChat website where you can learn more about the SDK and how to get started.**](https://try.cometchat.com/oj0s7hrm5v78)

For more web3 resources, check out this video that teaches how to create a decentralized app by building a web3 lottery dapp, I recommend that you it.


{% embed https://www.youtube.com/watch?v=mVxRzkvX_w0 %}


The video provides a hands-on tutorial on how to build a lottery dapp using NextJs, Tailwind CSS, and Solidity.


## Conclusion

Congratulations on completing the journey of building a Web3 Upwork clone with React, Solidity, and CometChat. This comprehensive guide has empowered you to create a cutting-edge platform that combines the power of React for the frontend, Solidity for smart contracts, and CometChat for real-time communication. By undertaking this project, you've demonstrated your prowess in blockchain development and interactive user experiences.

This tutorial has unveiled the potential of web3 technology in transforming the gig economy, offering secure and transparent transactions while enhancing user engagement through dynamic real-time interactions. The smart contracts have been rigorously tested to ensure reliability, making your Upwork clone a robust and trustworthy platform for users.

As you conclude this project, you're not only equipped with technical skills but also with a vision of the future where decentralized applications redefine traditional industries. Your Upwork clone is a testament to the possibilities that emerge when innovative technologies converge.
To further enhance your knowledge and stay updated on the latest developments in blockchain and web3, consider subscribing to our [**YouTube channel**](https://www.youtube.com/@dappmentors?sub_confirmation=1) and [**exploring our website for additional resources.**](https://dappmentors.org/)

Best wishes on your journey of innovation and discovery in the world of web3 and decentralized applications!


## About Author

I am a web3 developer and the founder of [Dapp Mentors](https://dappmentors.org/), a company that helps businesses and individuals build and launch decentralized applications. I have over 7 years of experience in the software industry, and I am passionate about using blockchain technology to create new and innovative applications. I run a [**YouTube channel called Dapp Mentors**](https://www.youtube.com/@dappmentors?sub_confirmation=1) where I share tutorials and tips on web3 development, and I regularly post articles online about the latest trends in the blockchain space.

**Stay connected with us, join communities on**
Discord: [Join](https://discord.gg/PgFDUVT6n9)
Twitter: [Follow](https://twitter.com/iDaltonic)
LinkedIn: [Connect](https://www.linkedin.com/company/dapp-mentors)
GitHub: [Explore](https://github.com/Daltonic)
Website: [Visit](https://dappmentors.org/)