Add BuyingMessages page
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index 994aebc..953efe4 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -10,6 +10,7 @@
 import './pages/publish';
 import './pages/published_products';
 import './pages/messages';
+import './pages/buying_messages';
 import './pages/not_found';
 
 // components
@@ -140,7 +141,7 @@
 
 	make_body() {
 		this.$body = this.$parent.find('.layout-main-section');
-		this.$body.on('seller-registered', () => {
+		erpnext.hub.on('seller-registered', () => {
 			this.registered = 1;
 			this.make_sidebar_nav_buttons();
 		});
@@ -213,6 +214,10 @@
 			this.subpages['messages'] = new erpnext.hub.Messages(this.$body);
 		}
 
+		if (route[1] === 'buy' && !this.subpages['buy']) {
+			this.subpages['buy'] = new erpnext.hub.BuyingMessages(this.$body);
+		}
+
 		// dont allow unregistered users to access registered routes
 		const registered_routes = ['favourites', 'profile', 'publish', 'my-products', 'messages'];
 		if (!hub.settings.registered && registered_routes.includes(route[1])) {
@@ -253,8 +258,7 @@
 			this.register_dialog.hide();
 			frappe.set_route('marketplace', 'publish');
 
-		    // custom jquery event
-		    this.$body.trigger('seller-registered');
+		    erpnext.hub.trigger('seller-registered');
 		});
 	}
 }
diff --git a/erpnext/public/js/hub/pages/buying_messages.js b/erpnext/public/js/hub/pages/buying_messages.js
new file mode 100644
index 0000000..c307b8d
--- /dev/null
+++ b/erpnext/public/js/hub/pages/buying_messages.js
@@ -0,0 +1,96 @@
+import SubPage from './subpage';
+
+erpnext.hub.BuyingMessages = class BuyingMessages extends SubPage {
+	make_wrapper() {
+		super.make_wrapper();
+		this.add_back_link(__('Back to Messages'), 'marketplace/messages');
+		this.$message_container = this.add_section({ title: 'Buy' });
+	}
+
+	refresh() {
+		const item_code = frappe.get_route()[2] || null;
+		if (!item_code) {
+			frappe.set_route('marketplace/messages');
+			return;
+		}
+
+		this.get_item_details(item_code)
+			.then(item_details => {
+				this.item_details = item_details;
+
+				// make chat area
+				this.$message_container.find('.hub-section-header h4').text(this.item_details.item_name);
+				this.$message_container.find('.hub-section-body').html(`
+					<div class="col-md-7 message-container">
+						<div class="message-list"></div>
+						<div class="message-input"></div>
+					</div>
+				`)
+				this.make_message_input();
+
+				// fetch messages
+				this.get_messages(item_details)
+					.then(messages => {
+						const $message_list = this.$message_container.find('.message-list');
+						const html = messages.map(get_message_html).join('');
+						$message_list.html(html);
+						frappe.dom.scroll_to_bottom($message_list);
+					});
+			});
+
+	}
+
+	get_messages(item_details) {
+		 return hub.call('get_messages', {
+			against_seller: item_details.hub_seller,
+			against_item: item_details.hub_item_code
+		});
+	}
+
+	get_item_details(hub_item_code) {
+		return hub.call('get_item_details', { hub_item_code })
+	}
+
+	make_message_input() {
+		this.message_input = new frappe.ui.CommentArea({
+			parent: this.$message_container.find('.message-input'),
+			on_submit: (message) => {
+				this.message_input.reset();
+
+				// append message html
+				const $message_list = this.$message_container.find('.message-list');
+				const message_html = get_message_html({
+					sender: hub.settings.company_email,
+					content: message
+				});
+				$message_list.append(message_html);
+				frappe.dom.scroll_to_bottom($message_list);
+
+				// send message
+				hub.call('send_message', {
+					from_seller: hub.settings.company_email,
+					to_seller: this.item_details.hub_seller,
+					hub_item: this.item_details.hub_item_code,
+					message
+				});
+			},
+			no_wrapper: true
+		});
+	}
+}
+
+function get_message_html(message) {
+	return `
+		<div class="level margin-bottom">
+			<div class="level-left ellipsis" style="width: 80%;">
+				${frappe.avatar(message.sender)}
+				<div style="white-space: normal;">
+					${message.content}
+				</div>
+			</div>
+			<div class="level-right text-muted">
+				${comment_when(message.creation, true)}
+			</div>
+		</div>
+	`;
+}
\ No newline at end of file
diff --git a/erpnext/public/js/hub/pages/item.js b/erpnext/public/js/hub/pages/item.js
index 71a4b0f..421d7ef 100644
--- a/erpnext/public/js/hub/pages/item.js
+++ b/erpnext/public/js/hub/pages/item.js
@@ -26,7 +26,6 @@
 
 	get_item(hub_item_code) {
 		return hub.call('get_item_details', {
-			hub_seller: hub.settings.company_email,
 			hub_item_code
 		});
 	}
