feat: Selling Page
- common Messages page for both buying and selling
This commit is contained in:
parent
bc859cbf1d
commit
725603c0a9
@ -15,7 +15,8 @@ import Item from './pages/Item.vue';
|
|||||||
import Seller from './pages/Seller.vue';
|
import Seller from './pages/Seller.vue';
|
||||||
import Publish from './pages/Publish.vue';
|
import Publish from './pages/Publish.vue';
|
||||||
import Buying from './pages/Buying.vue';
|
import Buying from './pages/Buying.vue';
|
||||||
import BuyingMessages from './pages/BuyingMessages.vue';
|
import Selling from './pages/Selling.vue';
|
||||||
|
import Messages from './pages/Messages.vue';
|
||||||
import Profile from './pages/Profile.vue';
|
import Profile from './pages/Profile.vue';
|
||||||
import NotFound from './pages/NotFound.vue';
|
import NotFound from './pages/NotFound.vue';
|
||||||
|
|
||||||
@ -33,7 +34,9 @@ const route_map = {
|
|||||||
'marketplace/publish': Publish,
|
'marketplace/publish': Publish,
|
||||||
'marketplace/my-products': PublishedProducts,
|
'marketplace/my-products': PublishedProducts,
|
||||||
'marketplace/buying': Buying,
|
'marketplace/buying': Buying,
|
||||||
'marketplace/buying/:item': BuyingMessages,
|
'marketplace/buying/:item': Messages,
|
||||||
|
'marketplace/selling': Selling,
|
||||||
|
'marketplace/selling/:buyer/:item': Messages
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="list-unstyled hub-sidebar-group" data-categories>
|
<ul class="list-unstyled hub-sidebar-group" data-categories>
|
||||||
|
<li class="hub-sidebar-item is-title bold text-muted">
|
||||||
|
{{ __('Categories') }}
|
||||||
|
</li>
|
||||||
<li class="hub-sidebar-item" v-for="category in categories" :key="category.label" v-route="category.route">
|
<li class="hub-sidebar-item" v-for="category in categories" :key="category.label" v-route="category.route">
|
||||||
{{ category.label }}
|
{{ category.label }}
|
||||||
</li>
|
</li>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="empty-state flex align-center flex-column justify-center"
|
<div class="empty-state flex flex-column"
|
||||||
:class="{ bordered: bordered }"
|
:class="{ 'bordered': bordered, 'align-center': centered, 'justify-center': centered }"
|
||||||
:style="{ height: height + 'px' }"
|
:style="{ height: height + 'px' }"
|
||||||
>
|
>
|
||||||
<p class="text-muted">{{ message }}</p>
|
<p class="text-muted">{{ message }}</p>
|
||||||
@ -22,17 +22,20 @@ export default {
|
|||||||
message: String,
|
message: String,
|
||||||
bordered: Boolean,
|
bordered: Boolean,
|
||||||
height: Number,
|
height: Number,
|
||||||
action: Object
|
action: Object,
|
||||||
|
centered: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less">
|
||||||
@import "../../../../../../frappe/frappe/public/less/variables.less";
|
@import "../../../../../../frappe/frappe/public/less/variables.less";
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
height: 500px;
|
height: 500px;
|
||||||
margin: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-state.bordered {
|
.empty-state.bordered {
|
||||||
|
@ -5,13 +5,11 @@
|
|||||||
<div class="hub-list-body ellipsis">
|
<div class="hub-list-body ellipsis">
|
||||||
<div class="hub-list-title">{{item.item_name}}</div>
|
<div class="hub-list-title">{{item.item_name}}</div>
|
||||||
<div class="hub-list-subtitle ellipsis">
|
<div class="hub-list-subtitle ellipsis">
|
||||||
<span>{{message.sender}}: </span>
|
<slot name="subtitle"></slot>
|
||||||
<span>{{message.content}}</span>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hub-list-right">
|
<div class="hub-list-right" v-if="message">
|
||||||
<span class="text-muted" v-html="frappe.datetime.comment_when(message.creation, true)" />
|
<span class="text-muted" v-html="frappe.datetime.comment_when(message.creation, true)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,32 +3,39 @@
|
|||||||
<section-header>
|
<section-header>
|
||||||
<h4>{{ __('Buying') }}</h4>
|
<h4>{{ __('Buying') }}</h4>
|
||||||
</section-header>
|
</section-header>
|
||||||
<div class="row">
|
<div class="row" v-if="items">
|
||||||
<div class="col-md-7"
|
<div class="col-md-7 margin-bottom"
|
||||||
v-for="item of items"
|
v-for="item of items"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
>
|
>
|
||||||
<item-list-card
|
<item-list-card
|
||||||
:item="item"
|
:item="item"
|
||||||
:message="item.recent_message"
|
|
||||||
v-route="'marketplace/buying/' + item.name"
|
v-route="'marketplace/buying/' + item.name"
|
||||||
/>
|
>
|
||||||
|
<div slot="subtitle">
|
||||||
|
<span>{{item.recent_message.sender}}: </span>
|
||||||
|
<span>{{item.recent_message.content}}</span>
|
||||||
|
</div>
|
||||||
|
</item-list-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<empty-state v-else message="This page keeps track of items you want to buy from sellers." :centered="false" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import EmptyState from '../components/EmptyState.vue';
|
||||||
import SectionHeader from '../components/SectionHeader.vue';
|
import SectionHeader from '../components/SectionHeader.vue';
|
||||||
import ItemListCard from '../components/ItemListCard.vue';
|
import ItemListCard from '../components/ItemListCard.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SectionHeader,
|
SectionHeader,
|
||||||
ItemListCard
|
ItemListCard,
|
||||||
|
EmptyState
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
items: []
|
items: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
></detail-header-item>
|
></detail-header-item>
|
||||||
|
|
||||||
<button slot="detail-header-item"
|
<button slot="detail-header-item"
|
||||||
class="btn btn-primary margin-top"
|
class="btn btn-primary btn-sm margin-top"
|
||||||
@click="primary_action.action"
|
@click="primary_action.action"
|
||||||
>
|
>
|
||||||
{{ primary_action.label }}
|
{{ primary_action.label }}
|
||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
</detail-view>
|
</detail-view>
|
||||||
|
|
||||||
<!-- <review-area :hub_item_code="hub_item_code"></review-area> -->
|
<!-- <review-area :hub_item_name="hub_item_name"></review-area> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
page_name: frappe.get_route()[1],
|
page_name: frappe.get_route()[1],
|
||||||
hub_item_code: frappe.get_route()[2],
|
hub_item_name: frappe.get_route()[2],
|
||||||
|
|
||||||
init: true,
|
init: true,
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
get_profile() {
|
get_profile() {
|
||||||
hub.call('get_item_details',{ hub_item_code: this.hub_item_code })
|
hub.call('get_item_details', { hub_item_name: this.hub_item_name })
|
||||||
.then(item => {
|
.then(item => {
|
||||||
this.init = false;
|
this.init = false;
|
||||||
this.item = item;
|
this.item = item;
|
||||||
@ -185,12 +185,12 @@ export default {
|
|||||||
hub.call('send_message', {
|
hub.call('send_message', {
|
||||||
from_seller: hub.settings.company_email,
|
from_seller: hub.settings.company_email,
|
||||||
to_seller: this.item.hub_seller,
|
to_seller: this.item.hub_seller,
|
||||||
hub_item: this.item.hub_item_code,
|
hub_item: this.item.name,
|
||||||
message
|
message
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
d.hide();
|
d.hide();
|
||||||
frappe.set_route('marketplace', 'buy', this.item.hub_item_code);
|
frappe.set_route('marketplace', 'buying', this.item.name);
|
||||||
erpnext.hub.trigger('action:send_message')
|
erpnext.hub.trigger('action:send_message')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="item_details">
|
<div v-if="item_details">
|
||||||
<div>
|
<div>
|
||||||
<a class="text-muted" v-route="'marketplace/buying'">← {{ __('Back to Messages') }}</a>
|
<a class="text-muted" v-route="back_link">← {{ __('Back to Messages') }}</a>
|
||||||
</div>
|
</div>
|
||||||
<section-header>
|
<section-header>
|
||||||
<div class="flex flex-column margin-bottom">
|
<div class="flex flex-column margin-bottom">
|
||||||
@ -40,6 +40,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
message_type: frappe.get_route()[1],
|
||||||
item_details: null,
|
item_details: null,
|
||||||
messages: []
|
messages: []
|
||||||
}
|
}
|
||||||
@ -49,12 +50,17 @@ export default {
|
|||||||
this.get_item_details(hub_item_name)
|
this.get_item_details(hub_item_name)
|
||||||
.then(item_details => {
|
.then(item_details => {
|
||||||
this.item_details = item_details;
|
this.item_details = item_details;
|
||||||
this.get_messages(item_details)
|
this.get_messages()
|
||||||
.then(messages => {
|
.then(messages => {
|
||||||
this.messages = messages;
|
this.messages = messages;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
back_link() {
|
||||||
|
return 'marketplace/' + this.message_type;
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
send_message(message) {
|
send_message(message) {
|
||||||
this.messages.push({
|
this.messages.push({
|
||||||
@ -65,7 +71,7 @@ export default {
|
|||||||
});
|
});
|
||||||
hub.call('send_message', {
|
hub.call('send_message', {
|
||||||
from_seller: hub.settings.company_email,
|
from_seller: hub.settings.company_email,
|
||||||
to_seller: this.item_details.hub_seller,
|
to_seller: this.get_against_seller(),
|
||||||
hub_item: this.item_details.name,
|
hub_item: this.item_details.name,
|
||||||
message
|
message
|
||||||
});
|
});
|
||||||
@ -76,12 +82,23 @@ export default {
|
|||||||
get_messages() {
|
get_messages() {
|
||||||
if (!this.item_details) return [];
|
if (!this.item_details) return [];
|
||||||
return hub.call('get_messages', {
|
return hub.call('get_messages', {
|
||||||
against_seller: this.item_details.hub_seller,
|
against_seller: this.get_against_seller(),
|
||||||
against_item: this.item_details.name
|
against_item: this.item_details.name
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
get_against_seller() {
|
||||||
|
if (this.message_type === 'buying') {
|
||||||
|
return this.item_details.hub_seller;
|
||||||
|
} else if (this.message_type === 'selling') {
|
||||||
|
return frappe.get_route()[2];
|
||||||
|
}
|
||||||
|
},
|
||||||
get_hub_item_name() {
|
get_hub_item_name() {
|
||||||
return frappe.get_route()[2];
|
if (this.message_type === 'buying') {
|
||||||
|
return frappe.get_route()[2];
|
||||||
|
} else if (this.message_type === 'selling') {
|
||||||
|
return frappe.get_route()[3];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
64
erpnext/public/js/hub/pages/Selling.vue
Normal file
64
erpnext/public/js/hub/pages/Selling.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<section-header>
|
||||||
|
<h4>{{ __('Selling') }}</h4>
|
||||||
|
</section-header>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-7"
|
||||||
|
style="margin-bottom: 30px;"
|
||||||
|
v-for="item of items"
|
||||||
|
:key="item.name"
|
||||||
|
>
|
||||||
|
<item-list-card
|
||||||
|
:item="item"
|
||||||
|
>
|
||||||
|
<div slot="subtitle">
|
||||||
|
<span class="text-muted">{{ __('{0} conversations', [item.received_messages.length]) }}</span>
|
||||||
|
</div>
|
||||||
|
</item-list-card>
|
||||||
|
<div class="hub-list-item" v-for="(message, index) in item.received_messages" :key="index"
|
||||||
|
v-route="'marketplace/selling/' + message.buyer_email + '/' + item.name"
|
||||||
|
>
|
||||||
|
<div class="hub-list-left">
|
||||||
|
<div class="hub-list-body">
|
||||||
|
<div class="hub-list-title">
|
||||||
|
{{ message.buyer }}
|
||||||
|
</div>
|
||||||
|
<div class="hub-list-subtitle">
|
||||||
|
{{ message.sender }}: {{ message.content }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import SectionHeader from '../components/SectionHeader.vue';
|
||||||
|
import ItemListCard from '../components/ItemListCard.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
SectionHeader,
|
||||||
|
ItemListCard
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
items: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.get_items_for_messages()
|
||||||
|
.then(items => {
|
||||||
|
this.items = items;
|
||||||
|
console.log(items);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
get_items_for_messages() {
|
||||||
|
return hub.call('get_selling_items_for_messages');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -198,8 +198,17 @@ body[data-route^="marketplace/"] {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border: 1px solid @border-color;
|
border: 1px solid @border-color;
|
||||||
margin-bottom: 15px;
|
margin-bottom: -1px;
|
||||||
border-radius: 3px;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hub-list-item:first-child {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.hub-list-item:last-child {
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hub-list-left {
|
.hub-list-left {
|
||||||
|
Loading…
Reference in New Issue
Block a user