[hub][vue] Home page, add section title in item key in v-for
diff --git a/erpnext/public/js/hub/components/ItemCardsContainer.vue b/erpnext/public/js/hub/components/ItemCardsContainer.vue
index 741fc6b..5af82de 100644
--- a/erpnext/public/js/hub/components/ItemCardsContainer.vue
+++ b/erpnext/public/js/hub/components/ItemCardsContainer.vue
@@ -9,7 +9,7 @@
 		</empty-state>
 		<item-card
 			v-for="item in items"
-			:key="item[item_id_fieldname]"
+			:key="container_name + '_' +item[item_id_fieldname]"
 			:item="item"
 			:item_id_fieldname="item_id_fieldname"
 			:is_local="is_local"
@@ -29,6 +29,7 @@
 export default {
 	name: 'item-cards-container',
 	props: {
+		container_name: String,
 		items: Array,
 		item_id_fieldname: String,
 		is_local: Boolean,
diff --git a/erpnext/public/js/hub/components/search_bar.js b/erpnext/public/js/hub/components/search_bar.js
deleted file mode 100644
index 9526516..0000000
--- a/erpnext/public/js/hub/components/search_bar.js
+++ /dev/null
@@ -1,20 +0,0 @@
-function make_search_bar({wrapper, on_search, placeholder = __('Search for anything')}) {
-	const $search = $(`
-		<div class="hub-search-container">
-			<input type="text" class="form-control" placeholder="${placeholder}">
-		</div>`
-	);
-	wrapper.append($search);
-	const $search_input = $search.find('input');
-
-	$search_input.on('keydown', frappe.utils.debounce((e) => {
-		if (e.which === frappe.ui.keyCode.ENTER) {
-			const search_value = $search_input.val();
-			on_search(search_value);
-		}
-	}, 300));
-}
-
-export {
-    make_search_bar
-}
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index 0438d6f..d8bfea8 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -1,7 +1,6 @@
 import Vue from 'vue/dist/vue.js';
 
 // pages
-import './pages/home';
 import './pages/item';
 import './pages/seller';
 import './pages/profile';
@@ -9,6 +8,7 @@
 import './pages/buying_messages';
 import './pages/not_found';
 
+import Home from './pages/Home.vue';
 import SavedProducts from './pages/SavedProducts.vue';
 import Publish from './pages/Publish.vue';
 import Category from './pages/Category.vue';
@@ -170,7 +170,7 @@
 		}
 
 		if (route[1] === 'home' && !this.subpages.home) {
-			this.subpages.home = new erpnext.hub.Home(this.$body);
+			this.subpages.home = new erpnext.hub.HomePage(this.$body);
 		}
 
 		if (route[1] === 'search' && !this.subpages.search) {
@@ -266,6 +266,23 @@
 	}
 }
 
