diff --git a/erpnext/public/js/hub/hub_factory.js b/erpnext/public/js/hub/hub_factory.js
index d54787a..c94edf4 100644
--- a/erpnext/public/js/hub/hub_factory.js
+++ b/erpnext/public/js/hub/hub_factory.js
@@ -14,7 +14,7 @@
 
 	make(page_name) {
 		const assets = [
-			'/assets/erpnext/js/hub/hub_listing.js'
+			'/assets/erpnext/js/hub/marketplace.js'
 		];
 
 		frappe.require(assets, () => {
diff --git a/erpnext/public/js/hub/hub_listing.js b/erpnext/public/js/hub/hub_listing.js
index eb55806..368c723 100644
--- a/erpnext/public/js/hub/hub_listing.js
+++ b/erpnext/public/js/hub/hub_listing.js
@@ -1,792 +1,3 @@
-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');
-
-		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>`;
-
-		this.$sidebar.append(`
-			<ul class="list-unstyled hub-sidebar-group">
-				<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}
-			</ul>
-		`);
-
-		this.make_sidebar_categories();
-	}
-
-	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');
-	}
-
-	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) {
-			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(r => {
-				erpnext.hub.hub_item_cache = r.message;
-				this.render(r.message);
-			});
-	}
-
-	get_items() {
-		return frappe.call('erpnext.hub_node.get_list', {
-			doctype: 'Hub Item',
-			filters: {
-				image: ['like', 'http%']
-			}
-		});
-	}
-
-	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();
-
-		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', () => {
-			const form_values = this.field_group.get_values();
-			frappe.call('erpnext.hub_node.doctype.hub_settings.hub_settings.register_seller', form_values)
-				.then(() => {
-					// Reload page and things ... but for now
-					frappe.msgprint('Registered successfully.');
-				});
-		});
-	}
-}
-
-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 = get_rating(item);
-	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 isLocal = item.source_type === "local";
-	const route = !isLocal
-		? `marketplace/item/${item.hub_item_code}`
-		: `Form/Item/${item.item_name}`;
-
-	const card_route = isLocal ? '' : `data-route='${route}'`;
-
-	const show_local_item_button = isLocal
-		? `<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(item) {
-	const review_length = (item.reviews || []).length;
-	return review_length
-		? item.reviews
-			.map(r => r.rating)
-			.reduce((a, b) => a + b, 0) / review_length
-		: 0;
-}
-
-function get_rating_html(item) {
-	const rating = get_rating(item);
-	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.HubListing = class HubListing extends frappe.views.BaseList {
 	setup_defaults() {
