forked from M-Labs/web2019
253 lines
9.7 KiB
React
253 lines
9.7 KiB
React
|
import React, {PureComponent} from 'react'
|
||
|
import PropTypes from "prop-types";
|
||
|
import {Draggable} from "react-beautiful-dnd";
|
||
|
import {OverlayTrigger} from "react-bootstrap";
|
||
|
import {DialogPopup} from "./options/DialogPopup.jsx";
|
||
|
import {nbrClocksStyle, nbrConnectorsStyle, productStyle} from "./utils";
|
||
|
|
||
|
/**
|
||
|
* Component that renders a product.
|
||
|
* Used in the crate
|
||
|
*/
|
||
|
export class ProductCartItem extends PureComponent {
|
||
|
|
||
|
static get propTypes() {
|
||
|
return {
|
||
|
isMobile: PropTypes.bool,
|
||
|
isTouch: PropTypes.bool,
|
||
|
hovered: PropTypes.bool,
|
||
|
first: PropTypes.bool,
|
||
|
last: PropTypes.bool,
|
||
|
index: PropTypes.number.isRequired,
|
||
|
model: PropTypes.object.isRequired,
|
||
|
data: PropTypes.object,
|
||
|
ext_data: PropTypes.object,
|
||
|
onToggleOverlayRemove: PropTypes.func,
|
||
|
onClickRemoveItem: PropTypes.func,
|
||
|
onClickItem: PropTypes.func,
|
||
|
onCardUpdate: PropTypes.func,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
static get defaultProps() {
|
||
|
return {
|
||
|
hovered: false,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
constructor(props) {
|
||
|
super(props);
|
||
|
this.handleOnMouseEnterRemoveItem = this.handleOnMouseEnterRemoveItem.bind(this);
|
||
|
this.handleOnMouseLeaveRemoveItem = this.handleOnMouseLeaveRemoveItem.bind(this);
|
||
|
this.handleOnClickRemoveItem = this.handleOnClickRemoveItem.bind(this);
|
||
|
this.handleOnClickItem = this.handleOnClickItem.bind(this);
|
||
|
}
|
||
|
|
||
|
handleOnMouseEnterRemoveItem(index, e) {
|
||
|
if (this.props.onToggleOverlayRemove && !this.props.isMobile) {
|
||
|
this.props.onToggleOverlayRemove(index, true);
|
||
|
}
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
|
||
|
handleOnMouseLeaveRemoveItem(index, e) {
|
||
|
if (this.props.onToggleOverlayRemove && !this.props.isMobile) {
|
||
|
this.props.onToggleOverlayRemove(index, false);
|
||
|
}
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
|
||
|
handleOnClickItem(index, e) {
|
||
|
if (this.props.onClickItem && this.props.isTouch) {
|
||
|
this.props.onClickItem(index);
|
||
|
}
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
|
||
|
handleOnClickRemoveItem(index, e) {
|
||
|
if (this.props.onClickRemoveItem) {
|
||
|
this.props.onClickRemoveItem(index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
render() {
|
||
|
const {
|
||
|
hovered,
|
||
|
model,
|
||
|
data,
|
||
|
index,
|
||
|
first,
|
||
|
last,
|
||
|
ext_data,
|
||
|
onCardUpdate,
|
||
|
} = this.props;
|
||
|
|
||
|
let warning, options, options_data;
|
||
|
if (data && data.warnings) {
|
||
|
const warningsKeys = Object.keys(data.warnings);
|
||
|
if (warningsKeys && warningsKeys.length > 0) {
|
||
|
// we display only the first warning
|
||
|
warning = data.warnings[warningsKeys[0]];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
if (data && data.options) {
|
||
|
options = data.options;
|
||
|
if (!data.options_data) data.options_data = {};
|
||
|
options_data = data.options_data;
|
||
|
options_data.ext_data = ext_data;
|
||
|
}
|
||
|
|
||
|
let render_progress;
|
||
|
if (data) {
|
||
|
switch(model.type) {
|
||
|
case 'kasli':
|
||
|
render_progress = [
|
||
|
(<p key={model.type+model.id+"EEM"}>{`${data.nbrCurrentSlot}/${model.nbrSlotMax} EEM connectors used`}</p>),
|
||
|
(<p key={model.type+model.id+"CLK"}>{`${data.nbrCurrentClock}/${model.nbrClockMax} Clock connectors used`}</p>)
|
||
|
];
|
||
|
break;
|
||
|
|
||
|
case 'vhdcicarrier':
|
||
|
render_progress = (<p>{`${data.nbrCurrentSlot}/${model.nbrSlotMax} EEM connectors used`}</p>);
|
||
|
break;
|
||
|
|
||
|
case 'zotino':
|
||
|
case 'hd68':
|
||
|
render_progress = (<p>{`${data.nbrCurrentSlot}/${model.nbrSlotMax} connectors used`}</p>);
|
||
|
break;
|
||
|
|
||
|
case 'clocker':
|
||
|
render_progress = (<p>{`${data.nbrCurrentClock}/${model.nbrClockMax} Clock connectors used`}</p>);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<Draggable draggableId={model.id} index={index}>
|
||
|
|
||
|
{(provided, snapshot) => (
|
||
|
<div
|
||
|
ref={provided.innerRef}
|
||
|
{...provided.draggableProps}
|
||
|
{...provided.dragHandleProps}
|
||
|
style={{ ...productStyle(
|
||
|
provided.draggableProps.style,
|
||
|
snapshot,
|
||
|
true,
|
||
|
!!hovered,
|
||
|
!!model.selected,
|
||
|
true
|
||
|
)}}
|
||
|
onMouseEnter={this.handleOnMouseEnterRemoveItem.bind(this, index)}
|
||
|
onMouseLeave={this.handleOnMouseLeaveRemoveItem.bind(this, index)}
|
||
|
>
|
||
|
|
||
|
{/* warning container */}
|
||
|
|
||
|
<div className="progress-container warning d-flex justify-content-evenly">
|
||
|
{warning &&
|
||
|
(<OverlayTrigger
|
||
|
placement="bottom"
|
||
|
trigger={['click', 'hover', 'focus']}
|
||
|
overlay={
|
||
|
({arrowProps, hasDoneInitialMeasure, show, ...props}) => (
|
||
|
<div className="k-popup-warning" {...props}>
|
||
|
<p className="rule warning">
|
||
|
<i>{warning.message}</i>
|
||
|
</p>
|
||
|
</div>)
|
||
|
}
|
||
|
rootClose
|
||
|
>
|
||
|
<img className="alert-warning" src={`/images${warning.icon}`}/>
|
||
|
</OverlayTrigger>)
|
||
|
}
|
||
|
|
||
|
{options && (
|
||
|
<DialogPopup
|
||
|
options={options}
|
||
|
data={options_data}
|
||
|
options_class={model.options_class}
|
||
|
key={"popover" + index}
|
||
|
id={"popover" + index}
|
||
|
big={model.size === "big"}
|
||
|
first={first}
|
||
|
last={last}
|
||
|
target={{
|
||
|
construct: ((outvar, value) => {
|
||
|
// console.log("construct", outvar, value, options_data);
|
||
|
options_data[outvar] = value;
|
||
|
}),
|
||
|
update: ((outvar, value) => {
|
||
|
// console.log("update", outvar, value, options_data);
|
||
|
if (outvar in options_data) options_data[outvar] = value;
|
||
|
onCardUpdate();
|
||
|
})
|
||
|
}}
|
||
|
/>
|
||
|
)}
|
||
|
</div>
|
||
|
|
||
|
<h6>{model.name_number}</h6>
|
||
|
|
||
|
<div
|
||
|
onMouseEnter={this.handleOnMouseEnterRemoveItem.bind(this, index)}
|
||
|
onClick={this.handleOnClickItem.bind(this, index)}
|
||
|
>
|
||
|
|
||
|
<img
|
||
|
className='item-cart'
|
||
|
src={`/images${model.image}`} />
|
||
|
</div>
|
||
|
|
||
|
{/* remove container */}
|
||
|
<div
|
||
|
style={{'display': model.showOverlayRemove ? 'flex':'none'}}
|
||
|
className="overlayRemove"
|
||
|
onClick={this.handleOnClickRemoveItem.bind(this, index)}>
|
||
|
|
||
|
<img src="/images/shop/icon-remove.svg" alt="rm"/>
|
||
|
|
||
|
<p>Remove</p>
|
||
|
</div>
|
||
|
|
||
|
{/* progression container */}
|
||
|
{render_progress && (
|
||
|
<OverlayTrigger
|
||
|
placement="top"
|
||
|
trigger={['click', 'hover', 'focus']}
|
||
|
overlay={({arrowProps, hasDoneInitialMeasure, show, ...props}) => (<div className="k-popup-connectors" {...props}>{render_progress}</div>)}
|
||
|
rootClose
|
||
|
>
|
||
|
<div className="progress-container">
|
||
|
|
||
|
{model.nbrSlotMax > 0 && (
|
||
|
<div className="nbr-connectors">
|
||
|
<div style={{ ...nbrConnectorsStyle(data)}}></div>
|
||
|
</div>
|
||
|
)}
|
||
|
|
||
|
{model.nbrClockMax > 0 && (
|
||
|
<div className="nbr-clocks">
|
||
|
<div style={{ ...nbrClocksStyle(data)}}></div>
|
||
|
</div>
|
||
|
)}
|
||
|
</div>
|
||
|
</OverlayTrigger>
|
||
|
)}
|
||
|
|
||
|
|
||
|
</div>
|
||
|
)}
|
||
|
|
||
|
</Draggable>
|
||
|
);
|
||
|
}
|
||
|
}
|