+erpnext.hub.HomePage = class {
+	constructor(parent) {
+		this.$wrapper = $(`<div id="vue-area-home">`).appendTo($(parent));
+
+		new Vue({
+			render: h => h(Home)
+		}).$mount('#vue-area-home');
+	}
+
+	show() {
+		$('[data-page-name="home"]').show();
+	}
+
+	hide() {
+		$('[data-page-name="home"]').hide();
+	}
+}
 
 erpnext.hub.SavedProductsPage = class {
 	constructor(parent) {
diff --git a/erpnext/public/js/hub/pages/Category.vue b/erpnext/public/js/hub/pages/Category.vue
index c346ca9..2a521f4 100644
--- a/erpnext/public/js/hub/pages/Category.vue
+++ b/erpnext/public/js/hub/pages/Category.vue
@@ -6,6 +6,7 @@
 		<h5>{{ page_title }}</h5>
 
 		<item-cards-container
+			:container_name="page_title"
 			:items="items"
 			:item_id_fieldname="item_id_fieldname"
 			:on_click="go_to_item_details_page"
diff --git a/erpnext/public/js/hub/pages/Home.vue b/erpnext/public/js/hub/pages/Home.vue
new file mode 100644
index 0000000..e91fb38
--- /dev/null
+++ b/erpnext/public/js/hub/pages/Home.vue
@@ -0,0 +1,103 @@
+<template>
+	<div
+		class="marketplace-page"
+		:data-page-name="page_name"
+	>
+		<search-input
+			:placeholder="search_placeholder"
+			:on_search="set_search_route"
+			v-model="search_value"
+		>
+		</search-input>
+
+		<div v-for="section in sections"
+			:key="section.title"
+		>
+			<div class="hub-items-header margin-bottom level">
+				<h4>{{ section.title }}</h4>
+				<p :data-route="'marketplace/category/' + section.title">{{ 'See All' }}</p>
+			</div>
+
+			<item-cards-container
+				:container_name="section.title"
+				:items="section.items"
+				:item_id_fieldname="item_id_fieldname"
+				:on_click="go_to_item_details_page"
+			>
+			</item-cards-container>
+		</div>
+
+	</div>
+</template>
+
+<script>
+import SearchInput from '../components/SearchInput.vue';
+import ItemCardsContainer from '../components/ItemCardsContainer.vue';
+
+export default {
+	name: 'home-page',
+	components: {
+		SearchInput,
+		ItemCardsContainer
+	},
+	data() {
+		return {
+			page_name: frappe.get_route()[1],
+			item_id_fieldname: 'hub_item_code',
+			search_value: '',
+
+			sections: [],
+
+			// Constants
+			search_placeholder: __('Search for anything ...'),
+		};
+	},
+	created() {
+		// refreshed
+		this.search_value = '';
+		this.get_items();
+	},
+	methods: {
+		get_items() {
+			hub.call('get_data_for_homepage', {
+				country: frappe.defaults.get_user_default('country')
+			})
+			.then((data) => {
+				this.sections.push({
+					title: __('Explore'),
+					items: data.random_items
+				});
+				if (data.items_by_country.length) {
+					this.sections.push({
+						title: __('Near you'),
+						items: data.items_by_country
+					});
+				}
+
+				const category_items = data.category_items;
+
+				if (category_items) {
+					Object.keys(category_items).map(category => {
+						const items = category_items[category];
+
+						this.sections.push({
+							title: __(category),
+							items
+						});
+					});
+				}
+			})
+		},
+
+		go_to_item_details_page(hub_item_code) {
+			frappe.set_route(`marketplace/item/${hub_item_code}`);
+		},
+
+		set_search_route() {
+			frappe.set_route('marketplace', 'search', this.search_value);
+		},
+	}
+}
+</script>
+
+<style scoped></style>
diff --git a/erpnext/public/js/hub/pages/Publish.vue b/erpnext/public/js/hub/pages/Publish.vue
index f2b3369..b801b92 100644
--- a/erpnext/public/js/hub/pages/Publish.vue
+++ b/erpnext/public/js/hub/pages/Publish.vue
@@ -21,6 +21,7 @@
 		</div>
 
 		<item-cards-container
+			:container_name="page_title"
 			:items="selected_items"
 			:item_id_fieldname="item_id_fieldname"
 			:is_local="true"
diff --git a/erpnext/public/js/hub/pages/PublishedProducts.vue b/erpnext/public/js/hub/pages/PublishedProducts.vue
index cbebc03..db9057d 100644
--- a/erpnext/public/js/hub/pages/PublishedProducts.vue
+++ b/erpnext/public/js/hub/pages/PublishedProducts.vue
@@ -6,6 +6,7 @@
 		<h5>{{ page_title }}</h5>
 
 		<item-cards-container
+			:container_name="page_title"
 			:items="items"
 			:item_id_fieldname="item_id_fieldname"
 			:on_click="go_to_item_details_page"
diff --git a/erpnext/public/js/hub/pages/SavedProducts.vue b/erpnext/public/js/hub/pages/SavedProducts.vue
index a094a1c..6e5eeff 100644
--- a/erpnext/public/js/hub/pages/SavedProducts.vue
+++ b/erpnext/public/js/hub/pages/SavedProducts.vue
@@ -6,6 +6,7 @@
 		<h5>{{ page_title }}</h5>
 
 		<item-cards-container
+			:container_name="page_title"
 			:items="items"
 			:item_id_fieldname="item_id_fieldname"
 			:on_click="go_to_item_details_page"
diff --git a/erpnext/public/js/hub/pages/Search.vue b/erpnext/public/js/hub/pages/Search.vue
index 54aa58a..a7fbffc 100644
--- a/erpnext/public/js/hub/pages/Search.vue
+++ b/erpnext/public/js/hub/pages/Search.vue
@@ -5,7 +5,7 @@
 	>
 		<search-input
 			:placeholder="search_placeholder"
-			:on_search="set_route"
+			:on_search="set_route_and_get_items"
 			v-model="search_value"
 		>
 		</search-input>
@@ -13,6 +13,7 @@
 		<h5>{{ page_title }}</h5>
 
 		<item-cards-container
+			container_name="Search"
 			:items="items"
 			:item_id_fieldname="item_id_fieldname"
 			:on_click="go_to_item_details_page"
@@ -62,7 +63,7 @@
 			})
 		},
 
-		set_route() {
+		set_route_and_get_items() {
 			frappe.set_route('marketplace', 'search', this.search_value);
 			this.get_items();
 		},
diff --git a/erpnext/public/js/hub/pages/home.js b/erpnext/public/js/hub/pages/home.js
deleted file mode 100644
index 9902238..0000000
--- a/erpnext/public/js/hub/pages/home.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import SubPage from './subpage';
-import { make_search_bar } from '../components/search_bar';
-import { get_item_card_container_html } from '../components/items_container';
-import { get_item_card_html } from '../components/item_card';
-
-erpnext.hub.Home = class Home extends SubPage {
-	make_wrapper() {
-		super.make_wrapper();
-
-		make_search_bar({
-			wrapper: this.$wrapper,
-			on_search: keyword => {
-				frappe.set_route('marketplace', 'search', keyword);
-			}
-		});
-	}
-
-	refresh() {
-		this.get_items_and_render();
-	}
-
-	get_items_and_render() {
-		this.$wrapper.find('.hub-items-container').empty();
-		this.get_data()
-			.then(data => {
-				this.render(data);
-			});
-	}
-
-	get_data() {
-		return hub.call('get_data_for_homepage', { country: frappe.defaults.get_user_default('country') });
-	}
-
-	render(data) {
-		let html = get_item_card_container_html(data.random_items, __('Explore'));
-		this.$wrapper.append(html);
-
-		if (data.items_by_country.length) {
-			html = get_item_card_container_html(data.items_by_country, __('Near you'));
-			this.$wrapper.append(html);
-		}
-
-		const category_items = data.category_items;
-
-		if (category_items) {
-			Object.keys(category_items).map(category => {
-				const items = category_items[category];
-				const see_all_link = `<p data-route="marketplace/category/${category}">See All</p>`;
-
-				html = get_item_card_container_html(
-					items,
-					__(category),
-					get_item_card_html,
-					see_all_link
-				);
-				this.$wrapper.append(html);
-			});
-		}
-	}
-}