forked from M-Labs/web2019
190 lines
8.1 KiB
JavaScript
190 lines
8.1 KiB
JavaScript
import React, {PureComponent} from 'react';
|
|
import PropTypes from "prop-types";
|
|
import {SummaryPopup} from "./options/SummaryPopup.jsx";
|
|
import {formatMoney} from "./utils";
|
|
import {WarningIndicator} from "./CardWarnings.jsx";
|
|
import {total_order_price} from "./count_resources";
|
|
import {data as shared_data} from "./utils";
|
|
|
|
/**
|
|
* Components that displays the list of card that are used in the crate.
|
|
* It is a summary of purchase
|
|
*/
|
|
export class OrderSummary extends PureComponent {
|
|
|
|
static get propTypes() {
|
|
return {
|
|
currency: PropTypes.string,
|
|
crates: PropTypes.object,
|
|
onDeleteItem: PropTypes.func,
|
|
onDeleteAllItems: PropTypes.func,
|
|
onMouseEnterItem: PropTypes.func,
|
|
onMouseLeaveItem: PropTypes.func,
|
|
onClickSelectItem: PropTypes.func,
|
|
};
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
this.handleOnDeleteItem = this.handleOnDeleteItem.bind(this);
|
|
this.handleOnDeleteAllItems = this.handleOnDeleteAllItems.bind(this);
|
|
this.handleOnMouseEnterItem = this.handleOnMouseEnterItem.bind(this);
|
|
this.handleOnMouseLeaveItem = this.handleOnMouseLeaveItem.bind(this);
|
|
this.handleOnClickSelectItem = this.handleOnClickSelectItem.bind(this);
|
|
}
|
|
|
|
handleOnDeleteItem(index, e) {
|
|
if (this.props.onDeleteItem) {
|
|
this.props.onDeleteItem(index);
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
|
|
handleOnDeleteAllItems(e) {
|
|
if (this.props.onDeleteAllItems) {
|
|
this.props.onDeleteAllItems();
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
|
|
handleOnMouseEnterItem(id, e) {
|
|
if (this.props.onMouseEnterItem) {
|
|
this.props.onMouseEnterItem(id);
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
|
|
handleOnMouseLeaveItem(e) {
|
|
if (this.props.onMouseLeaveItem) {
|
|
this.props.onMouseLeaveItem();
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
|
|
handleOnClickSelectItem(index, e) {
|
|
if (e.target.tagName !== 'IMG') {
|
|
if (this.props.onClickSelectItem) {
|
|
this.props.onClickSelectItem(index);
|
|
}
|
|
}
|
|
return e.preventDefault();
|
|
}
|
|
|
|
render() {
|
|
const {
|
|
currency,
|
|
crates
|
|
} = this.props;
|
|
|
|
const total_price = total_order_price(crates);
|
|
|
|
return (
|
|
<div className="summary-price">
|
|
|
|
<table>
|
|
|
|
<thead>
|
|
<tr>
|
|
<td colSpan="2" className="summary-remove-all">
|
|
<span className="item-card-name">Remove all cards</span>
|
|
|
|
<button onClick={this.handleOnDeleteAllItems}>
|
|
<img src="/images/shop/icon-remove.svg" />
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</thead>
|
|
|
|
{Object.entries(crates).map(([crate_id, crate], _i) => {
|
|
let crate_type = shared_data.crateModes[crate.crate_type];
|
|
return (
|
|
<tbody key={"summary_crate_body"+crate_id}>
|
|
<tr key={"summary_crate_"+crate_id}>
|
|
<td className="item-card-name">{crate_type.name}</td>
|
|
<td className="price">
|
|
<div>
|
|
{`${currency} ${formatMoney(crate_type.price)}`}
|
|
|
|
<button style={{'opacity': '0', 'cursor': 'initial'}}>
|
|
<img src="/images/shop/icon-remove.svg" />
|
|
</button>
|
|
</div>
|
|
|
|
<span style={{
|
|
'display': 'inline-block',
|
|
'width': '30px',
|
|
}}> </span>
|
|
</td>
|
|
</tr>
|
|
{crate.items.map((item, index) => {
|
|
let options = item && item.options;
|
|
let options_data = item && item.options_data;
|
|
const warnings = item && item.show_warnings;
|
|
|
|
return (<tr key={"summary_crate_" + crate_id+item.id}
|
|
className={`hoverable ${item.selected ? 'selected' : ''}`}
|
|
onClick={this.handleOnClickSelectItem.bind(this, index)}
|
|
onMouseEnter={this.handleOnMouseEnterItem.bind(this, item.id)}
|
|
onMouseLeave={this.handleOnMouseLeaveItem}>
|
|
<td className="item-card-name">
|
|
<div>{`${item.name_number} ${item.name} ${item.name_codename}`}</div>
|
|
</td>
|
|
|
|
<td className="price">
|
|
<div className="d-inline-flex align-content-center">
|
|
{`${currency} ${formatMoney(item.price)}`}
|
|
|
|
<button onClick={this.handleOnDeleteItem.bind(this, index)}>
|
|
<img src="/images/shop/icon-remove.svg" />
|
|
</button>
|
|
|
|
<div style={{'width': '45px', 'height': '20px'}} className="d-inline-flex align-content-center align-self-center justify-content-evenly">
|
|
{(warnings && warnings.length > 0 ? (
|
|
<WarningIndicator warnings={warnings}/>
|
|
) : (
|
|
<span style={{
|
|
'display': 'inline-block',
|
|
'width': '20px',
|
|
}}> </span>
|
|
))}
|
|
{((options && options_data) ? (
|
|
<SummaryPopup id={item.id + "options"} options={options} data={options_data} />
|
|
) : (
|
|
<span style={{
|
|
'display': 'inline-block',
|
|
'width': '20px',
|
|
}}> </span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>);
|
|
})}
|
|
</tbody>
|
|
)})}
|
|
|
|
<tfoot>
|
|
<tr>
|
|
<td className="item-card-name">Price estimate</td>
|
|
<td className="price">
|
|
<div>
|
|
${currency} ${formatMoney(total_price)}
|
|
<button style={{'opacity': '0', 'cursor': 'initial'}}>
|
|
<img src="/images/shop/icon-remove.svg" alt="icon remove"/>
|
|
</button>
|
|
</div>
|
|
|
|
<span style={{
|
|
'display': 'inline-block',
|
|
'width': '30px',
|
|
}}> </span>
|
|
</td>
|
|
</tr>
|
|
</tfoot>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
);
|
|
}
|
|
} |