Skip to content

Commit

Permalink
Merge pull request #1107 from topcoder-platform/develop
Browse files Browse the repository at this point in the history
Prod release - 0.6.0
  • Loading branch information
vikasrohit authored Mar 11, 2021
2 parents 50d1664 + 3276c95 commit 15ee107
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 71 deletions.
5 changes: 3 additions & 2 deletions src/actions/challenges.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,10 @@ export function createChallenge (challengeDetails) {
type: CREATE_CHALLENGE_SUCCESS,
challengeDetails: challenge
})
}).catch(() => {
}).catch((e) => {
dispatch({
type: CREATE_CHALLENGE_FAILURE
type: CREATE_CHALLENGE_FAILURE,
error: e
})
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
display: flex;
flex-direction: row;
flex-wrap: wrap;
min-width: 280px;
}
}

Expand Down
21 changes: 19 additions & 2 deletions src/components/ChallengeEditor/ChallengeEditor.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
span {
color: $tc-red;
}

}

.textRequired {
Expand Down Expand Up @@ -211,6 +212,18 @@
}
}
}

.templateLink {
text-align: center;
font-size: 14px;
line-height: 29px;
font-weight: 400;

a {
font-weight: 400;
font-size: 12px;
}
}
}
.group:last-of-type {
margin-bottom: 0;
Expand All @@ -232,10 +245,13 @@
}

.error {
text-align: right;
padding-right: 40px;
padding-bottom: 20px;
color: $tc-red
color: $tc-red;

.errorMessage {
font-size: 25px;
}
}

.actionButtons {
Expand Down Expand Up @@ -332,6 +348,7 @@
line-height: 36px;
margin-bottom: 30px;
margin-top: 0;

}

