import * as React from 'react' ; import { RootState , HitDatabaseEntry , WorkerHitDatabaseEntry } from 'types' ; import { connect } from 'react-redux' ; import { ResourceList , Truncate , Badge , Stack , TextStyle } from '@shopify/polaris' ; import { Text } from '@blueprintjs/core' ; import HitDbEntryCollapsible from './HitDbEntryCollapsible' ; import { generateReviewLink } from 'utils/turkopticon' ; import { generateContactLink } from 'utils/urls' ; import { formatAsUsd } from 'utils/formatting' ; import { generateHitStatusBadge } from 'utils/badges' ; interface OwnProps { readonly id : string ; readonly renderDate ? : boolean ; } interface Props { readonly hit : HitDatabaseEntry ; } interface State { readonly expanded : boolean ; } class HitDbEntry extends React . PureComponent < Props & OwnProps , State > { public readonly state : State = { expanded : false } ; componentDidUpdate ( nextProps ) { if ( nextProps . hit . id !== this . props . hit . id ) { this . setState ( ( ) => ( { expanded : false } ) ) ; } } private static displayEarnings = ( reward , bonus ) => bonus > 0 ? `${ formatAsUsd ( reward ) } + ${ formatAsUsd ( bonus ) }` : `${ formatAsUsd ( reward ) }` ; private generateActions = ( assignmentId ? ) => [ { content : 'Contact' , url : assignmentId ? generateContactLink ( this . props . hit as WorkerHitDatabaseEntry ) : undefined , external : true , disabled : this . props . hit . assignmentId ? false : true } , { content : 'Review' , url : generateReviewLink ( this . props . hit ) , external : true } ] ; private handleExpand = ( ) => { this . setState ( ( prevState ) => ( { expanded : ! prevState . expanded } ) ) ; } ; public render ( ) { const { hit } = this . props ; const { status , content } = generateHitStatusBadge ( hit . status ) ; return ( < React . Fragment > < ResourceList . Item id = { hit . id } onClick = { this . handleExpand } shortcutActions = { this . generateActions ( hit . assignmentId ) } > < Stack vertical = { false } wrap = { false } alignment = "center" > < Stack . Item > < TextStyle variation = "strong" > < Truncate > { hit . requester . name } < /Truncate> < /TextStyle> < /Stack.Item> < Stack . Item fill > < Text ellipsize > { hit . title } < /Text> < /Stack.Item> < Stack . Item > < Stack vertical = { false } > < Stack . Item > < TextStyle variation = "strong" > { HitDbEntry . displayEarnings ( hit . reward , hit . bonus ) } < /TextStyle> < /Stack.Item> < Stack . Item > < Badge status = { status } > { content } < /Badge> < /Stack.Item> < /Stack> < /Stack.Item> < /Stack> < /ResourceList.Item> < HitDbEntryCollapsible open = { this . state . expanded } { ... this . props } /> < /React.Fragment>); } } const mapState = ( state , ownProps ) : Props => ( { hit : state . hitDatabase . get ( ownProps . id ) } ) ; export default connect ( mapState ) ( HitDbEntry ) ;