diff --git a/erpnext/public/js/hub/pages/messages.js b/erpnext/public/js/hub/pages/messages.js
index a1f734f..f09baf2 100644
--- a/erpnext/public/js/hub/pages/messages.js
+++ b/erpnext/public/js/hub/pages/messages.js
@@ -16,13 +16,6 @@
 		res.then(([buying_items, selling_items]) => {
 			this.empty();
 
-			if (buying_items.length) {
-				buying_items.map(item => {
-					item.route = `marketplace/buy/${item.hub_item_code}`
-				})
-				this.render(buying_items, __('Buying'));
-			}
-
 			if (selling_items.length) {
 				// selling_items.map(item => {
 				// 	item.route = `marketplace/sell/${item.hub_item_code}/${}`
@@ -30,6 +23,13 @@
 				this.render(selling_items, __('Selling'));
 			}
 
+			if (buying_items.length) {
+				buying_items.map(item => {
+					item.route = `marketplace/buy/${item.hub_item_code}`
+				})
+				this.render(buying_items, __('Buying'));
+			}
+
 			if (!buying_items.length && !selling_items.length) {
 				this.render_empty_state();
 			}
diff --git a/erpnext/public/js/hub/pages/register.js b/erpnext/public/js/hub/pages/register.js
index 9b07f29..36b0842 100644
--- a/erpnext/public/js/hub/pages/register.js
+++ b/erpnext/public/js/hub/pages/register.js
@@ -107,8 +107,7 @@
 		}).then(() => {
 			frappe.set_route('marketplace', 'publish');
 
-			// custom jquery event
-			this.$wrapper.trigger('seller-registered');
+			erpnext.hub.trigger('seller-registered');
 		});
 	}
 }
diff --git a/erpnext/public/js/hub/pages/subpage.js b/erpnext/public/js/hub/pages/subpage.js
index fd05838..c833446 100644
--- a/erpnext/public/js/hub/pages/subpage.js
+++ b/erpnext/public/js/hub/pages/subpage.js
@@ -32,6 +32,43 @@
 		this.hide();
 	}
 
+	add_section({ title, body } = {}) {
+		this._sections = this._sections || {};
+
+		if (title && this._sections[title]) {
+			return this._sections[title];
+		}
+
+		const $section = $(`
+			<div class="row hub-section">
+				<div class="col-sm-12 hub-section-header padding-bottom flex">
+					<h4>${title || ''}</h4>
+				</div>
+				<div class="col-sm-12 hub-section-body">
+					${body || ''}
+				</div>
+			</div>
+		`);
+
+		if (title) {
+			this._sections[title] = $section;
+		}
+
+		this.$wrapper.append($section);
+		return $section;
+	}
+
+	add_back_link(title, route) {
+		const $section = this.add_section();
+		this.$wrapper.prepend($section);
+
+		$section.addClass('margin-bottom');
+		$section.find('.hub-section-header').remove()
+		$section.find('.hub-section-body').html(`
+			<button class="btn btn-xs btn-default" data-route="${route}">${title}</button>
+		`);
+	}
+
 	empty() {
 		this.$wrapper.empty();
 	}
diff --git a/erpnext/public/less/hub.less b/erpnext/public/less/hub.less
index 2bfb109..88076c0 100644
--- a/erpnext/public/less/hub.less
+++ b/erpnext/public/less/hub.less
@@ -290,13 +290,18 @@
 		}
 	}
 
-	.message-list {
-		overflow: scroll;
+	.message-container {
+		display: flex;
+		flex-direction: column;
+		border: 1px solid @border-color;
+		border-radius: 3px;
+		height: calc(100vh - 300px);
+		justify-content: space-between;
 	}
 
-	.message-area {
-		border-radius: 4px;
-		justify-content: space-between;
-		height: calc(100vh - 220px);
+	.message-list {
+		padding-top: 15px;
+		padding-bottom: 15px;
+		overflow: scroll;
 	}
 }