Merge branch 'hub-redesign' of https://github.com/frappe/erpnext into hub-redesign
diff --git a/erpnext/public/js/hub/App.vue b/erpnext/public/js/hub/App.vue
deleted file mode 100644
index 37ec4f3..0000000
--- a/erpnext/public/js/hub/App.vue
+++ /dev/null
@@ -1,34 +0,0 @@
-<template>
-	<div class="app">
-		<hello></hello>
-	</div>
-</template>
-
-<script>
-import ItemCardsContainer from './components/ItemCardsContainer.vue';
-export default {
-	name: 'app',
-	components: {
-		ItemCardsContainer
-	}
-}
-</script>
-
-<style>
-body {
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	height: 100%;
-	margin: 0;
-}
-.app {
-	color: #444;
-	margin-top: 100px;
-	max-width: 600px;
-	font-family: Helvetica, sans-serif;
-	text-align: center;
-	display: flex;
-	align-items: center;
-}
-</style>
diff --git a/erpnext/public/js/hub/components/DetailView.vue b/erpnext/public/js/hub/components/DetailView.vue
new file mode 100644
index 0000000..b86468b
--- /dev/null
+++ b/erpnext/public/js/hub/components/DetailView.vue
@@ -0,0 +1,75 @@
+<template>
+	<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_text }}</button>
+			</div>
+		</div>
+
+		<div v-if="show_skeleton" class="row margin-bottom">
+			<div class="col-md-3">
+				<div class="hub-item-skeleton-image"></div>
+			</div>
+			<div class="col-md-6">
+				<h2 class="hub-skeleton" style="width: 75%;">Name</h2>
+				<div class="text-muted">
+					<p class="hub-skeleton" style="width: 35%;">Details</p>
+					<p class="hub-skeleton" style="width: 50%;">Ratings</p>
+				</div>
+				<hr>
+				<div class="hub-item-description">
+					<p class="hub-skeleton">Desc</p>
+					<p class="hub-skeleton" style="width: 85%;">Desc</p>
+				</div>
+			</div>
+		</div>
+
+		<div v-else>
+			<div class="row margin-bottom">
+				<div class="col-md-3">
+					<div class="hub-item-image">
+						<img :src="image">
+					</div>
+				</div>
+				<div class="col-md-6">
+					<h2>{{ title }}</h2>
+					<div class="text-muted">
+						<p v-for="subtitle in subtitles"
+							:key="subtitle"
+							v-html="subtitle"
+						>
+						</p>
+					</div>
+
+				</div>
+			</div>
+			<div v-for="section in sections" class="row hub-item-description margin-bottom"
+				:key="section.title"
+			>
+				<h6 class="col-md-12 margin-top">
+					<b class="text-muted">{{ section.title }}</b>
+				</h6>
+				<p class="col-md-12" v-html="section.content">
+				</p>
+			</div>
+		</div>
+
+	</div>
+</template>
+
+<script>
+
+export default {
+	name: 'detail-view',
+	props: ['title', 'subtitles', 'image', 'sections', 'show_skeleton'],
+	data() {
+		return {
+			back_to_home_text: __('Back to Home')
+		}
+	},
+	computed: {}
+}
+</script>
+
+<style lang="less" scoped>
+</style>
diff --git a/erpnext/public/js/hub/components/EmptyState.vue b/erpnext/public/js/hub/components/EmptyState.vue
index c0ad971..3d35efc 100644
--- a/erpnext/public/js/hub/components/EmptyState.vue
+++ b/erpnext/public/js/hub/components/EmptyState.vue
@@ -4,6 +4,13 @@
 		:style="{ height: height + 'px' }"
 	>
 		<p class="text-muted">{{ message }}</p>
+		<p v-if="action">
+			<button class="btn btn-default btn-xs"
+				@click="action.on_click"
+			>
+				{{ action.label }}
+			</button>
+		</p>
 	</div>
 </template>
 
