[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);
- });
- }
- }
-}