> For the complete documentation index, see [llms.txt](https://docs.obto.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.obto.co/apps/sample-apps/user-management-app.md).

# User Management App

In this article we will show you how to use OBTO platform for development purpose by creating a basic CRUD application where we can create user, read , update users, basically manage users.

Below is the Image of what we will be building

<figure><img src="https://media.licdn.com/dms/image/D4D12AQFRs803yVv1ZQ/article-inline_image-shrink_400_744/0/1715076664195?e=1721260800&#x26;v=beta&#x26;t=shtTaghSOMr0Vb10NXoHe9-2TpoH99oVxYDPYNkJ4So" alt=""><figcaption><p><br></p></figcaption></figure>

<br>

For that we will create a new app named 'userprofile'. In order to that follow below steps :-

* Login to "\<your-space>.obto.co"

<figure><img src="https://media.licdn.com/dms/image/D5612AQFzL4SB5uT1iA/article-inline_image-shrink_400_744/0/1714492117772?e=1721260800&#x26;v=beta&#x26;t=tghB_k0bT-vZAQwn7bCS82ArIowk9JV0wlsQwQXAbEs" alt=""><figcaption><p><br></p></figcaption></figure>

* On left navigation, click on Home > IDE. The IDE will open up

<figure><img src="https://media.licdn.com/dms/image/D5612AQFKlIp-wyHc5g/article-inline_image-shrink_400_744/0/1714492153227?e=1721260800&#x26;v=beta&#x26;t=lqF-ihvxx8YSSqpgjQ06OSIgxqoFAb52QOSm9zO5EWs" alt=""><figcaption><p><br></p></figcaption></figure>

* Click on Create New Button

<figure><img src="https://media.licdn.com/dms/image/D5612AQFIA4XYPm-cwQ/article-inline_image-shrink_400_744/0/1714492196187?e=1721260800&#x26;v=beta&#x26;t=0zn3C2e_FMa_2d7VV5JHhnMqnqtuDe8cgFDZIqnfae4" alt=""><figcaption><p><br></p></figcaption></figure>

* A modal popup will open. Enter the name as "userprofile" and Provide some description of the app

<figure><img src="https://media.licdn.com/dms/image/D5612AQEWEtefTqmT9Q/article-inline_image-shrink_400_744/0/1714492605721?e=1721260800&#x26;v=beta&#x26;t=pcLWpUhLlLVne_3ue8I8tXr9w4RPFx8pzll1PSh0VOs" alt=""><figcaption><p><br></p></figcaption></figure>

* Your app will open on the left side of the IDE in file explorer

<figure><img src="https://media.licdn.com/dms/image/D5612AQFxY9UeMv0C7A/article-inline_image-shrink_400_744/0/1714492713615?e=1721260800&#x26;v=beta&#x26;t=rvRdWn8TGv4Zq1Y9mAkn8Mfm1nZE3WS9LUWkVpHp49I" alt=""><figcaption><p><br></p></figcaption></figure>

#### CREATING THE DATABASE

* We need database to store our users, so lets create the Table for storing the user information.
* To create a table, click on DB icon on top right corner of the IDE.

<figure><img src="https://media.licdn.com/dms/image/D5612AQGJRANdGq7Mrg/article-inline_image-shrink_400_744/0/1715191830839?e=1721260800&#x26;v=beta&#x26;t=-VD3wDAgPS_Wh7VSqV3n1gIr-AmAXDEGP8DEPan-T8w" alt=""><figcaption><p><br></p></figcaption></figure>

* A drawer will open up. Click on "Create Table" button.

<figure><img src="https://media.licdn.com/dms/image/D5612AQGzL3DfmmDdwg/article-inline_image-shrink_400_744/0/1715191830934?e=1721260800&#x26;v=beta&#x26;t=d65nyH_WR5qf_gTrbSVrAjJHtypWLVRAahuo0t5XlSk" alt=""><figcaption><p><br></p></figcaption></figure>

* A modal will open up. Enter the name of the table.

<figure><img src="https://media.licdn.com/dms/image/D5612AQEcFbWNmGuvwQ/article-inline_image-shrink_400_744/0/1715191830857?e=1721260800&#x26;v=beta&#x26;t=M1MM2ax4USvZeVDAQJfkgrRvY7jPSs-39ggDiC_MItg" alt=""><figcaption><p><br></p></figcaption></figure>

* Now we will need to add column to our table. Click on DB icon on top right corner of the IDE, same drawer opens up. Search tablename we just created. Click on "Add New Column" Button

<figure><img src="https://media.licdn.com/dms/image/D5612AQHPEaJkcAFIDg/article-inline_image-shrink_400_744/0/1715191830879?e=1721260800&#x26;v=beta&#x26;t=HdRZV8tICfVUS3g21N09gHwwB-hYXCbgY05tbY1P1mw" alt=""><figcaption><p><br></p></figcaption></figure>

* A modal opens up asking for the details of the column we want to add. Enter the necessary details and submit. A column will be added.

<figure><img src="https://media.licdn.com/dms/image/D5612AQH8gycQDsqIUg/article-inline_image-shrink_400_744/0/1715191830880?e=1721260800&#x26;v=beta&#x26;t=vv-3t2E9tgDSXqL6t9RDCjEFWLInmgI2HYy7KdwLjNY" alt=""><figcaption><p><br></p></figcaption></figure>

* To view the table we just created, click on 'View'

<figure><img src="https://media.licdn.com/dms/image/D5612AQHaXTFSUuRUZQ/article-inline_image-shrink_400_744/0/1715191830862?e=1721260800&#x26;v=beta&#x26;t=wQrzUjdAFy5LiymuWxJ1tPp38k8x5qXM9BOH0OjW1WE" alt=""><figcaption><p><br></p></figcaption></figure>

* A new tab will open up rendering the table view. Here you can see the field we created, rest of the fields are provided by the platform that required by every table, so they are common.

<figure><img src="https://media.licdn.com/dms/image/D5612AQEYt7MfmMWmqg/article-inline_image-shrink_400_744/0/1715191830857?e=1721260800&#x26;v=beta&#x26;t=wl01uiIqcrcgoI6lEKrHDQTTW0we0_CIlN1NkrZedWw" alt=""><figcaption><p><br></p></figcaption></figure>

* Similarly you can add rest of the fields like Email, Last Name.

### BUILDING THE FRONTEND

* To Edit HTML, Expand the app > UI Template > userprofile

<figure><img src="https://media.licdn.com/dms/image/D5612AQGfZYT_bCNbeg/article-inline_image-shrink_400_744/0/1714492877620?e=1721260800&#x26;v=beta&#x26;t=557T-N18l1LACL2Dsixfa_hLcbQUAoGE22jYge5fLmY" alt=""><figcaption><p><br></p></figcaption></figure>

* Lets write some HTML. We will render root React Component.

<figure><img src="https://media.licdn.com/dms/image/D5612AQFciFwwTWl_Ew/article-inline_image-shrink_400_744/0/1715081066856?e=1721260800&#x26;v=beta&#x26;t=5TY0BYHQx2A7_I7Q-TeuUPHfqevCUohFeR9t4sgBK2Q" alt=""><figcaption><p><br></p></figcaption></figure>

<br>

* Now you must be thinking from where the component will be mounted in this container. So now we will write some React Js code. In order to do so, Expand the app > Policy Client > userprofile.

<figure><img src="https://media.licdn.com/dms/image/D5612AQHfpC4sz_afeQ/article-inline_image-shrink_400_744/0/1715083306599?e=1721260800&#x26;v=beta&#x26;t=FTHhvYSjZhxrSam86EufBbU00KXB9_9_azoPNflU1Vo" alt=""><figcaption><p><br></p></figcaption></figure>

<br>

* Now we will create this UserProfile Component. In order to do so click on hamburger icon on top of the file explorer > Select Client Script > Modal will open up > Enter the name of the Component as UserProfile > File will open up in editor. Below is the code for the root component.

```
const { useEffect } = React;
const {
  CaretRightOutlined,
  FormatPainterOutlined,
  CodeSandboxOutlined,
  ClearOutlined,
  DatabaseOutlined
} = antdIcons;
const { Menu, Layout, theme, Tooltip, Button, Drawer, Space, Table, Input, Tag } = antd;
const { Column, ColumnGroup } = Table;
const { Header, Content, Sider } = Layout;

const UserProfile = React.forwardRef((props, ref) => {
  const CreateUserModal = ob.M.CreateUserModal;
  const UpdateUserModal = ob.M.UpdateUserModal;
  const [open, setOpen] = React.useState(false);
  const [users, setUsers] = React.useState([]);
  const [usersCopy, setUsersCopy] = React.useState([]);
  const [inputTypes, setInputTypes] = React.useState(false);


  const showDrawer = () => {
    setOpen(true);
  };

  const onClose = () => {
    setOpen(false);
  };

  const columns = [
  {
    title: 'First Name',
    dataIndex: 'first_name',
  },
  {
    title: 'Last Name',
    dataIndex: 'last_name',
  },
  {
    title: 'Email',
    dataIndex: 'email',
  },
  {
    title: 'Status',
    dataIndex: 'status',
    render: (text, row) => {
      return (
        <Tag color={row.active ? 'green' : 'volcano'}>
          {row.active ? 'Active' : 'Inactive'}
        </Tag>
      )
    }
  },
  {
    title: 'Update',
    dataIndex: 'update',
    render: (text, row) => <UpdateUserModal user={row} closeDrawer={onClose}/>,
  },
];
  

  const getAllUsers = () => {
    return http.get(`/ms/getuserprofiledata`, {
      headers: {
        "Content-Type": "application/json"
      }
    });
  };

  useEffect(async () => {
    const response = await getAllUsers();
    setUsers(response.data);
    setUsersCopy(response.data);
  }, []);
  const handleSearchChange = e => {
    const value = e.target.value.toLowerCase();
    const newTableData = users.filter(user => {
      let userName = user.first_name ? user.first_name.toLowerCase() : "";
      return userName.startsWith(value);
    });
    setUsersCopy(newTableData);
  };

  return (
    <React.Fragment>
        <div><h1 className="text-center">USER MANAGER</h1></div>
        <div style={{display:"flex"}}>
          <Input placeholder="Search..." onChange={handleSearchChange} />
          <CreateUserModal closeDrawer={onClose}/>
        </div>
        <Table
            className="mt-5"
            columns={columns}
            dataSource={usersCopy}
        />
    </React.Fragment>
  );
});

return UserProfile;

```

* Now lets create CreateUserModal and UpdateUserModal component which are imported in the above UserProfile Component.

```

const { useEffect,useState } = React;
const { Form, Input, Button, Modal, Alert } = antd;
const { UserAddOutlined } = antdIcons;

const CreateUserModal = ({closeDrawer}) => {
  const [formData, setFormData] = useState({});
  const [open, setOpen] = useState(false);
  const [successMessage, setSuccessMessage] = useState("");
  const [errorMessage, setErrorMessage] = useState("");
  const [confirmLoading, setConfirmLoading] = useState(false);
  const [modalText, setModalText] = useState("Content of the modal");
  const showModal = () => {
    closeDrawer();
    setOpen(true);
  };

  const createUser = () => {
    return http({
      method: "post",
      url: "/ms/createuser",
      data: {
        first_name: formData.firstName,
        last_name: formData.lastName,
        email: formData.email,
        active:"true"
      }
    });
  }

  const handleOk = async () => {
    setConfirmLoading(true);
    try {
      const response = await createUser();
      if(response.status === 200) {
        setSuccessMessage(`User Created Successfully`);
      }
    } catch(err) {
      if(err.response.status === 400) {
        setErrorMessage("User already exists");
      }
      
    }
    setConfirmLoading(false);
    setTimeout(() => {
      setOpen(false);
      
    }, 2000);
  };

  const handleCancel = () => {
    console.log("Clicked cancel button");
    setOpen(false);
  };

  const handleChange = event => {
    let nextFormData = JSON.parse(JSON.stringify(formData));
    nextFormData[event.target.name] = event.target.value;
    setFormData(nextFormData);
  };

  return (
    <React.Fragment>
      <Button type="primary" style={{height: "40px"}} onClick={showModal}>
        <UserAddOutlined style={{fontSize:"1.5em"}}/>
      </Button>
      <Modal
        id="create-user-modal"
        title="Create User"
        open={open}
        confirmLoading={confirmLoading}
        onCancel={handleCancel}
        footer={[
          <Button key="submit" type="primary" loading={confirmLoading} onClick={handleOk}>
            Submit
          </Button>
        ]}
      >
        <Form labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
            <Form.Item label="First Name">
                <Input
                    name="firstName"
                    defaultValue={formData.firstName || ""}
                    onChange={handleChange}
                />
            </Form.Item>
            <Form.Item label="Last Name">
                <Input
                    name="lastName"
                    defaultValue={formData.lastName || ""}
                    onChange={handleChange}
                />
            </Form.Item>
            <Form.Item label="Email">
                <Input
                    name="email"
                    defaultValue={formData.email || ""}
                    onChange={handleChange}
                />
                
                { successMessage ? <Alert message={successMessage} type="success" showIcon /> : "" }
                { errorMessage ? <Alert message={errorMessage} type="error" showIcon /> : "" }
            </Form.Item>
        </Form>
      </Modal>
    </React.Fragment>
  );
};

return CreateUserModal;
```

```
const { useEffect, useState } = React;
const { Form, Input, Button, Modal, Alert, Checkbox } = antd;

const UpdateUserModal = ({ user, closeDrawer }) => {
  const [formData, setFormData] = useState({
    _id: user._id,
    firstName: user.first_name,
    lastName: user.last_name,
    email: user.email,
    active: user.active
  });
  const [open, setOpen] = useState(false);
  const [successMessage, setSuccessMessage] = useState("");
  const [errorMessage, setErrorMessage] = useState("");
  const [confirmLoading, setConfirmLoading] = useState(false);
  const [modalText, setModalText] = useState("Content of the modal");
  const showModal = () => {
    closeDrawer();
    setOpen(true);
  };

  const updateUser = () => {
    return http({
      method: "post",
      url: "/ms/updateuserprofiledata",
      data: {
        _id:formData._id,
        first_name: formData.firstName,
        last_name: formData.lastName,
        email: formData.email,
        active: formData.active
      }
    });
  };

  const handleOk = async () => {
    setConfirmLoading(true);
    try {
      const response = await updateUser();
      if (response.status === 200) {
        setSuccessMessage(`User Updated Successfully`);
      }
    } catch (err) {
      if (err.response.status === 400) {
        setErrorMessage("User already exists");
      }
    }
    setConfirmLoading(false);
    setTimeout(() => {
      setOpen(false);
    }, 2000);
  };

  const handleCancel = () => {
    console.log("Clicked cancel button");
    setOpen(false);
  };

  const handleChange = event => {
    let nextFormData = JSON.parse(JSON.stringify(formData));
    nextFormData[event.target.name] = event.target.value;
    setFormData(nextFormData);
  };

  const handleCheckChange = event => {
    console.log(formData.collection_name);
    let nextFormData = JSON.parse(JSON.stringify(formData));
    nextFormData[event.target.name] = event.target.checked;
    setFormData(nextFormData);
  };

  return (
    <React.Fragment>
      <Button type="primary" onClick={showModal}>
        Update User
      </Button>
      <Modal
        id="update-user-modal"
        title="Update User"
        open={open}
        confirmLoading={confirmLoading}
        onCancel={handleCancel}
        footer={[
          <Button
            key="submit"
            type="primary"
            loading={confirmLoading}
            onClick={handleOk}
          >
            Update
          </Button>
        ]}
      >
        <Form labelCol={{ span: 8 }} wrapperCol={{ span: 16 }}>
          <Form.Item label="First Name">
            <Input
              name="firstName"
              defaultValue={formData.firstName || ""}
              onChange={handleChange}
            />
          </Form.Item>
          <Form.Item label="Last Name">
            <Input
              name="lastName"
              defaultValue={formData.lastName || ""}
              onChange={handleChange}
            />
          </Form.Item>
          <Form.Item label="Active">
            <Checkbox name="active" value={formData.active || ""} checked={formData.active} onChange={handleCheckChange}>
              
            </Checkbox>
          </Form.Item>
          <Form.Item label="Email">
            <Input
              name="email"
              defaultValue={formData.email || ""}
              onChange={handleChange}
            />

            {successMessage ? (
              <Alert message={successMessage} type="success" showIcon />
            ) : (
              ""
            )}
            {errorMessage ? (
              <Alert message={errorMessage} type="error" showIcon />
            ) : (
              ""
            )}
          </Form.Item>
        </Form>
      </Modal>
    </React.Fragment>
  );
};

return UpdateUserModal;
```

### <br>

### CREATING THE APIs

* Now lets create the APIs
* getuserprofiledata: this API will fetch all the users, created by us.

```
module.exports.getuserprofiledata = () => {
  return (req, res) => {
    const domain = req.subdomains[0] || "dev";

    let query = {
      domain,
    };
    let options = {};

    let cback = function(err, doc) {
      if (doc === null) {
        return res.status(400).send(err);
      } else {
        return res.json(doc);
      }
    };

    ob.db.findWithOptions("user_profile", query, options, cback);
  };
};

```

* createuser: this API will save user details to the database.

```
module.exports.createuser = () => {
  return (req, res) => {
    const domain = req.subdomains[0];
    const record = {
        first_name:req.body.first_name,
        last_name:req.body.last_name,
        email:req.body.email,
        domain
    }
    ob.db.create(
        "user_profile",
        record,
        {},
        (err, document) => {
          if (err) {
            return res.status(400).send(err);
          }
          else {
            return res.send({message:"User successfully added"});
          }
        }
      );
  };
};

```

* updateuserprofiledata: this API will update user details.

```
module.exports.updateuserprofiledata = () => {
  return (req, res) => {
    const domain = req.subdomains[0];
    const updateOptions = {
      propogate: false,
      sync: true,
      domain,
    };
    ob.db.update(
      "user_profile",
      {
        _id: new ob.objectId(req.body._id),
      },
      {
        $set: {
          first_name: req.body.first_name,
          last_name: req.body.last_name,
          email: req.body.email,
          active:req.body.active
        },
      },
      {},
      updateOptions,
      (err, result) => {
        return res.json({ message: "user updated successfully" });
      }
    );
  };
};
```

<br>

<br>
