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

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

  • Login to "<your-space>.obto.co"

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

  • Click on Create New Button

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

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

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.

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

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

  • 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

  • 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.

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

  • 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.

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

BUILDING THE FRONTEND

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

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

  • 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.

  • 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;

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" });
      }
    );
  };
};

Last updated