web2019/static/js/shop/OrderSummary.jsx
Egor Savkin 94f321ecf7 Minimal summary and crate mode
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-01-09 10:14:53 +08:00

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',
}}>&nbsp;</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',
}}>&nbsp;</span>
))}
{((options && options_data) ? (
<SummaryPopup id={item.id + "options"} options={options} data={options_data} />
) : (
<span style={{
'display': 'inline-block',
'width': '20px',
}}>&nbsp;</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',
}}>&nbsp;</span>
</td>
</tr>
</tfoot>
</table>
</div>
);
}
}