diff --git a/erpnext/public/js/hub/hub_listing.js b/erpnext/public/js/hub/hub_listing.js
index 368c723..7a82a91 100644
--- a/erpnext/public/js/hub/hub_listing.js
+++ b/erpnext/public/js/hub/hub_listing.js
@@ -1,3 +1,848 @@
+frappe.provide('hub');
+frappe.provide('erpnext.hub');
+
+erpnext.hub.Marketplace = class Marketplace {
+	constructor({ parent }) {
+		this.$parent = $(parent);
+		this.page = parent.page;
+
+		frappe.db.get_doc('Hub Settings')
+			.then(doc => {
+				this.hub_settings = doc;
+				this.registered = doc.registered;
+
+				this.setup_header();
+				this.make_sidebar();
+				this.make_body();
+				this.setup_events();
+				this.refresh();
+			});
+	}
+
+	setup_header() {
+		this.page.set_title(__('Marketplace'));
+	}
+
+	setup_events() {
+		this.$parent.on('click', '[data-route]', (e) => {
+			const $target = $(e.currentTarget);
+			const route = $target.data().route;
+			frappe.set_route(route);
+
+			e.stopPropagation();
+		});
+	}
+
+	make_sidebar() {
+		this.$sidebar = this.$parent.find('.layout-side-section').addClass('hidden-xs');
+
+		this.make_sidebar_nav_buttons();
+		this.make_sidebar_categories();
+	}
+
+	make_sidebar_nav_buttons() {
+		let $nav_group = this.$sidebar.find('[data-nav-buttons]');
+		if (!$nav_group.length) {
+			$nav_group = $('<ul class="list-unstyled hub-sidebar-group" data-nav-buttons>').appendTo(this.$sidebar);
+		}
+		$nav_group.empty();
+
+		const user_specific_items_html = this.registered
+			? `<li class="hub-sidebar-item text-muted" data-route="marketplace/profile">
+					${__('Your Profile')}
+				</li>
+				<li class="hub-sidebar-item text-muted" data-route="marketplace/publish">
+					${__('Publish Products')}
+				</li>`
+
+			: `<li class="hub-sidebar-item text-muted" data-route="marketplace/register">
+					${__('Become a seller')}
+				</li>`;
+
+		$nav_group.append(`
+			<li class="hub-sidebar-item" data-route="marketplace/home">
+				${__('Browse')}
+			</li>
+			<li class="hub-sidebar-item" data-route="marketplace/favourites">
+				${__('Favorites')}
+			</li>
+			${user_specific_items_html}
+		`);
+	}
+
+	make_sidebar_categories() {
+		frappe.call('erpnext.hub_node.get_categories')
+			.then(r => {
+				const categories = r.message.map(d => d.value).sort();
+				const sidebar_items = [
+					`<li class="hub-sidebar-item bold is-title">
+						${__('Category')}
+					</li>`,
+					`<li class="hub-sidebar-item active" data-route="marketplace/home">
+						${__('All')}
+					</li>`,
+					...(this.registered
+						? [`<li class="hub-sidebar-item active" data-route="marketplace/my-products">
+							${__('Your Products')}
+						</li>`]
+						: []),
+					...categories.map(category => `
+						<li class="hub-sidebar-item text-muted" data-route="marketplace/category/${category}">
+							${__(category)}
+						</li>
+					`)
+				];
+
+				this.$sidebar.append(`
+					<ul class="list-unstyled">
+						${sidebar_items.join('')}
+					</ul>
+				`);
+
+				this.update_sidebar();
+			});
+	}
+
+	make_body() {
+		this.$body = this.$parent.find('.layout-main-section');
+
+		this.$body.on('seller-registered', () => {
+			this.registered = 1;
+			this.make_sidebar_nav_buttons();
+		});
+	}
+
+	update_sidebar() {
+		const route = frappe.get_route_str();
+		const $sidebar_item = this.$sidebar.find(`[data-route="${route}"]`);
+
+		const $siblings = this.$sidebar.find('[data-route]');
+		$siblings.removeClass('active').addClass('text-muted');
+
+		$sidebar_item.addClass('active').removeClass('text-muted');
+	}
+
+	refresh() {
+		const route = frappe.get_route();
+		this.subpages = this.subpages || {};
+
+		for (let page in this.subpages) {
+			this.subpages[page].hide();
+		}
+
+		if (route[1] === 'home' && !this.subpages.home) {
+			this.subpages.home = new erpnext.hub.Home(this.$body);
+		}
+
+		if (route[1] === 'favourites' && !this.subpages.favourites) {
+			this.subpages.favourites = new erpnext.hub.Favourites(this.$body);
+		}
+
+		if (route[1] === 'category' && route[2] && !this.subpages.category) {
+			this.subpages.category = new erpnext.hub.Category(this.$body);
+		}
+
+		if (route[1] === 'item' && route[2] && !this.subpages.item) {
+			this.subpages.item = new erpnext.hub.Item(this.$body);
+		}
+
+		if (route[1] === 'register' && !this.subpages.register) {
+			// if (this.registered) {
+			// 	frappe.set_route('marketplace', 'home');
+			// 	return;
+			// }
+			this.subpages.register = new erpnext.hub.Register(this.$body);
+		}
+
+		if (route[1] === 'publish' && !this.subpages.publish) {
+			this.subpages.publish = new erpnext.hub.Publish(this.$body);
+		}
+
+
+		if (!Object.keys(this.subpages).includes(route[1])) {
+			frappe.show_not_found();
+			return;
+		}
+
+		this.update_sidebar();
+		frappe.utils.scroll_to(0);
+		this.subpages[route[1]].show();
+	}
+}
+
+class SubPage {
+	constructor(parent) {
+		this.$parent = $(parent);
+		this.make_wrapper();
+	}
+
+	make_wrapper() {
+		const page_name = frappe.get_route()[1];
+		this.$wrapper = $(`<div class="marketplace-page" data-page-name="${page_name}">`).appendTo(this.$parent);
+		this.hide();
+	}
+
+	show() {
+		this.refresh();
+		this.$wrapper.show();
+	}
+
+	hide() {
+		this.$wrapper.hide();
+	}
+}
+
+erpnext.hub.Home = class Home extends SubPage {
+	make_wrapper() {
+		super.make_wrapper();
+		this.make_search_bar();
+	}
+
+	refresh() {
+		this.get_items_and_render();
+	}
+
+	get_items_and_render() {
+		this.$wrapper.find('.hub-card-container').empty();
+		this.get_items()
+			.then(items => {
+				this.render(items);
+			});
+	}
+
+	get_items() {
+		return hub.call('get_data_for_homepage');
+	}
+
+	make_search_bar() {
+		const $search = $(`
+			<div class="hub-search-container">
+				<input type="text" class="form-control" placeholder="Search for anything">
+			</div>`
+		);
+		this.$wrapper.append($search);
+		const $search_input = $search.find('input');
+
+		$search_input.on('keydown', frappe.utils.debounce((e) => {
+			if (e.which === frappe.ui.keyCode.ENTER) {
+				this.search_value = $search_input.val();
+				this.get_items_and_render();
+			}
+		}, 300));
+	}
+
+	render(items) {
+		const html = get_item_card_container_html(items, __('Recently Published'));
+		this.$wrapper.append(html)
+	}
+}
+
+erpnext.hub.Favourites = class Favourites extends SubPage {
+	refresh() {
+		this.get_favourites()
+			.then(r => {
+				this.render(r.message);
+			});
+	}
+
+	get_favourites() {
+		return frappe.call('erpnext.hub_node.get_item_favourites');
+	}
+
+	render(items) {
+		this.$wrapper.find('.hub-card-container').empty();
+		const html = get_item_card_container_html(items, __('Favourites'));
+		this.$wrapper.append(html)
+	}
+}
+
+erpnext.hub.Category = class Category extends SubPage {
+	refresh() {
+		this.category = frappe.get_route()[2];
+		this.get_items_for_category(this.category)
+			.then(r => {
+				this.render(r.message);
+			});
+	}
+
+	get_items_for_category(category) {
+		this.$wrapper.find('.hub-card-container').empty();
+		return frappe.call('erpnext.hub_node.get_list', {
+			doctype: 'Hub Item',
+			filters: {
+				hub_category: category
+			}
+		});
+	}
+
+	render(items) {
+		const html = get_item_card_container_html(items, __(this.category));
+		this.$wrapper.append(html)
+	}
+}
+
+erpnext.hub.Item = class Item extends SubPage {
+	refresh() {
+		this.hub_item_code = frappe.get_route()[2];
+
+		this.get_item(this.hub_item_code)
+			.then(item => {
+				this.render(item);
+			});
+	}
+
+	get_item(hub_item_code) {
+		return new Promise(resolve => {
+			const item = (erpnext.hub.hub_item_cache || []).find(item => item.name === hub_item_code)
+
+			if (item) {
+				resolve(item);
+			} else {
+				frappe.call('erpnext.hub_node.get_list', {
+					doctype: 'Hub Item',
+					filters: {
+						name: hub_item_code
+					}
+				})
+				.then(r => {
+					resolve(r.message[0]);
+				});
+			}
+		});
+	}
+
+	render(item) {
+		const title = item.item_name || item.name;
+		const company = item.company_name;
+
+		const who = __('Posted By {0}', [company]);
+		const when = comment_when(item.creation);
+
+		const city = item.seller_city ? item.seller_city + ', ' : '';
+		const country = item.country ? item.country : '';
+		const where = `${city}${country}`;
+
+		const dot_spacer = '<span aria-hidden="true"> · </span>';
+
+		const description = item.description || '';
+
+		const rating_html = get_rating_html(item);
+		const rating_count = item.reviews.length > 0 ? `(${item.reviews.length} reviews)` : '';
+
+		const html = `
+			<div class="hub-item-container">
+				<div class="row visible-xs">
+					<div class="col-xs-12 margin-bottom">
+						<button class="btn btn-xs btn-default" data-route="marketplace/home">Back to home</button>
+					</div>
+				</div>
+				<div class="row">
+					<div class="col-md-3">
+						<div class="hub-item-image">
+							<img src="${item.image}">
+						</div>
+					</div>
+					<div class="col-md-6">
+						<h2>${title}</h2>
+						<div class="text-muted">
+							<p>${where}${dot_spacer}${when}</p>
+							<p>${rating_html}${rating_count}</p>
+						</div>
+						<hr>
+						<div class="hub-item-description">
+						${description ?
+							`<b>${__('Description')}</b>
+							<p>${description}</p>
+							` : __('No description')
+						}
+						</div>
+					</div>
+				</div>
+				<div class="row hub-item-seller">
+					<div class="col-md-12 margin-top margin-bottom">
+						<b class="text-muted">Seller Information</b>
+					</div>
+					<div class="col-md-1">
+						<img src="https://picsum.photos/200">
+					</div>
+					<div class="col-md-6">
+						<a href="#marketplace/seller/${company}" class="bold">${company}</a>
+						<p class="text-muted">
+							Contact Seller
+						</p>
+					</div>
+				</div>
+				<!-- review area -->
+				<div class="row hub-item-review-container">
+					<div class="col-md-12 form-footer">
+						<div class="form-comments">
+							<div class="timeline">
+								<div class="timeline-head"></div>
+								<div class="timeline-items"></div>
+							</div>
+						</div>
+						<div class="pull-right scroll-to-top">
+							<a onclick="frappe.utils.scroll_to(0)"><i class="fa fa-chevron-up text-muted"></i></a>
+						</div>
+					</div>
+				</div>
+			</div>
+		`;
+
+		this.$wrapper.html(html);
+
+		this.make_review_area();
+		this.render_reviews(item);
+	}
+
+	make_review_area() {
+		this.comment_area = new frappe.ui.ReviewArea({
+			parent: this.$wrapper.find('.timeline-head').empty(),
+			mentions: [],
+			on_submit: (val) => {
+				val.user = frappe.session.user;
+				val.username = frappe.session.user_fullname;
+
+				frappe.call({
+					method: 'erpnext.hub_node.send_review',
+					args: {
+						hub_item_code: this.hub_item_code,
+						review: val
+					},
+					callback: (r) => {
+						console.log(r);
+						this.render_reviews(r.message);
+						this.comment_area.reset();
+					},
+					freeze: true
+				});
+			}
+		});
+	}
+
+	render_reviews(item) {
+		this.$wrapper.find('.timeline-items').empty();
+		item.reviews.forEach(review => this.render_review(review, item));
+	}
+
+	render_review(review, item) {
+		let username = review.username || review.user || __("Anonymous");
+
+		let image_html = review.user_image
+			? `<div class="avatar-frame" style="background-image: url(${review.user_image})"></div>`
+			: `<div class="standard-image" style="background-color: #fafbfc">${frappe.get_abbr(username)}</div>`
+
+		let edit_html = review.own
+			? `<div class="pull-right hidden-xs close-btn-container">
+				<span class="small text-muted">
+					${'data.delete'}
+				</span>
+			</div>
+			<div class="pull-right edit-btn-container">
+				<span class="small text-muted">
+					${'data.edit'}
+				</span>
+			</div>`
+			: '';
+
+		let rating_html = get_rating_html(item);
+
+		const $timeline_items = this.$wrapper.find('.timeline-items');
+
+		$(this.get_timeline_item(review, image_html, edit_html, rating_html))
+			.appendTo($timeline_items);
+	}
+
+	get_timeline_item(data, image_html, edit_html, rating_html) {
+		return `<div class="media timeline-item user-content" data-doctype="${''}" data-name="${''}">
+			<span class="pull-left avatar avatar-medium hidden-xs" style="margin-top: 1px">
+				${image_html}
+			</span>
+			<div class="pull-left media-body">
+				<div class="media-content-wrapper">
+					<div class="action-btns">${edit_html}</div>
+
+					<div class="comment-header clearfix">
+						<span class="pull-left avatar avatar-small visible-xs">
+							${image_html}
+						</span>
+
+						<div class="asset-details">
+							<span class="author-wrap">
+								<i class="octicon octicon-quote hidden-xs fa-fw"></i>
+								<span>${data.username}</span>
+							</span>
+							<a class="text-muted">
+								<span class="text-muted hidden-xs">&ndash;</span>
+								<span class="hidden-xs">${comment_when(data.modified)}</span>
+							</a>
+						</div>
+					</div>
+					<div class="reply timeline-content-show">
+						<div class="timeline-item-content">
+							<p class="text-muted">
+								${rating_html}
+							</p>
+							<h6 class="bold">${data.subject}</h6>
+							<p class="text-muted">
+								${data.content}
+							</p>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>`;
+	}
+}
+erpnext.hub.Register = class Register extends SubPage {
+	make_wrapper() {
+		super.make_wrapper();
+		this.$register_container = $(`<div class="row register-container">`)
+			.appendTo(this.$wrapper);
+		this.$form_container = $('<div class="col-md-8 col-md-offset-1 form-container">')
+			.appendTo(this.$wrapper);
+	}
+
+	refresh() {
+		this.$register_container.empty();
+		this.$form_container.empty();
+		this.render();
+	}
+
+	render() {
+		this.make_field_group();
+	}
+
+	make_field_group() {
+		const fields = [
+			{
+				fieldtype: 'Link',
+				fieldname: 'company',
+				label: __('Company'),
+				options: 'Company',
+				onchange: () => {
+					const value = this.field_group.get_value('company');
+
+					if (value) {
+						frappe.db.get_doc('Company', value)
+							.then(company => {
+								this.field_group.set_values({
+									country: company.country,
+									company_email: company.email,
+									currency: company.default_currency
+								});
+							});
+					}
+				}
+			},
+			{
+				fieldname: 'company_email',
+				label: __('Email'),
+				fieldtype: 'Data'
+			},
+			{
+				fieldname: 'country',
+				label: __('Country'),
+				fieldtype: 'Read Only'
+			},
+			{
+				fieldname: 'currency',
+				label: __('Currency'),
+				fieldtype: 'Read Only'
+			},
+			{
+				fieldtype: 'Text',
+				label: __('About your Company'),
+				fieldname: 'company_description'
+			}
+		];
+
+		this.field_group = new frappe.ui.FieldGroup({
+			parent: this.$form_container,
+			fields
+		});
+
+		this.field_group.make();
+
+		const default_company = frappe.defaults.get_default('company');
+		this.field_group.set_value('company', default_company);
+
+		this.$form_container.find('.form-column').append(`
+			<div class="text-right">
+				<button type="submit" class="btn btn-primary btn-register btn-sm">${__('Submit')}</button>
+			</div>
+		`);
+
+		this.$form_container.find('.form-message').removeClass('hidden small').addClass('h4').text(__('Become a Seller'))
+
+		this.$form_container.on('click', '.btn-register', (e) => {
+			const form_values = this.field_group.get_values();
+
+			let values_filled = true;
+			const mandatory_fields = ['company', 'company_email', 'company_description'];
+			mandatory_fields.forEach(field => {
+				const value = form_values[field];
+				if (!value) {
+					this.field_group.set_df_property(field, 'reqd', 1);
+					values_filled = false;
+				}
+			});
+			if (!values_filled) return;
+
+			frappe.call({
+				method: 'erpnext.hub_node.doctype.hub_settings.hub_settings.register_seller',
+				args: form_values,
+				btn: $(e.currentTarget)
+			}).then(() => {
+				frappe.set_route('marketplace', 'publish');
+
+				// custom jquery event
+				this.$wrapper.trigger('seller-registered');
+			});
+		});
+	}
+}
+
+erpnext.hub.Publish = class Publish extends SubPage {
+	make_wrapper() {
+		super.make_wrapper();
+		const title_html = `<b>${__('Select Products to Publish')}</b>`;
+		const info = `<p class="text-muted">${__("Status decided by the 'Publish in Hub' field in Item.")}</p>`;
+		const subtitle_html = `
+		<p class="text-muted">
+			${__(`Only products with an image, description and category can be published.
+			Please update them if an item in your inventory does not appear.`)}
+		</p>`;
+		const publish_button_html = `<button class="btn btn-primary btn-sm publish-items">
+			<i class="visible-xs octicon octicon-check"></i>
+			<span class="hidden-xs">Publish</span>
+		</button>`;
+
+		const select_all_button = `<button class="btn btn-secondary btn-default btn-xs margin-right select-all">Select All</button>`;
+		const deselect_all_button = `<button class="btn btn-secondary btn-default btn-xs deselect-all">Deselect All</button>`;
+
+		const search_html = `<div class="hub-search-container">
+			<input type="text" class="form-control" placeholder="Search Items">
+		</div>`;
+
+		const subpage_header = $(`
+			<div class='subpage-title flex'>
+				<div>
+					${title_html}
+					${subtitle_html}
+				</div>
+				${publish_button_html}
+			</div>
+
+			${search_html}
+
+			${select_all_button}
+			${deselect_all_button}
+		`);
+
+		this.$wrapper.append(subpage_header);
+
+		this.setup_events();
+	}
+
+	setup_events() {
+		this.$wrapper.find('.select-all').on('click', () => {
+			this.$wrapper.find('.hub-card').addClass('active');
+		});
+
+		this.$wrapper.find('.deselect-all').on('click', () => {
+			this.$wrapper.find('.hub-card').removeClass('active');
+		});
+
+		this.$wrapper.find('.publish-items').on('click', () => {
+			this.publish_selected_items()
+				.then(r => {
+					frappe.msgprint('check');
+				});
+		});
+
+		const $search_input = this.$wrapper.find('.hub-search-container input');
+		this.search_value = '';
+
+		$search_input.on('keydown', frappe.utils.debounce((e) => {
+			if (e.which === frappe.ui.keyCode.ENTER) {
+				this.search_value = $search_input.val();
+				this.get_items_and_render();
+			}
+		}, 300));
+	}
+
+	get_items_and_render() {
+		this.$wrapper.find('.hub-card-container').empty();
+		this.get_valid_items()
+			.then(r => {
+				this.render(r.message);
+			});
+	}
+
+	refresh() {
+		this.get_items_and_render();
+	}
+
+	render(items) {
+		const items_container = $(get_item_card_container_html(items));
+		items_container.addClass('static').on('click', '.hub-card', (e) => {
+			const $target = $(e.currentTarget);
+			$target.toggleClass('active');
+		});
+
+		this.$wrapper.append(items_container);
+	}
+
+	get_valid_items() {
+		return frappe.call(
+			'erpnext.hub_node.get_valid_items',
+			{
+				search_value: this.search_value
+			}
+		);
+	}
+
+	publish_selected_items() {
+		const items_to_publish = [];
+		const items_to_unpublish = [];
+		this.$wrapper.find('.hub-card').map(function () {
+			const active = $(this).hasClass('active');
+
+			if(active) {
+				items_to_publish.push($(this).attr("data-id"));
+			} else {
+				items_to_unpublish.push($(this).attr("data-id"));
+			}
+		});
+
+		return frappe.call(
+			'erpnext.hub_node.publish_selected_items',
+			{
+				items_to_publish: items_to_publish,
+				items_to_unpublish: items_to_unpublish
+			}
+		);
+	}
+}
+
+function get_item_card_container_html(items, title='') {
+	const items_html = (items || []).map(item => get_item_card_html(item)).join('');
+
+	const html = `<div class="row hub-card-container">
+		<div class="col-sm-12 margin-bottom">
+			<b>${title}</b>
+		</div>
+		${items_html}
+	</div>`;
+
+	return html;
+}
+
+function get_item_card_html(item) {
+	const item_name = item.item_name || item.name;
+	const title = strip_html(item_name);
+	const img_url = item.image;
+
+	const company_name = item.company_name;
+
+	const active = item.publish_in_hub;
+
+	const id = item.hub_item_code || item.item_code;
+
+	// Subtitle
+	let subtitle = [comment_when(item.creation)];
+	const rating = item.average_rating;
+	if (rating > 0) {
+		subtitle.push(rating + `<i class='fa fa-fw fa-star-o'></i>`)
+	}
+	subtitle.push(company_name);
+
+	let dot_spacer = '<span aria-hidden="true"> · </span>';
+	subtitle = subtitle.join(dot_spacer);
+
+	// Decide item link
+	const is_local = item.source_type === "local";
+	const route = !is_local
+		? `marketplace/item/${item.hub_item_code}`
+		: `Form/Item/${item.item_name}`;
+
+	const card_route = is_local ? '' : `data-route='${route}'`;
+
+	const show_local_item_button = is_local
+		? `<div class="overlay button-overlay" data-route='${route}' onclick="event.preventDefault();">
+				<button class="btn btn-default zoom-view">
+					<i class="octicon octicon-eye"></i>
+				</button>
+			</div>`
+		: '';
+
+	const item_html = `
+		<div class="col-md-3 col-sm-4 col-xs-6">
+			<div class="hub-card ${active ? 'active' : ''}" ${card_route} data-id="${id}">
+				<div class="hub-card-header">
+					<div class="title">
+						<div class="hub-card-title ellipsis bold">${title}</div>
+						<div class="hub-card-subtitle ellipsis text-muted">${subtitle}</div>
+					</div>
+					<i class="octicon octicon-check text-success"></i>
+				</div>
+				<div class="hub-card-body">
+					<img class="hub-card-image ${item.image ? '' : 'no-image'}" src="${img_url}" />
+					<div class="overlay hub-card-overlay"></div>
+					${show_local_item_button}
+				</div>
+			</div>
+		</div>
+	`;
+
+	return item_html;
+}
+
+function get_rating_html(item) {
+	const rating = item.average_rating;
+	let rating_html = ``;
+	for (var i = 0; i < 5; i++) {
+		let star_class = 'fa-star';
+		if (i >= rating) star_class = 'fa-star-o';
+		rating_html += `<i class='fa fa-fw ${star_class} star-icon' data-index=${i}></i>`;
+	}
+	return rating_html;
+}
+
+erpnext.hub.cache = {};
+hub.call = function call_hub_method(method, args={}) {
+	return new Promise((resolve, reject) => {
+
+		// cache
+		const key = method + JSON.stringify(args);
+		if (erpnext.hub.cache[key]) {
+			resolve(erpnext.hub.cache[key]);
+		}
+
+		// cache invalidation after 5 minutes
+		setTimeout(() => {
+			delete erpnext.hub.cache[key];
+		}, 5 * 60 * 1000);
+
+		frappe.call({
+			method: 'erpnext.hub_node.call_hub_method',
+			args: {
+				method,
+				params: args
+			}
+		})
+		.then(r => {
+			if (r.message) {
+				erpnext.hub.cache[key] = r.message;
+				resolve(r.message)
+			}
+			reject(r)
+		})
+		.fail(reject)
+	});
+}
+
 
 erpnext.hub.HubListing = class HubListing extends frappe.views.BaseList {
 	setup_defaults() {