span {
Expand Down
143 changes: 99 additions & 44 deletions src/components/ChallengeEditor/ChallengePrizes-Field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import PrizeInput from '../../PrizeInput'
import styles from './ChallengePrizes-Field.module.scss'
import cn from 'classnames'
import { PrimaryButton } from '../../Buttons'
import { CHALLENGE_PRIZE_TYPE, VALIDATION_VALUE_TYPE, PRIZE_SETS_TYPE, CHALLENGE_TYPES_WITH_MULTIPLE_PRIZES } from '../../../config/constants'
import {
CHALLENGE_PRIZE_TYPE,
VALIDATION_VALUE_TYPE,
PRIZE_SETS_TYPE,
CHALLENGE_TYPES_WITH_MULTIPLE_PRIZES
} from '../../../config/constants'
import { validateValue } from '../../../util/input-check'

class ChallengePrizesField extends Component {
Expand All @@ -26,7 +31,10 @@ class ChallengePrizesField extends Component {

addNewPrize () {
const challengePrize = this.getChallengePrize()
challengePrize.prizes = [...challengePrize.prizes, { type: CHALLENGE_PRIZE_TYPE.USD, value: 1 }]
challengePrize.prizes = [
...challengePrize.prizes,
{ type: CHALLENGE_PRIZE_TYPE.USD, value: 1 }
]
this.onUpdateValue(challengePrize)
}

Expand All @@ -38,7 +46,10 @@ class ChallengePrizesField extends Component {

onUpdateInput (value, index) {
const challengePrize = this.getChallengePrize()
challengePrize.prizes[index].value = validateValue(value, VALIDATION_VALUE_TYPE.INTEGER)
challengePrize.prizes[index].value = validateValue(
value,
VALIDATION_VALUE_TYPE.INTEGER
)
if (parseInt(challengePrize.prizes[index].value) > 1000000) {
challengePrize.prizes[index].value = '1000000'
}
Expand All @@ -48,71 +59,115 @@ class ChallengePrizesField extends Component {
onUpdateValue (challengePrize) {
const type = PRIZE_SETS_TYPE.CHALLENGE_PRIZES
const { onUpdateOthers, challenge } = this.props
const existingPrizes = challenge.prizeSets ? challenge.prizeSets.filter(p => p.type !== type) : []
const existingPrizes = challenge.prizeSets
? challenge.prizeSets.filter(p => p.type !== type)
: []

onUpdateOthers({ field: 'prizeSets', value: [...existingPrizes, challengePrize] })
onUpdateOthers({
field: 'prizeSets',
value: [...existingPrizes, challengePrize]
})
}

getChallengePrize () {
const type = PRIZE_SETS_TYPE.CHALLENGE_PRIZES
return (this.props.challenge.prizeSets && this.props.challenge.prizeSets.length && this.props.challenge.prizeSets.find(p => p.type === type)) || { type, prizes: [{ type: CHALLENGE_PRIZE_TYPE.USD, value: 0 }] }
return (
(this.props.challenge.prizeSets &&
this.props.challenge.prizeSets.length &&
this.props.challenge.prizeSets.find(p => p.type === type)) || {
type,
prizes: [{ type: CHALLENGE_PRIZE_TYPE.USD, value: 0 }]
}
)
}

renderPrizes () {
const { currentPrizeIndex } = this.state
const { readOnly, challenge } = this.props
const allowMultiplePrizes = _.includes(CHALLENGE_TYPES_WITH_MULTIPLE_PRIZES, challenge.type)
return _.map(this.getChallengePrize().prizes, (prize, index, { length }) => (
<div key={`${index}-${prize.amount}-edit`}>
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)}>
<label htmlFor={`${index}-prize`}>Prize {allowMultiplePrizes ? index + 1 : ''} {!readOnly && (<span>*</span>)}:</label>
</div>
{readOnly ? (
<span>${prize.value}</span>
) : (<div className={cn(styles.field, styles.col2)}>
<PrizeInput
prize={prize}
isFocus={index === currentPrizeIndex}
onUpdateInput={this.onUpdateInput}
index={index} activeIndex={currentPrizeIndex} />
{
index > 0 && (
<div className={styles.icon} onClick={() => this.removePrize(index)}>
<FontAwesomeIcon icon={faTrash} />
const allowMultiplePrizes = _.includes(
CHALLENGE_TYPES_WITH_MULTIPLE_PRIZES,
challenge.type
)
return _.map(
this.getChallengePrize().prizes,
(prize, index, { length }) => {
let errMessage = ''
if (prize.value === '') {
errMessage = 'Prize amount is required field'
} else if (+prize.value <= 0 || +prize.value > 1000000) {
errMessage =
'Prize amount must be more than 0 and no more than 1000000'
} else if (index > 0) {
const prePrize = this.getChallengePrize().prizes[index - 1]
if (+prePrize.value < +prize.value) {
errMessage =
'Prize for the higher place cannot be bigger than for lower place'
}
}
return (
<div key={`${index}-${prize.amount}-edit`}>
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)}>
<label htmlFor={`${index}-prize`}>
Prize {allowMultiplePrizes ? index + 1 : ''}{' '}
{!readOnly && <span>*</span>}:
</label>
</div>
{readOnly ? (
<span>${prize.value}</span>
) : (
<div className={cn(styles.field, styles.col2)}>
<PrizeInput
prize={prize}
isFocus={index === currentPrizeIndex}
onUpdateInput={this.onUpdateInput}
index={index}
activeIndex={currentPrizeIndex}
/>
{index > 0 && (
<div
className={styles.icon}
onClick={() => this.removePrize(index)}
>
<FontAwesomeIcon icon={faTrash} />
</div>
)}
</div>
)
}
</div>)}
</div>
{!readOnly && challenge.submitTriggered && (prize.value === '' || (+prize.value <= 0 || +prize.value > 1000000)) && (
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)} />
<div className={cn(styles.field, styles.col2, styles.error)}>
{prize.value === ''
? 'Prize amount is required field'
: 'Prize amount must be more than 0 and no more than 1000000'}
)}
</div>
{!readOnly && challenge.submitTriggered && errMessage && (
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)} />
<div className={cn(styles.field, styles.col2, styles.error)}>
{errMessage}
</div>
</div>
)}
</div>
)}
</div>
))
)
}
)
}

