mirror of
https://github.com/irislib/iris-messenger.git
synced 2024-09-20 01:56:33 +00:00
wip store
This commit is contained in:
parent
363a8246b9
commit
b29f8680f8
@ -78,9 +78,10 @@ class Main extends Component {
|
||||
<${Settings} path="/settings"/>
|
||||
<${LogoutConfirmation} path="/logout"/>
|
||||
<${Profile.Profile} path="/profile/:id"/>
|
||||
<${StoreView} path="/store/:id"/>
|
||||
<${CheckoutView} path="/checkout/:id"/>
|
||||
<${ProductView} path="/product/:id/:store"/>
|
||||
<${StoreView} path="/store/:store"/>
|
||||
<${CheckoutView} path="/checkout/:store"/>
|
||||
<${ProductView} path="/product/:product/:store"/>
|
||||
<${ProductView} path="/product/new"/>
|
||||
<${FollowsView} path="/follows/:id"/>
|
||||
<${FollowsView} followers=${true} path="/followers/:id"/>
|
||||
</${Router}>
|
||||
|
@ -15,33 +15,24 @@ import MessageFeed from './MessageFeed.js';
|
||||
import Identicon from './Identicon.js';
|
||||
import Name from './Name.js';
|
||||
import SearchBox from './SearchBox.js';
|
||||
import StoreView from './StoreView.js';
|
||||
|
||||
class CheckoutView extends Component {
|
||||
class CheckoutView extends StoreView {
|
||||
constructor() {
|
||||
super();
|
||||
this.eventListeners = [];
|
||||
this.followedUsers = new Set();
|
||||
this.followers = new Set();
|
||||
this.cart = {};
|
||||
this.state = {
|
||||
paymentMethod: 'bitcoin',
|
||||
items: {
|
||||
aa: {name: 'Doge T-shirt', description: 'Amazing t shirt with doge', price: '100€'},
|
||||
bb: {name: 'Doge Mug', description: 'Wonderful mug with doge', price: '200€'},
|
||||
cc: {name: 'Iris Sticker', description: 'Very sticky stickers', price: '10€'},
|
||||
dd: {name: 'Iris virtual badge', description: 'Incredible profile badge', price: '5€'},
|
||||
ee: {name: 'Gun hosting', description: 'Top gun hosting', price: '10€ / month'}
|
||||
}
|
||||
};
|
||||
this.state.paymentMethod = 'bitcoin';
|
||||
}
|
||||
|
||||
changeItemCount(k, v, e) {
|
||||
this.cart[k] = Math.max(this.cart[k] + v, 0);
|
||||
localState.get('cart').get(this.props.id).get(k).put(this.cart[k]);
|
||||
localState.get('cart').get(this.props.store).get(k).put(this.cart[k]);
|
||||
}
|
||||
|
||||
confirm() {
|
||||
const pub = this.props.id;
|
||||
const pub = this.props.store;
|
||||
localState.get('cart').get(pub).map().once((v, k) => {
|
||||
!!v && localState.get('cart').get(pub).get(k).put(null);
|
||||
});
|
||||
@ -51,19 +42,18 @@ class CheckoutView extends Component {
|
||||
}
|
||||
|
||||
renderCart() {
|
||||
const total = Object.keys(this.cart).reduce((sum, currentKey) => {
|
||||
return sum + parseInt(this.state.items[currentKey].price) * this.cart[currentKey];
|
||||
}, 0);
|
||||
return html`
|
||||
<h3 class="side-padding-xs">Shopping cart</h3>
|
||||
<div class="flex-table">
|
||||
${Object.keys(this.cart).filter(k => !!this.cart[k]).map(k => {
|
||||
${Object.keys(this.cart).filter(k => !!this.cart[k] && !!this.state.items[k]).map(k => {
|
||||
const i = this.state.items[k];
|
||||
return html`
|
||||
<div class="flex-row">
|
||||
<div class="flex-cell">
|
||||
<${SafeImg} src=${i.thumbnail}/>
|
||||
${i.name}
|
||||
<a href=${'/product/' + k + '/' + this.props.store}>
|
||||
<${SafeImg} src=${i.thumbnail}/>
|
||||
${i.name || 'item'}
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex-cell no-flex price-cell">
|
||||
<p>
|
||||
@ -79,7 +69,7 @@ class CheckoutView extends Component {
|
||||
})}
|
||||
<div class="flex-row">
|
||||
<div class="flex-cell"></div>
|
||||
<div class="flex-cell no-flex"><b>Total ${total} €</b></div>
|
||||
<div class="flex-cell no-flex"><b>Total ${this.state.totalPrice} €</b></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="side-padding-xs">
|
||||
@ -133,9 +123,6 @@ class CheckoutView extends Component {
|
||||
}
|
||||
|
||||
renderConfirmation() {
|
||||
const total = Object.keys(this.cart).reduce((sum, currentKey) => {
|
||||
return sum + parseInt(this.state.items[currentKey].price) * this.cart[currentKey];
|
||||
}, 0);
|
||||
return html`
|
||||
<h3 class="side-padding-xs">Confirmation</h3>
|
||||
<div class="flex-table">
|
||||
@ -145,7 +132,7 @@ class CheckoutView extends Component {
|
||||
<div class="flex-row">
|
||||
<div class="flex-cell">
|
||||
<${SafeImg} src=${i.thumbnail}/>
|
||||
${i.name}
|
||||
${i.name || 'item'}
|
||||
</div>
|
||||
<div class="flex-cell no-flex price-cell">
|
||||
<p>
|
||||
@ -158,7 +145,7 @@ class CheckoutView extends Component {
|
||||
})}
|
||||
<div class="flex-row">
|
||||
<div class="flex-cell"></div>
|
||||
<div class="flex-cell no-flex"><b>Total ${total} €</b></div>
|
||||
<div class="flex-cell no-flex"><b>Total ${this.state.totalPrice} €</b></div>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
@ -188,7 +175,7 @@ class CheckoutView extends Component {
|
||||
<div class="main-view" id="profile">
|
||||
<div class="content">
|
||||
<p>
|
||||
<a href="/store/${this.props.id}"><iris-profile-attribute pub=${this.props.id}/></a>
|
||||
<a href="/store/${this.props.store}"><iris-profile-attribute pub=${this.props.store}/></a>
|
||||
</p>
|
||||
<div id="store-steps">
|
||||
<div class=${p === 'cart' ? 'active' : ''} onClick=${() => this.setState({page:'cart'})}>Cart</div>
|
||||
@ -206,19 +193,19 @@ class CheckoutView extends Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.id !== this.props.id) {
|
||||
if (prevProps.store !== this.props.store) {
|
||||
this.componentDidMount();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const pub = this.props.id;
|
||||
StoreView.prototype.componentDidMount.call(this);
|
||||
const pub = this.props.store;
|
||||
this.setState({page:'cart'})
|
||||
this.eventListeners.forEach(e => e.off());
|
||||
this.cart = {};
|
||||
localState.get('cart').get(pub).map().on((v, k) => {
|
||||
this.cart[k] = v;
|
||||
this.setState({cart: this.cart})
|
||||
this.setState({cart: this.cart});
|
||||
});
|
||||
localState.get('paymentMethod').on(paymentMethod => this.setState({paymentMethod}));
|
||||
localState.get('delivery').open(delivery => this.setState({delivery}));
|
||||
|
@ -15,33 +15,47 @@ import MessageFeed from './MessageFeed.js';
|
||||
import Identicon from './Identicon.js';
|
||||
import Name from './Name.js';
|
||||
import SearchBox from './SearchBox.js';
|
||||
import StoreView from './StoreView.js';
|
||||
|
||||
class ProductView extends Component {
|
||||
class ProductView extends StoreView {
|
||||
constructor() {
|
||||
super();
|
||||
this.eventListeners = [];
|
||||
this.followedUsers = new Set();
|
||||
this.followers = new Set();
|
||||
this.cart = {};
|
||||
this.state = {
|
||||
items: {
|
||||
aa: {name: 'Doge T-shirt', description: 'Amazing t shirt with doge', price: '100€'},
|
||||
bb: {name: 'Doge Mug', description: 'Wonderful mug with doge', price: '200€'},
|
||||
cc: {name: 'Iris Sticker', description: 'Very sticky stickers', price: '10€'},
|
||||
dd: {name: 'Iris virtual badge', description: 'Incredible profile badge', price: '5€'},
|
||||
ee: {name: 'Gun hosting', description: 'Top gun hosting', price: '10€ / month'}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addToCart() {
|
||||
const count = (this.cart[this.props.id] || 0) + 1;
|
||||
localState.get('cart').get(this.props.store).get(this.props.id).put(count);
|
||||
const count = (this.cart[this.props.product] || 0) + 1;
|
||||
localState.get('cart').get(this.props.store).get(this.props.product).put(count);
|
||||
}
|
||||
|
||||
showProduct() {
|
||||
newProduct() {
|
||||
return html`
|
||||
<div class="main-view" id="profile">
|
||||
<div class="content">
|
||||
<a href="/store/${Session.getPubKey()}"><iris-profile-attribute pub=${Session.getPubKey()} /></a>
|
||||
<h3>Add item</h3>
|
||||
<h2 contenteditable placeholder="Item name" onInput=${e => this.newProductName = e.target.innerText} />
|
||||
<textarea placeholder="Item description" onInput=${e => this.newProductDescription = e.target.value} style="resize: vertical"/>
|
||||
<input type="number" placeholder="Price" onInput=${e => this.newProductPrice = parseInt(e.target.value)}/>
|
||||
<hr/>
|
||||
<p>
|
||||
Item ID:
|
||||
</p>
|
||||
<p>
|
||||
<input placeholder="Item ID" onInput=${e => this.newProductId = e.target.value} />
|
||||
</p>
|
||||
<button onClick=${e => this.addItemClicked(e)}>Add item</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
const cartTotalItems = Object.values(this.cart).reduce((sum, current) => sum + current, 0);
|
||||
const i = this.state.items[this.props.id];
|
||||
const i = this.state.product;
|
||||
if (!i) return html``;
|
||||
return html`
|
||||
<div class="main-view" id="profile">
|
||||
<div class="content">
|
||||
@ -51,64 +65,52 @@ class ProductView extends Component {
|
||||
<button onClick=${() => route('/checkout/' + this.props.store)}>Shopping cart (${cartTotalItems})</button>
|
||||
</p>
|
||||
` : ''}
|
||||
<h3>${i.name}</h3>
|
||||
<${SafeImg} src=${i.thumbnail}/>
|
||||
<p class="description">${i.description}</p>
|
||||
<p class="price">${i.price}</p>
|
||||
<button class="add" onClick=${() => this.addToCart()}>
|
||||
Add to cart
|
||||
${this.cart[this.props.id] ? ` (${this.cart[this.props.id]})` : ''}
|
||||
</button>
|
||||
${this.state.product ? html`
|
||||
<h3>${i.name}</h3>
|
||||
<${SafeImg} src=${i.thumbnail}/>
|
||||
<p class="description">${i.description}</p>
|
||||
<p class="price">${i.price}</p>
|
||||
<button class="add" onClick=${() => this.addToCart()}>
|
||||
Add to cart
|
||||
${this.cart[this.props.product] ? ` (${this.cart[this.props.product]})` : ''}
|
||||
</button>
|
||||
` : ''}
|
||||
|
||||
${this.props.store && this.props.product ? '' : this.newProduct()}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
newProduct() {
|
||||
return html`<div class="main-view">add product</div>`
|
||||
}
|
||||
|
||||
render() {
|
||||
this.isMyProfile = Session.getPubKey() === this.props.id;
|
||||
const chat = chats[this.props.id];
|
||||
const uuid = chat && chat.uuid;
|
||||
const messageForm = this.isMyProfile ? html`<${MessageForm} class="hidden-xs" autofocus=${false} activeChat="public"/>` : '';
|
||||
const followable = !(this.isMyProfile || this.props.id.length < 40);
|
||||
let profilePhoto;
|
||||
if (this.isMyProfile) {
|
||||
profilePhoto = html`<${ProfilePhotoPicker} currentPhoto=${this.state.photo} placeholder=${this.props.id} callback=${src => this.onProfilePhotoSet(src)}/>`;
|
||||
} else {
|
||||
if (this.state.photo) {
|
||||
profilePhoto = html`<${SafeImg} class="profile-photo" src=${this.state.photo}/>`
|
||||
} else {
|
||||
profilePhoto = html`<${Identicon} str=${this.props.id} width=250/>`
|
||||
}
|
||||
}
|
||||
if (this.props.id && this.props.store) {
|
||||
return this.showProduct();
|
||||
}
|
||||
return this.newProduct();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.eventListeners.forEach(e => e.off());
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.id !== this.props.id) {
|
||||
if (prevProps.product !== this.props.product) {
|
||||
this.componentDidMount();
|
||||
}
|
||||
}
|
||||
|
||||
addItemClicked(e) {
|
||||
const product = {
|
||||
name: this.newProductName,
|
||||
description: this.newProductDescription,
|
||||
price: this.newProductPrice
|
||||
};
|
||||
console.log(product);
|
||||
publicState.user().get('store').get('products').get(this.newProductId).put(product);
|
||||
route(`/store/${Session.getPubKey()}`)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const pub = this.props.id;
|
||||
StoreView.prototype.componentDidMount.call(this);
|
||||
const pub = this.props.store;
|
||||
this.eventListeners.forEach(e => e.off());
|
||||
this.setState({followedUserCount: 0, followerCount: 0, name: '', photo: '', about: ''});
|
||||
this.isMyProfile = Session.getPubKey() === pub;
|
||||
this.cart = {};
|
||||
localState.get('cart').get(this.props.store).map().on((v, k) => {
|
||||
this.cart[k] = v;
|
||||
this.setState({cart: this.cart})
|
||||
});
|
||||
if (this.props.product && pub) {
|
||||
publicState.user(pub).get('store').get('products').get(this.props.product).on(product => this.setState({product}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,38 +23,31 @@ class StoreView extends Component {
|
||||
this.followedUsers = new Set();
|
||||
this.followers = new Set();
|
||||
this.cart = {};
|
||||
this.state = {
|
||||
items: {
|
||||
aa: {name: 'Doge T-shirt', description: 'Amazing t shirt with doge', price: '100€'},
|
||||
bb: {name: 'Doge Mug', description: 'Wonderful mug with doge', price: '200€'},
|
||||
cc: {name: 'Iris Sticker', description: 'Very sticky stickers', price: '10€'},
|
||||
dd: {name: 'Iris virtual badge', description: 'Incredible profile badge', price: '5€'},
|
||||
ee: {name: 'Gun hosting', description: 'Top gun hosting', price: '10€ / month'}
|
||||
}
|
||||
};
|
||||
this.state = {items:{}};
|
||||
this.items = {};
|
||||
}
|
||||
|
||||
addToCart(k, e) {
|
||||
e.stopPropagation();
|
||||
const count = (this.cart[k] || 0) + 1;
|
||||
localState.get('cart').get(this.props.id).get(k).put(count);
|
||||
localState.get('cart').get(this.props.store).get(k).put(count);
|
||||
}
|
||||
|
||||
render() {
|
||||
const cartTotalItems = Object.values(this.cart).reduce((sum, current) => sum + current, 0);
|
||||
this.isMyProfile = Session.getPubKey() === this.props.id;
|
||||
const chat = chats[this.props.id];
|
||||
this.isMyProfile = Session.getPubKey() === this.props.store;
|
||||
const chat = chats[this.props.store];
|
||||
const uuid = chat && chat.uuid;
|
||||
const messageForm = this.isMyProfile ? html`<${MessageForm} class="hidden-xs" autofocus=${false} activeChat="public"/>` : '';
|
||||
const followable = !(this.isMyProfile || this.props.id.length < 40);
|
||||
const followable = !(this.isMyProfile || this.props.store.length < 40);
|
||||
let profilePhoto;
|
||||
if (this.isMyProfile) {
|
||||
profilePhoto = html`<${ProfilePhotoPicker} currentPhoto=${this.state.photo} placeholder=${this.props.id} callback=${src => this.onProfilePhotoSet(src)}/>`;
|
||||
profilePhoto = html`<${ProfilePhotoPicker} currentPhoto=${this.state.photo} placeholder=${this.props.store} callback=${src => this.onProfilePhotoSet(src)}/>`;
|
||||
} else {
|
||||
if (this.state.photo) {
|
||||
profilePhoto = html`<${SafeImg} class="profile-photo" src=${this.state.photo}/>`
|
||||
} else {
|
||||
profilePhoto = html`<${Identicon} str=${this.props.id} width=250/>`
|
||||
profilePhoto = html`<${Identicon} str=${this.props.store} width=250/>`
|
||||
}
|
||||
}
|
||||
return html`
|
||||
@ -66,30 +59,29 @@ class StoreView extends Component {
|
||||
${profilePhoto}
|
||||
</div>
|
||||
<div class="profile-header-stuff">
|
||||
<h3 class="profile-name"><iris-profile-attribute placeholder="Name" contenteditable=${this.isMyProfile} pub=${this.props.id}/></h3>
|
||||
<h3 class="profile-name"><iris-profile-attribute placeholder="Name" contenteditable=${this.isMyProfile} pub=${this.props.store}/></h3>
|
||||
<div class="profile-about hidden-xs">
|
||||
<p class="profile-about-content">
|
||||
<iris-profile-attribute placeholder="About" contenteditable=${this.isMyProfile} attr="about" pub=${this.props.id}/>
|
||||
<iris-profile-attribute placeholder="About" contenteditable=${this.isMyProfile} attr="about" pub=${this.props.store}/>
|
||||
</p>
|
||||
</div>
|
||||
<div class="profile-actions">
|
||||
<div class="follow-count">
|
||||
<a href="/follows/${this.props.id}">
|
||||
<a href="/follows/${this.props.store}">
|
||||
<span>${this.state.followedUserCount}</span> ${t('following')}
|
||||
</a>
|
||||
<a href="/followers/${this.props.id}">
|
||||
<a href="/followers/${this.props.store}">
|
||||
<span>${this.state.followerCount}</span> ${t('known_followers')}
|
||||
</a>
|
||||
</div>
|
||||
${this.followedUsers.has(Session.getPubKey()) ? html`
|
||||
<p><small>${t('follows_you')}</small></p>
|
||||
`: ''}
|
||||
${followable ? html`<${FollowButton} id=${this.props.id}/>` : ''}
|
||||
<button onClick=${() => route('/chat/' + this.props.id)}>${t('send_message')}</button>
|
||||
${followable ? html`<${FollowButton} id=${this.props.store}/>` : ''}
|
||||
<button onClick=${() => route('/chat/' + this.props.store)}>${t('send_message')}</button>
|
||||
${uuid ? '' : html`
|
||||
<${CopyButton} text=${t('copy_link')} title=${this.state.name} copyStr=${'https://iris.to/' + window.location.hash}/>
|
||||
`}
|
||||
<button onClick=${() => $('#profile-page-qr').toggle()}>${t('show_qr_code')}</button>
|
||||
${this.isMyProfile ? '' : html`
|
||||
<button class="show-settings" onClick=${() => this.onClickSettings()}>${t('settings')}</button>
|
||||
`}
|
||||
@ -99,27 +91,25 @@ class StoreView extends Component {
|
||||
<div class="profile-about visible-xs-flex">
|
||||
<p class="profile-about-content" placeholder=${this.isMyProfile ? t('about') : ''} contenteditable=${this.isMyProfile} onInput=${e => this.onAboutInput(e)}>${this.state.about}</p>
|
||||
</div>
|
||||
|
||||
<p id="profile-page-qr" style="display:none" class="qr-container"></p>
|
||||
</div>
|
||||
|
||||
<h3>Store</h3>
|
||||
${cartTotalItems ? html`
|
||||
<p>
|
||||
<button onClick=${() => route('/checkout/' + this.props.id)}>Shopping cart (${cartTotalItems})</button>
|
||||
<button onClick=${() => route('/checkout/' + this.props.store)}>Shopping cart (${cartTotalItems})</button>
|
||||
</p>
|
||||
` : ''}
|
||||
${this.isMyProfile ? html`
|
||||
<div class="store-item" onClick=${() => route(`/product//${this.props.id}`)}>
|
||||
<a href="/product/new/${this.props.id}" class="name">Add item</a>
|
||||
<div class="store-item" onClick=${() => route(`/product/new`)}>
|
||||
<a href="/product/new" class="name">Add item</a>
|
||||
</div>
|
||||
` : ''}
|
||||
${Object.keys(this.state.items).map(k => {
|
||||
const i = this.state.items[k];
|
||||
return html`
|
||||
<div class="store-item" onClick=${() => route(`/product/${k}/${this.props.id}`)}>
|
||||
<div class="store-item" onClick=${() => route(`/product/${k}/${this.props.store}`)}>
|
||||
<${SafeImg} src=${i.thumbnail}/>
|
||||
<a href="/product/${k}/${this.props.id}" class="name">${i.name}</a>
|
||||
<a href="/product/${k}/${this.props.store}" class="name">${i.name}</a>
|
||||
<p class="description">${i.description}</p>
|
||||
<p class="price">${i.price}</p>
|
||||
<button class="add" onClick=${e => this.addToCart(k, e)}>
|
||||
@ -139,34 +129,44 @@ class StoreView extends Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.id !== this.props.id) {
|
||||
if (prevProps.store !== this.props.store) {
|
||||
this.componentDidMount();
|
||||
}
|
||||
}
|
||||
|
||||
updateTotalPrice() {
|
||||
const totalPrice = Object.keys(this.cart).reduce((sum, currentKey) => {
|
||||
const item = this.items[currentKey];
|
||||
const price = item && parseInt(item.price) || 0;
|
||||
return sum + price * this.cart[currentKey];
|
||||
}, 0);
|
||||
this.setState({totalPrice});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const pub = this.props.id;
|
||||
const pub = this.props.store;
|
||||
this.eventListeners.forEach(e => e.off());
|
||||
this.setState({followedUserCount: 0, followerCount: 0, name: '', photo: '', about: ''});
|
||||
this.setState({followedUserCount: 0, followerCount: 0, name: '', photo: '', about: '', totalPrice: 0});
|
||||
this.isMyProfile = Session.getPubKey() === pub;
|
||||
this.cart = {};
|
||||
|
||||
var qrCodeEl = $('#profile-page-qr');
|
||||
qrCodeEl.empty();
|
||||
localState.get('cart').get(this.props.id).map().on((v, k) => {
|
||||
localState.get('cart').get(this.props.store).map().on((v, k) => {
|
||||
this.cart[k] = v;
|
||||
this.setState({cart: this.cart})
|
||||
this.updateTotalPrice();
|
||||
});
|
||||
|
||||
qrCodeEl.empty();
|
||||
new QRCode(qrCodeEl[0], {
|
||||
text: 'https://iris.to/' + window.location.hash,
|
||||
width: 300,
|
||||
height: 300,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRCode.CorrectLevel.H
|
||||
});
|
||||
if (pub) {
|
||||
publicState.user(pub).get('store').get('products').map().on((p, id) => {
|
||||
if (p) {
|
||||
const o = {};
|
||||
o[id] = p;
|
||||
Object.assign(this.items, o);
|
||||
this.setState({items: this.items});
|
||||
this.updateTotalPrice();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user