@@ -15,7 +22,7 @@
 		message: String,
 		bordered: Boolean,
 		height: Number,
-		// action: Function
+		action: Object
 	}
 }
 </script>
diff --git a/erpnext/public/js/hub/components/TimelineItem.vue b/erpnext/public/js/hub/components/TimelineItem.vue
new file mode 100644
index 0000000..97b5a0d
--- /dev/null
+++ b/erpnext/public/js/hub/components/TimelineItem.vue
@@ -0,0 +1,9 @@
+/* Saving this for later */
+<template>
+	<div class="media timeline-item  notification-content">
+		<div class="small">
+			<i class="octicon octicon-bookmark fa-fw"></i>
+			<span title="Administrator"><b>4 weeks ago</b> Published 1 product to Marketplace</span>
+		</div>
+	</div>
+</template>
diff --git a/erpnext/public/js/hub/components/detail_view.js b/erpnext/public/js/hub/components/detail_view.js
index f161e45..fca6a56 100644
--- a/erpnext/public/js/hub/components/detail_view.js
+++ b/erpnext/public/js/hub/components/detail_view.js
@@ -132,42 +132,6 @@
 	return html;
 }
 
-function get_profile_html(profile) {
-	const p = profile;
-	const profile_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="${p.logo}">
-				</div>
-			</div>
-			<div class="col-md-6">
-				<h2>${p.company}</h2>
-				<div class="text-muted">
-					<p>${p.country}</p>
-					<p>${p.site_name}</p>
-					<p>${__(`Joined ${comment_when(p.creation)}`)}</p>
-				</div>
-				<hr>
-				<div class="hub-item-description">
-				${'description'
-					? `<p>${p.company_description}</p>`
-					: `<p>__('No description')</p`
-				}
-				</div>
-			</div>
-		</div>
-
-	</div>`;
-
-	return profile_html;
-}
-
 export {
 	get_detail_view_html,
 	get_profile_html
diff --git a/erpnext/public/js/hub/components/empty_state.js b/erpnext/public/js/hub/components/empty_state.js
deleted file mode 100644
index 0e1ad46..0000000
--- a/erpnext/public/js/hub/components/empty_state.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function get_empty_state(message, action) {
-	return `<div class="empty-state flex align-center flex-column justify-center">
-		<p class="text-muted">${message}</p>
-		${action ? `<p>${action}</p>`: ''}
-	</div>`;
-}
-
-export {
-    get_empty_state
-}
diff --git a/erpnext/public/js/hub/components/item_card.js b/erpnext/public/js/hub/components/item_card.js
index 7cb2281..fdf2690 100644
--- a/erpnext/public/js/hub/components/item_card.js
+++ b/erpnext/public/js/hub/components/item_card.js
@@ -1,108 +1,3 @@
-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;
-
-	// 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);
-
-	// route
-	if (!item.route) {
-		item.route = `marketplace/item/${item.hub_item_code}`
-	}
-
-	const item_html = `
-		<div class="col-md-3 col-sm-4 col-xs-6 hub-card-container">
-			<div class="hub-card"
-				data-hub-item-code="${item.hub_item_code}"
-				data-route="${item.route}">
-
-				<div class="hub-card-header level">
-					<div class="ellipsis">
-						<div class="hub-card-title ellipsis bold">${title}</div>
-						<div class="hub-card-subtitle ellipsis text-muted">${subtitle}</div>
-					</div>
-					<i class="octicon octicon-x text-extra-muted"
-						data-hub-item-code="${item.hub_item_code}">
-					</i>
-				</div>
-				<div class="hub-card-body">
-					<img class="hub-card-image" src="${img_url}" />
-					<div class="overlay hub-card-overlay"></div>
-				</div>
-			</div>
-		</div>
-	`;
-
-	return item_html;
-}
-
-function get_local_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;
-
-	const is_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>`)
-	}
-
-	if (company_name) {
-		subtitle.push(company_name);
-	}
-
-	let dot_spacer = '<span aria-hidden="true"> · </span>';
-	subtitle = subtitle.join(dot_spacer);
-
-	const edit_item_button = `<div class="hub-card-overlay-button" data-route="Form/Item/${item.item_name}">
-		<button class="btn btn-default zoom-view">
-			<i class="octicon octicon-pencil text-muted"></i>
-		</button>
-	</div>`;
-
-	const item_html = `
-		<div class="col-md-3 col-sm-4 col-xs-6 hub-card-container">
-			<div class="hub-card is-local ${is_active ? 'active' : ''}" data-id="${id}">
-				<div class="hub-card-header flex">
-					<div class="ellipsis">
-						<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" src="${img_url}" />
-					<div class="hub-card-overlay">
-						<div class="hub-card-overlay-body">
-							${edit_item_button}
-						</div>
-					</div>
-				</div>
-			</div>
-		</div>
-	`;
-
-	return item_html;
-}
-
 function get_buying_item_message_card_html(item) {
 	const item_name = item.item_name || item.name;
 	const title = strip_html(item_name);
diff --git a/erpnext/public/js/hub/components/items_container.js b/erpnext/public/js/hub/components/items_container.js
deleted file mode 100644
index 61b8af6..0000000
--- a/erpnext/public/js/hub/components/items_container.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { get_item_card_html } from './item_card';
-
-function get_item_card_container_html(items, title='', get_item_html = get_item_card_html, action='') {
-	const items_html = (items || []).map(item => get_item_html(item)).join('');
-	const title_html = title
-		? `<div class="hub-items-header flex">
-				<h4>${title}</h4>
-				${action}
-			</div>`
-		: '';
-
-	const html = `<div class="row hub-items-container">
-		${title_html}
-		${items_html}
-	</div>`;
-
-	return html;
-}
-
-export {
-	get_item_card_container_html
-}
diff --git a/erpnext/public/js/hub/components/profile_dialog.js b/erpnext/public/js/hub/components/profile_dialog.js
index 800e8c6..e76abfa 100644
--- a/erpnext/public/js/hub/components/profile_dialog.js
+++ b/erpnext/public/js/hub/components/profile_dialog.js
@@ -1,75 +1,75 @@
 const ProfileDialog = (title = __('Edit Profile'), action={}, initial_values={}) => {
-    const fields = [
-        {
-            fieldtype: 'Link',
-            fieldname: 'company',
-            label: __('Company'),
-            options: 'Company',
-            onchange: () => {
-                const value = dialog.get_value('company');
+	const fields = [
+		{
+			fieldtype: 'Link',
+			fieldname: 'company',
+			label: __('Company'),
+			options: 'Company',
+			onchange: () => {
+				const value = dialog.get_value('company');
 
-                if (value) {
-                    frappe.db.get_doc('Company', value)
-                        .then(company => {
-                            dialog.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'
-        }
-    ];
+				if (value) {
+					frappe.db.get_doc('Company', value)
+						.then(company => {
+							dialog.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'
+		}
+	];
 
-    let dialog = new frappe.ui.Dialog({
-        title: title,
-        fields: fields,
-        primary_action_label: action.label || __('Update'),
-        primary_action: () => {
-            const form_values = dialog.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) {
-                    dialog.set_df_property(field, 'reqd', 1);
-                    values_filled = false;
-                }
-            });
-            if (!values_filled) return;
+	let dialog = new frappe.ui.Dialog({
+		title: title,
+		fields: fields,
+		primary_action_label: action.label || __('Update'),
+		primary_action: () => {
+			const form_values = dialog.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) {
+					dialog.set_df_property(field, 'reqd', 1);
+					values_filled = false;
+				}
+			});
+			if (!values_filled) return;
 
-            action.on_submit(form_values);
-        }
-    });
+			action.on_submit(form_values);
+		}
+	});
 
-    dialog.set_values(initial_values);
+	dialog.set_values(initial_values);
 
-    // Post create
-    const default_company = frappe.defaults.get_default('company');
-    dialog.set_value('company', default_company);
+	// Post create
+	const default_company = frappe.defaults.get_default('company');
+	dialog.set_value('company', default_company);
 
-    return dialog;
+	return dialog;
 }
 
 export {
diff --git a/erpnext/public/js/hub/components/skeleton_state.js b/erpnext/public/js/hub/components/skeleton_state.js
deleted file mode 100644
index 7c68802..0000000
--- a/erpnext/public/js/hub/components/skeleton_state.js
+++ /dev/null
@@ -1,27 +0,0 @@
-function get_detail_skeleton_html() {
-	const skeleton = `<div class="hub-item-container">
-		<div class="row">
-			<div class="col-md-3">
-				<div class="hub-item-skeleton-image"></div>
-			</div>
-			<div class="col-md-6">
-				<h2 class="hub-skeleton" style="width: 75%;">Name</h2>
-				<div class="text-muted">
-					<p class="hub-skeleton" style="width: 35%;">Details</p>
-					<p class="hub-skeleton" style="width: 50%;">Ratings</p>
-				</div>
-				<hr>
-				<div class="hub-item-description">
-					<p class="hub-skeleton">Desc</p>
-					<p class="hub-skeleton" style="width: 85%;">Desc</p>
-				</div>
-			</div>
-		</div>
-	</div>`;
-
-	return skeleton;
-}
-
-export {
-	get_detail_skeleton_html
-}
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index 08cc01a..10a55aa 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -3,11 +3,8 @@
 
 // pages
 import './pages/item';
-import './pages/seller';
-import './pages/profile';
 import './pages/messages';
 import './pages/buying_messages';
-import './pages/not_found';
 
 import PageContainer from './PageContainer.vue';
 import Home from './pages/Home.vue';
@@ -16,6 +13,9 @@
 import Category from './pages/Category.vue';
 import Search from './pages/Search.vue';
 import PublishedProducts from './pages/PublishedProducts.vue';
+import Profile from './pages/Profile.vue';
+import Seller from './pages/Seller.vue';
+import NotFound from './pages/NotFound.vue';
 
 // components
 import { ProfileDialog } from './components/profile_dialog';
@@ -203,7 +203,7 @@
 		}
 
 		if (route[1] === 'seller' && !this.subpages['seller']) {
-			this.subpages['seller'] = new erpnext.hub.Seller(this.$body);
+			this.subpages['seller'] = new erpnext.hub.SellerPage(this.$body);
 		}
 
 		if (route[1] === 'register' && !this.subpages.register) {
@@ -220,7 +220,7 @@
 		}
 
 		if (route[1] === 'profile' && !this.subpages.profile) {
-			this.subpages.profile = new erpnext.hub.Profile(this.$body);
+			this.subpages.profile = new erpnext.hub.ProfilePage(this.$body);
 		}
 
 		if (route[1] === 'publish' && !this.subpages.publish) {
@@ -248,7 +248,7 @@
 
 		if (!Object.keys(this.subpages).includes(route[1])) {
 			if (!this.subpages.not_found) {
-				this.subpages.not_found = new erpnext.hub.NotFound(this.$body);
+				this.subpages.not_found = new erpnext.hub.NotFoundPage(this.$body);
 			}
 			route[1] = 'not_found';
 		}
@@ -391,3 +391,58 @@
 		$('[data-page-name="search"]').hide();
 	}
 }
+
+erpnext.hub.ProfilePage = class {
+	constructor(parent) {
+		this.$wrapper = $(`<div id="vue-area-profile">`).appendTo($(parent));
+
+		new Vue({
+			render: h => h(Profile)
+		}).$mount('#vue-area-profile');
+	}
+
+	show() {
+		$('[data-page-name="profile"]').show();
+	}
+
+	hide() {
+		$('[data-page-name="profile"]').hide();
+	}
+}
+
+erpnext.hub.SellerPage = class {
+	constructor(parent) {
+		this.$wrapper = $(`<div id="vue-area-seller">`).appendTo($(parent));
+
+		new Vue({
+			render: h => h(Seller)
+		}).$mount('#vue-area-seller');
+	}
+
+	show() {
+		$('[data-page-name="seller"]').show();
+	}
+
+	hide() {
+		$('[data-page-name="seller"]').hide();
+	}
+}
+
+erpnext.hub.NotFoundPage = class {
+	constructor(parent) {
+		this.$wrapper = $(`<div id="vue-area-not-found">`).appendTo($(parent));
+
+		new Vue({
+			render: h => h(NotFound)
+		}).$mount('#vue-area-not-found');
+	}
+
+	show() {
+		$('[data-page-name="not-found"]').show();
+	}
+
+	hide() {
+		$('[data-page-name="not-found"]').hide();
+	}
+}
+
diff --git a/erpnext/public/js/hub/pages/NotFound.vue b/erpnext/public/js/hub/pages/NotFound.vue
new file mode 100644
index 0000000..7a76437
--- /dev/null
+++ b/erpnext/public/js/hub/pages/NotFound.vue
@@ -0,0 +1,41 @@
+<template>
+	<div
+		class="marketplace-page"
+		:data-page-name="page_name"
+	>
+		<empty-state
+			:message="empty_state_message"
+			:height="500"
+			:action="action"
+		>
+		</empty-state>
+
+	</div>
+</template>
+
+<script>
+import EmptyState from '../components/EmptyState.vue';
+
+export default {
+	name: 'not-found-page',
+	components: {
+		EmptyState
+	},
+	data() {
+		return {
+			page_name: 'not-found',
+			action: {
+				label: __('Back to Home'),
+				on_click: () => {
+					frappe.set_route(`marketplace/home`);
+				}
+			},
+
+			// Constants
+			empty_state_message: __(`Sorry! I could not find what you were looking for.`)
+		};
+	},
+}
+</script>
+
+<style scoped></style>
diff --git a/erpnext/public/js/hub/pages/Profile.vue b/erpnext/public/js/hub/pages/Profile.vue
new file mode 100644
index 0000000..1767796
--- /dev/null
+++ b/erpnext/public/js/hub/pages/Profile.vue
@@ -0,0 +1,73 @@
+<template>
+	<div
+		class="marketplace-page"
+		:data-page-name="page_name"
+		v-if="init || profile"
+	>
+
+		<detail-view
+			:title="title"
+			:subtitles="subtitles"
+			:image="image"
+			:sections="sections"
+			:show_skeleton="init"
+		>
+		</detail-view>
+	</div>
+</template>
+
+<script>
+import DetailView from '../components/DetailView.vue';
+
+export default {
+	name: 'profile-page',
+	components: {
+		DetailView
+	},
+	data() {
+		return {
+			page_name: frappe.get_route()[1],
+
+			init: true,
+
+			profile: null,
+			title: null,
+			subtitles: [],
+			image: null,
+			sections: []
+		};
+	},
+	created() {
+		this.get_profile();
+	},
+	methods: {
+		get_profile() {
+			hub.call(
+				'get_hub_seller_profile',
+				{ hub_seller: hub.settings.company_email }
+			).then(profile => {
+				this.init = false;
+
+				this.profile = profile;
+				this.title = profile.company;
+				this.subtitles = [
+					__(profile.country),
+					__(profile.site_name),
+					__(`Joined ${comment_when(profile.creation)}`)
+				];
+				this.image = profile.logo;
+				this.sections = [
+					{
+						title: __('About the Company'),
+						content: profile.company_description
+							? __(profile.company_description)
+							: __('No description')
+					}
+				];
+			});
+		}
+	}
+}
+</script>
+
+<style scoped></style>
diff --git a/erpnext/public/js/hub/pages/SavedProducts.vue b/erpnext/public/js/hub/pages/SavedProducts.vue
index 6e5eeff..f113a20 100644
--- a/erpnext/public/js/hub/pages/SavedProducts.vue
+++ b/erpnext/public/js/hub/pages/SavedProducts.vue
@@ -71,7 +71,7 @@
 			}
 
 			alert = frappe.show_alert(__(`<span>${hub_item_code} removed.
-				<a href="#" class="undo-remove" data-action="undo-remove"><b>Undo</b></a></span>`),
+				<a href="#" data-action="undo-remove"><b>Undo</b></a></span>`),
 				grace_period/1000,
 				{
 					'undo-remove': undo_remove.bind(this)
diff --git a/erpnext/public/js/hub/pages/Seller.vue b/erpnext/public/js/hub/pages/Seller.vue
new file mode 100644
index 0000000..5a35812
--- /dev/null
+++ b/erpnext/public/js/hub/pages/Seller.vue
@@ -0,0 +1,99 @@
+<template>
+	<div
+		class="marketplace-page"
+		:data-page-name="page_name"
+		v-if="init || profile"
+	>
+		<detail-view
+			:title="title"
+			:subtitles="subtitles"
+			:image="image"
+			:sections="sections"
+			:show_skeleton="init"
+		>
+		</detail-view>
+
+		<h5 v-if="profile">{{ item_container_heading }}</h5>
+		<item-cards-container
+			:container_name="item_container_heading"
+			:items="items"
+			:item_id_fieldname="item_id_fieldname"
+			:on_click="go_to_item_details_page"
+		>
+		</item-cards-container>
+	</div>
+</template>
+
+<script>
+import DetailView from '../components/DetailView.vue';
+import ItemCardsContainer from '../components/ItemCardsContainer.vue';
+
+export default {
+	name: 'seller-page',
+	components: {
+		DetailView,
+		ItemCardsContainer
+	},
+	data() {
+		return {
+			page_name: frappe.get_route()[1],
+			seller_company: frappe.get_route()[2],
+
+			init: true,
+
+			profile: null,
+			items:[],
+			item_id_fieldname: 'hub_item_code',
+
+			title: null,
+			subtitles: [],
+			image: null,
+			sections: [],
+		};
+	},
+	created() {
+		this.get_seller_profile_and_items();
+	},
+	computed: {
+		item_container_heading() {
+			return __('Products by ' + this.seller_company);
+		}
+	},
+	methods: {
+		get_seller_profile_and_items() {
+			hub.call(
+				'get_hub_seller_page_info',
+				{ company: this.seller_company }
+			).then(data => {
+				this.init = false;
+				this.profile = data.profile;
+				this.items = data.items;
+
+				const profile = this.profile;
+
+				this.title = profile.company;
+				this.subtitles = [
+					__(profile.country),
+					__(profile.site_name),
+					__(`Joined ${comment_when(profile.creation)}`)
+				];
+				this.image = profile.logo;
+				this.sections = [
+					{
+						title: __('About the Company'),
+						content: profile.company_description
+							? __(profile.company_description)
+							: __('No description')
+					}
+				];
+			});
+		},
+
+		go_to_item_details_page(hub_item_code) {
+			frappe.set_route(`marketplace/item/${hub_item_code}`);
+		}
+	}
+}
+</script>
+
+<style scoped></style>
diff --git a/erpnext/public/js/hub/pages/item.js b/erpnext/public/js/hub/pages/item.js
index 618c958..f15d1be 100644
--- a/erpnext/public/js/hub/pages/item.js
+++ b/erpnext/public/js/hub/pages/item.js
@@ -1,6 +1,6 @@
 import SubPage from './subpage';
 import { get_detail_view_html } from '../components/detail_view';
-import { get_detail_skeleton_html } from '../components/skeleton_state';
+// import { get_detail_skeleton_html } from '../components/skeleton_state';
 import { get_review_html } from '../components/reviews';
 
 erpnext.hub.Item = class Item extends SubPage {
@@ -20,7 +20,7 @@
 
 
 	show_skeleton() {
-		this.$wrapper.html(get_detail_skeleton_html());
+		// this.$wrapper.html(get_detail_skeleton_html());
 	}
 
 
diff --git a/erpnext/public/js/hub/pages/messages.js b/erpnext/public/js/hub/pages/messages.js
index f8faa99..6222f53 100644
--- a/erpnext/public/js/hub/pages/messages.js
+++ b/erpnext/public/js/hub/pages/messages.js
@@ -1,5 +1,5 @@
 import SubPage from './subpage';
-import { get_item_card_container_html } from '../components/items_container';
+// import { get_item_card_container_html } from '../components/items_container';
 import { get_buying_item_message_card_html } from '../components/item_card';
 import { get_selling_item_message_card_html } from '../components/item_card';
 import { get_empty_state } from '../components/empty_state';
@@ -22,7 +22,7 @@
 	}
 
 	render(items = [], title) {
-		const html = get_item_card_container_html(items, title, get_buying_item_message_card_html);
+		// const html = get_item_card_container_html(items, title, get_buying_item_message_card_html);
 		this.$wrapper.append(html);
 	}
 
@@ -54,7 +54,7 @@
 	}
 
 	render(items = [], title) {
-		const html = get_item_card_container_html(items, title, get_selling_item_message_card_html);
+		// const html = get_item_card_container_html(items, title, get_selling_item_message_card_html);
 		this.$wrapper.append(html);
 	}
 
@@ -101,4 +101,4 @@
 			<p>${message.content}</p>
 		</div>
 	`;
-}
\ No newline at end of file
+}
diff --git a/erpnext/public/js/hub/pages/not_found.js b/erpnext/public/js/hub/pages/not_found.js
deleted file mode 100644
index f7ccc2f..0000000
--- a/erpnext/public/js/hub/pages/not_found.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import SubPage from './subpage';
-import { get_empty_state } from '../components/empty_state';
-
-erpnext.hub.NotFound = class NotFound extends SubPage {
-	refresh() {
-		this.$wrapper.html(get_empty_state(
-			__('Sorry! I could not find what you were looking for.'),
-			`<button class="btn btn-default btn-xs" data-route="marketplace/home">${__('Back to home')}</button>`
-		));
-	}
-}
diff --git a/erpnext/public/js/hub/pages/profile.js b/erpnext/public/js/hub/pages/profile.js
deleted file mode 100644
index 9bfa85d..0000000
--- a/erpnext/public/js/hub/pages/profile.js
+++ /dev/null
@@ -1,148 +0,0 @@
-import SubPage from './subpage';
-import { get_detail_skeleton_html } from '../components/skeleton_state';
-import { ProfileDialog } from '../components/profile_dialog';
-
-erpnext.hub.Profile = class Profile extends SubPage {
-	make_wrapper() {
-		super.make_wrapper();
-		this.make_edit_profile_dialog();
-	}
-
-	refresh() {
-		this.show_skeleton();
-		this.get_hub_seller_profile(this.keyword)
-			.then(profile => {
-				this.edit_profile_dialog.set_values(profile);
-				this.render(profile);
-			});
-	}
-
-	get_hub_seller_profile() {
-		return hub.call('get_hub_seller_profile', { hub_seller: hub.settings.company_email });
-	}
-
-	show_skeleton() {
-		this.$wrapper.html(get_detail_skeleton_html());
-	}
-
-	render(profile) {
-		const p = profile;
-		const content_by_log_type = this.get_content_by_log_type();
-
-		let activity_logs = (p.hub_seller_activity || []).sort((a, b) => {
-			return new Date(b.creation) - new Date(a.creation);
-		});
-
-		const timeline_items_html = activity_logs
-			.map(log => {
-				const stats = JSON.parse(log.stats);
-				const no_of_items = stats && stats.push_update || '';
-
-				const content = content_by_log_type[log.type];
-				const message = content.get_message(no_of_items);
-				const icon = content.icon;
-				return this.get_timeline_log_item(log.pretty_date, message, icon);
-			})
-			.join('');
-
-		const profile_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="${p.logo}">
-					</div>
-				</div>
-				<div class="col-md-8">
-					<h2>${p.company}</h2>
-					<div class="text-muted">
-						<p>${p.country}</p>
-						<p>${p.site_name}</p>
-					</div>
-					<hr>
-					<div class="hub-item-description">
-					${'description'
-						? `<p>${p.company_description}</p>`
-						: `<p>__('No description')</p`
-					}
-					</div>
-				</div>
-				<div class="col-md-1">
-					<div class="dropdown pull-right hub-item-dropdown">
-						<a class="dropdown-toggle btn btn-xs btn-default" data-toggle="dropdown">
-							<span class="caret"></span>
-						</a>
-						<ul class="dropdown-menu dropdown-right" role="menu">
-						<li><a data-action="edit_profile">${__('Edit Profile')}</a></li>
-						</ul>
-					</div>
-				</div>
-			</div>
-
-			<div class="timeline">
-				<div class="timeline-items">
-					${timeline_items_html}
-				</div>
-			</div>
-
-		</div>`;
-
-		this.$wrapper.html(profile_html);
-	}
-
-	make_edit_profile_dialog() {
-		this.edit_profile_dialog = ProfileDialog(
-			__('Edit Profile'),
-			{
-				label: __('Update'),
-				on_submit: this.update_profile.bind(this)
-			}
-		);
-
-		this.edit_profile_dialog.set_df_property('company_email', 'read_only', 1);
-	}
-
-	edit_profile() {
-		this.edit_profile_dialog.set_values({
-			company_email: hub.settings.company_email
-		});
-		this.edit_profile_dialog.show();
-	}
-
-	update_profile(new_values) {
-		hub.call('update_profile', {
-			hub_seller: hub.settings.company_email,
-			updated_profile: new_values
-		}).then(new_profile => {
-				this.edit_profile_dialog.hide();
-				this.render(new_profile);
-			});
-	}
-
-	get_timeline_log_item(pretty_date, message, icon) {
-		return `<div class="media timeline-item  notification-content">
-			<div class="small">
-				<i class="octicon ${icon} fa-fw"></i>
-				<span title="Administrator"><b>${pretty_date}</b> ${message}</span>
-			</div>
-		</div>`;
-	}
-
-	get_content_by_log_type() {
-		return {
-			"Created": {
-				icon: 'octicon-heart',
-				get_message: () => 'Joined Marketplace'
-			},
-			"Items Publish": {
-				icon: 'octicon-bookmark',
-				get_message: (no_of_items) =>
-					`Published ${no_of_items} product${no_of_items > 1 ? 's' : ''} to Marketplace`
-			}
-		}
-	}
-}
diff --git a/erpnext/public/js/hub/pages/seller.js b/erpnext/public/js/hub/pages/seller.js
deleted file mode 100644
index b86e46e..0000000
--- a/erpnext/public/js/hub/pages/seller.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import SubPage from './subpage';
-import { get_profile_html } from '../components/detail_view';
-import { get_item_card_container_html } from '../components/items_container';
-import { get_detail_skeleton_html } from '../components/skeleton_state';
-
-erpnext.hub.Seller = class Seller extends SubPage {
-	make_wrapper() {
-		super.make_wrapper();
-	}
-
-	refresh() {
-		this.show_skeleton();
-		this.company = frappe.get_route()[2];
-		this.get_hub_seller_profile()
-			.then(this.render.bind(this));
-	}
-
-	get_hub_seller_profile() {
-		return hub.call('get_hub_seller_page_info', { company: this.company });
-	}
-
-	show_skeleton() {
-		this.$wrapper.html(get_detail_skeleton_html());
-	}
-
-	render(data) {
-		this.$wrapper.html(get_profile_html(data.profile));
-
-		let html = get_item_card_container_html(data.items, __('Products by ' + p.company));
-		this.$wrapper.append(html);
-	}
-}