render () {
const { readOnly, challenge } = this.props
const allowMultiplePrizes = _.includes(CHALLENGE_TYPES_WITH_MULTIPLE_PRIZES, challenge.type)
const allowMultiplePrizes = _.includes(
CHALLENGE_TYPES_WITH_MULTIPLE_PRIZES,
challenge.type
)
return (
<div className={styles.container}>
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)}>
<label htmlFor={`challengePrizes`}>Challenge Prizes :</label>
</div>
</div>
{ this.renderPrizes() }
{!readOnly && allowMultiplePrizes && (<div className={styles.button} onClick={this.addNewPrize}>
<PrimaryButton text={'Add New Prize'} type={'info'} />
</div>)}
{this.renderPrizes()}
{!readOnly && allowMultiplePrizes && (
<div className={styles.button} onClick={this.addNewPrize}>
<PrimaryButton text={'Add New Prize'} type={'info'} />
</div>
)}
</div>
)
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/ChallengeEditor/TextEditor-Field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class TextEditorField extends Component {
</div>)}
{shouldShowPrivateDescription && showShowPrivateDescriptionField && (<div className={styles.title}>
<span>Private specification</span>
{!readOnly && (<div>
<i>Access specification templates <a href='https://github.com/topcoder-platform-templates/specification-templates' target='_blank'>here</a></i>
</div>)}
<i>
This text will only be visible to Topcoder members that have
registered for this challenge
Expand Down
13 changes: 12 additions & 1 deletion src/components/ChallengeEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -677,14 +677,19 @@ class ChallengeEditor extends Component {
return false
}

return _.every(challengePrizes.prizes, (prize) => {
return _.every(challengePrizes.prizes, (prize, index) => {
if (prize.value === '') {
return false
}
const prizeNumber = parseInt(prize.value)
if (prizeNumber <= 0 || prizeNumber > 1000000) {
return false
}
if (index > 0) {
if (+prize.value > +challengePrizes.prizes[index - 1].value) {
return false
}
}
return true
})
}
Expand Down Expand Up @@ -1157,6 +1162,7 @@ class ChallengeEditor extends Component {
token,
removeAttachment,
failedToLoad,
errorMessage,
projectDetail,
attachments
} = this.props
Expand Down Expand Up @@ -1184,6 +1190,7 @@ class ChallengeEditor extends Component {
<div className={styles.group}>
<div className={styles.row}>
<div className={styles.error}>
{errorMessage && <div className={styles.errorMessage}>{`Error : ${errorMessage}`}</div>}
Please try again later and if the issue persists contact us at&nbsp;
<a href='mailto:support@topcoder.com'>support@topcoder.com</a>
&nbsp;to resolve the issue as soon as possible.
Expand Down Expand Up @@ -1478,6 +1485,9 @@ class ChallengeEditor extends Component {
</div>
<div className={styles.group}>
<div className={styles.title}>Public specification <span>*</span></div>
<div className={styles.templateLink}>
<i>Access specification templates <a href='https://github.com/topcoder-platform-templates/specification-templates' target='_blank'>here</a></i>
</div>
<TextEditorField
challengeTags={metadata.challengeTags}
challenge={challenge}
Expand Down Expand Up @@ -1554,6 +1564,7 @@ ChallengeEditor.propTypes = {
attachments: PropTypes.arrayOf(PropTypes.shape()),
token: PropTypes.string.isRequired,
failedToLoad: PropTypes.bool,
errorMessage: PropTypes.string,
history: PropTypes.any.isRequired,
assignedMemberDetails: PropTypes.shape(),
updateChallengeDetails: PropTypes.func.isRequired,
Expand Down
Loading

0 comments on commit 15ee107

Please sign in to comment.