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.
Copy 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.
Copy
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;
Copy 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
getuserprofiledata: this API will fetch all the users, created by us.
Copy 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.
Copy 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.
Copy 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" });
}
);
};
};