/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/no-array-index-key */
import React, { Component } from 'react';
import { getDate, scrollTo, parseAmount, parseDecimal, parseSelectionTimeline } from '../../../utils/common';
import { BET_TYPES_VALUES, SVG_ICONS, DIGITS, BET_STATUS } from '../../../constants';
import Section from '../../Section';
import SVGComponent from '../../SVG/SVGComponent';
const elementId = 'coupon-detail';
/**
* @module MI-Coupons/CouponDetails
*/
/**
* @typedef {object} props
* @property {Array} selectedCoupon Selected coupon data
* @property {string} currency Currency sign
* @property {boolean} settled Is it settled
*/
export default class CouponDetails extends Component {
constructor(props) {
super(props);
this.state = {
expandedRows: {},
};
}
/**
* Scroll to coupon details view
*
* @returns {void}
*/
componentDidMount() {
scrollTo(elementId);
}
/**
* Scroll to coupon details view
*
* @param {object} nextProps
* @returns {void}
*/
// eslint-disable-next-line react/no-deprecated
componentWillUpdate(nextProps) {
if (nextProps.selectedCoupon.id !== this.props.selectedCoupon.id) {
scrollTo(elementId);
}
}
getCouponDetailsPostText = (couponDetails) => {
const couponSource = this.props.couponSource.find(
(source) => source.id.toString() === couponDetails.source.toString()
);
if (couponSource) {
return couponSource.label;
}
return '';
};
toggleRow = (rowKey, event) => {
event.stopPropagation();
this.setState((prevState) => ({
expandedRows: {
...prevState.expandedRows,
[rowKey]: !prevState.expandedRows[rowKey],
},
}));
};
is1UpSelection = (selection) => {
const selectionName = selection?.selection || '';
return selectionName.toUpperCase().includes('1UP');
};
renderTimeline = (timeline, matchString) => {
if (!timeline || timeline.length === 0) return null;
const [homeTeam = '', awayTeam = ''] = (matchString || '').split('-');
return (
<div className="match-timeline">
<div className="timeline-row timeline-header">
<div className="timeline-home">{homeTeam}</div>
<div className="timeline-time" />
<div className="timeline-away">{awayTeam}</div>
</div>
{timeline.map((event, idx) => (
<div className="timeline-row" key={idx}>
<div className={`timeline-home${event.homeHas1up ? ' has-1up' : ''}`}>
{event.homeHas1up && <span className="icon-1up" />}
{event.homeScore}
</div>
<div className="timeline-time">{event.minute}</div>
<div className={`timeline-away${event.awayHas1up ? ' has-1up' : ''}`}>
{event.awayScore}
{event.awayHas1up && <span className="icon-1up" />}
</div>
</div>
))}
</div>
);
};
getSelectionTimeline = (selection) => {
if (selection.timeline && selection.timeline.length > 0) {
return selection.timeline;
}
if (selection.goalTimeline) {
return parseSelectionTimeline(selection.goalTimeline);
}
return null;
};
// eslint-disable-next-line sonarjs/cognitive-complexity
renderSelectionRow = (selection, stake, hasStakeAndWinnings, isRoundSpecial, key, index) => {
const is1Up = this.is1UpSelection(selection);
const timeline = is1Up ? this.getSelectionTimeline(selection) : null;
const hasTimeline = timeline && timeline.length > 0;
const isExpanded = this.state.expandedRows[`selection-${index}`];
const rowClassName = `table-style-row${hasTimeline ? ' result-row' : ''}${isExpanded ? ' open' : ''}`;
return (
<tr className={rowClassName} key={key}>
<td>{isRoundSpecial ? selection.roundSpecialMarket : selection.match}</td>
<td>{selection.selection}</td>
<td>{parseDecimal(selection.odds, 1)}</td>
{this.props.settled && (
<td className={hasTimeline ? 'result-cell-expandable' : ''}>
{hasTimeline ? (
<div className="result-cell-content">
<div
className="result-expandable"
onClick={(e) => this.toggleRow(`selection-${index}`, e)}
role="button"
tabIndex={0}
onKeyDown={(e) => e.key === 'Enter' && this.toggleRow(`selection-${index}`, e)}
>
<span className="result-score">
{isRoundSpecial ? selection.roundSpecialResults : selection.results}
</span>
<div className="result-toggle">
<svg width="12" height="8" viewBox="0 0 12 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 1L6 6L11 1" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
</svg>
</div>
</div>
{isExpanded && this.renderTimeline(timeline, selection.match)}
</div>
) : (
<span>{isRoundSpecial ? selection.roundSpecialResults : selection.results}</span>
)}
</td>
)}
{this.props.settled && (
<td>
<SVGComponent
className="icon-xxs"
src={`${SVG_ICONS.utility}#${selection.status === 'W' ? 'tick' : 'cross'}`}
/>
</td>
)}
<td>{hasStakeAndWinnings && `${parseAmount(stake.stake, 100)} ${this.props.currency}`}</td>
<td>
{hasStakeAndWinnings && this.props.settled
? stake.winnings
? `${parseAmount(stake.winnings, 100)} ${this.props.currency}`
: '-'
: null}
</td>
</tr>
);
};
/**
* Render selections table
*
* @function
* @returns {view}
*/
renderSelections = () => {
const isSingle = this.props.selectedCoupon.betType === BET_TYPES_VALUES.SINGLE;
const isRoundSpecial = this.props.selectedCoupon.betType === BET_TYPES_VALUES.ROUND_SPECIAL;
const hasStakeAndWinnings = isSingle || isRoundSpecial;
return (
<div className="table-wrapper overflow-hidden pr-30 mt-20">
<span className="table-title">Selections</span>
<div className="table-responsive">
<table className="table-style table-s nbb">
<thead>
<tr>
<th>{isRoundSpecial ? 'Market' : 'Match'}</th>
<th>Selection</th>
<th>Odds</th>
{this.props.settled && <th>Results</th>}
{this.props.settled && <th>Status</th>}
<th>{hasStakeAndWinnings && 'Stake'}</th>
<th>{hasStakeAndWinnings && this.props.settled && 'Winnings'}</th>
</tr>
</thead>
<tbody>
{this.props.selectedCoupon.selections.map((selection, i) => {
const stake = this.props.selectedCoupon.stakes.find((s) => parseInt(s.bet) === i + 1);
return (stake && hasStakeAndWinnings) || !isSingle
? this.renderSelectionRow(selection, stake, hasStakeAndWinnings, isRoundSpecial, `match-${i}`, i)
: null;
})}
</tbody>
</table>
</div>
</div>
);
};
renderGGSelectionRow = (selection, stake, key) => (
<tr className="table-style-row " key={key}>
<td>{selection.extraMarket}</td>
<td>{selection.selection}</td>
{selection.odds ? <td>{selection.odds}X</td> : <td>-</td>}
{this.props.settled && (
<td>
<SVGComponent
className="icon-xxs"
src={`${SVG_ICONS.utility}#${selection.status === 'W' ? 'tick' : 'cross'}`}
/>
</td>
)}
<td>{`${parseAmount(stake.stake, 100)} ${this.props.currency}`}</td>
<td>
{this.props.settled
? stake.winnings
? `${parseAmount(stake.winnings, 100)} ${this.props.currency}`
: '-'
: null}
</td>
</tr>
);
/**
* Render gg selections table
*
* @function
* @returns {view}
*/
renderGGSelections = () =>
this.props.selectedCoupon.extraSelections &&
this.props.selectedCoupon.extraSelections.length > 0 && (
<div className="table-wrapper overflow-hidden pr-30 mt-20">
<span className="table-title">Selections</span>
<div className="table-responsive">
<table className="table-style table-s nbb">
<thead>
<tr>
<th>Market</th>
<th>Selection</th>
<th>Multiplier</th>
{this.props.settled && <th>Status</th>}
<th>Stake</th>
{this.props.settled && <th>Winnings</th>}
</tr>
</thead>
<tbody>
{this.props.selectedCoupon.extraSelections.map((selection, i) =>
this.renderGGSelectionRow(selection, this.props.selectedCoupon.extraStakes[i], `match-${i}`)
)}
</tbody>
</table>
</div>
</div>
);
/**
* Render combinations
*
* @function
* @returns {view}
*/
renderCombinations = () => {
const isCombi =
this.props.selectedCoupon.betType === BET_TYPES_VALUES.COMBINATION ||
this.props.selectedCoupon.betType === BET_TYPES_VALUES.SYSTEM;
return (
isCombi && (
<div className="table-wrapper overflow-hidden pr-30 mt-20">
<span className="table-title">Combinations</span>
<div className="table-responsive">
<table className="table-style table-s nbb">
<thead>
<tr>
<th>Bet</th>
<th>Stake</th>
<th>{this.props.settled && 'Winning'}</th>
<th>{this.props.settled && 'Status'}</th>
<th />
<th />
<th />
</tr>
</thead>
<tbody>
{this.props.selectedCoupon.stakes.map((stake) => {
const bet = stake.bet > 3 ? `${DIGITS[stake.bet - 1]} Fold` : DIGITS[stake.bet - 1];
return (
<tr className="table-style-row" key={stake.bet}>
<td>{`${bet} (${stake.coefficient})`}</td>
<td>{`${parseAmount(stake.stake, 100)} ${this.props.currency}`}</td>
<td>
{this.props.settled
? stake.winnings
? `${parseAmount(stake.winnings, 100)} ${this.props.currency}`
: '-'
: null}
</td>
{this.props.settled && (
<td>
{this.props.selectedCoupon?.status === BET_STATUS.VOIDED ? (
<span>Voided</span>
) : (
<SVGComponent
className="icon-xxs"
src={`${SVG_ICONS.utility}#${stake.status === 'W' ? 'tick' : 'cross'}`}
/>
)}
</td>
)}
</tr>
);
})}
</tbody>
</table>
</div>
</div>
)
);
};
/**
* Render
*
* @returns {view}
*/
render() {
const odds = this.props.selectedCoupon.odds.split('-');
const couponSource = this.getCouponDetailsPostText(this.props.selectedCoupon);
return (
<Section heading="Coupon details" className="has-indicator active mt-5" id={elementId}>
<div className="table-responsive mt-20">
<table className="table-style table-s">
<thead>
<tr>
<th>Bet Date</th>
<th>Coupon ID</th>
<th>Total Stake</th>
{this.props.settled && <th>Total Won Amount</th>}
<th>Odds</th>
<th>Bet Type</th>
{couponSource && <th>Cashier Type</th>}
{this.props.settled && <th>Status</th>}
</tr>
</thead>
<tbody>
<tr className="table-style-row ">
<td>{getDate(this.props.selectedCoupon.placedDate)}</td>
<td>{this.props.selectedCoupon.id}</td>
<td>{`${parseAmount(this.props.selectedCoupon.stake, 100)} ${this.props.currency}`}</td>
{this.props.settled && (
<td>
{this.props.selectedCoupon.wonAmount
? `${parseAmount(this.props.selectedCoupon.wonAmount, 100)} ${this.props.currency}`
: '-'}
</td>
)}
<td>
{parseDecimal(odds[0], 1)}
{odds[1] ? `-${parseDecimal(odds[1], 1)}` : ''}
</td>
<td>{this.props.selectedCoupon.betType}</td>
{couponSource && <td>{couponSource}</td>}
{this.props.settled && (
<td>
{
this.props.betStatus?.find(
(status) => parseInt(status.id) === parseInt(this.props.selectedCoupon.status)
)?.label
}
</td>
)}
</tr>
</tbody>
</table>
</div>
{this.props.selectedCoupon.selections &&
this.props.selectedCoupon.selections.length > 0 &&
this.renderSelections()}
{this.renderCombinations()}
{this.renderGGSelections()}
</Section>
);
}
}