diff --git a/src/components/ChallengeEditor/ChallengeReviewer-Field/AiReviewerTab/utils.js b/src/components/ChallengeEditor/ChallengeReviewer-Field/AiReviewerTab/utils.js
index a9b2b134..9fd84ab9 100644
--- a/src/components/ChallengeEditor/ChallengeReviewer-Field/AiReviewerTab/utils.js
+++ b/src/components/ChallengeEditor/ChallengeReviewer-Field/AiReviewerTab/utils.js
@@ -4,3 +4,7 @@ export const isAIReviewer = (reviewer) => {
(reviewer.isMemberReview === false)
)
}
+
+export const hasAiReviewers = (reviewers) => {
+ return Array.isArray(reviewers) && reviewers.some(isAIReviewer)
+}
diff --git a/src/components/ChallengeEditor/ChallengeView/index.js b/src/components/ChallengeEditor/ChallengeView/index.js
index 8637bd6a..97764ef9 100644
--- a/src/components/ChallengeEditor/ChallengeView/index.js
+++ b/src/components/ChallengeEditor/ChallengeView/index.js
@@ -26,9 +26,11 @@ import {
DEV_TRACK_ID,
MARATHON_TYPE_ID,
CHALLENGE_TYPE_ID,
- COMMUNITY_APP_URL
+ COMMUNITY_APP_URL,
+ AI_SCREENING_PHASE_NAME
} from '../../../config/constants'
import PhaseInput from '../../PhaseInput'
+import { hasAiReviewers } from '../ChallengeReviewer-Field/AiReviewerTab/utils'
import CheckpointPrizesField from '../CheckpointPrizes-Field'
import { isBetaMode } from '../../../util/localstorage'
import WiproAllowedField from '../WiproAllowedField'
@@ -224,21 +226,41 @@ const ChallengeView = ({
{
- challenge.legacy.subTrack === 'WEB_DESIGNS' && challenge.phases.length === 8 ? phases.map((phase, index) => (
-
- )) : _.sortBy(phases, ['scheduledEndDate']).map((phase, index) => (
-
- ))
+ (() => {
+ const phaseList = challenge.legacy.subTrack === 'WEB_DESIGNS' && challenge.phases.length === 8
+ ? phases
+ : _.sortBy(phases, ['scheduledEndDate'])
+ const hasRealAiScreeningPhase = phaseList.some(p => p.name === AI_SCREENING_PHASE_NAME)
+ const showVirtualAiScreening = hasAiReviewers(challenge.reviewers) && !hasRealAiScreeningPhase
+ const submissionIndex = phaseList.findIndex(p => p.name === 'Submission')
+ return (
+ <>
+ {phaseList.map((phase, index) => (
+
+
+ {showVirtualAiScreening && index === submissionIndex && (
+
+ )}
+
+ ))}
+ {showVirtualAiScreening && submissionIndex === -1 && (
+
+ )}
+ >
+ )
+ })()
}
{showTimeline && (
{
- phases.map((phase, index) => (
- {
- this.onUpdatePhaseDate(item, index)
- }}
- />
- )
- )
+ (() => {
+ const hasRealAiScreeningPhase = phases.some(p => p.name === AI_SCREENING_PHASE_NAME)
+ const showVirtualAiScreening = hasAiReviewers(challenge.reviewers) && !hasRealAiScreeningPhase
+ const submissionIndex = phases.findIndex(p => p.name === 'Submission')
+ return (
+ <>
+ {phases.map((phase, index) => (
+
+ {
+ this.onUpdatePhaseDate(item, index)
+ }}
+ />
+ {showVirtualAiScreening && index === submissionIndex && (
+
+ )}
+
+ ))}
+ {showVirtualAiScreening && submissionIndex === -1 && (
+
+ )}
+ >
+ )
+ })()
}
>
)}
diff --git a/src/components/PhaseInput/index.js b/src/components/PhaseInput/index.js
index 7c362563..3cd7c239 100644
--- a/src/components/PhaseInput/index.js
+++ b/src/components/PhaseInput/index.js
@@ -14,12 +14,39 @@ const inputDateFormat = 'MM/dd/yyyy'
const inputTimeFormat = 'HH:mm'
const MAX_LENGTH = 5
-const PhaseInput = ({ onUpdatePhase, phase, readOnly, phaseIndex }) => {
+const PhaseInput = ({ onUpdatePhase, phase, readOnly, phaseIndex, isVirtual }) => {
const { scheduledStartDate: startDate, scheduledEndDate: endDate, duration, isStartTimeActive, isDurationActive } = phase
const durationHoursMinutes = useMemo(() => getPhaseHoursMinutes(duration), [duration])
const endDateInputRef = useRef()
+ useEffect(() => {
+ if (!startDate && onUpdatePhase && !isVirtual) {
+ let startDate = moment().format(dateFormat)
+ let endDate = getPhaseEndDate(startDate, duration)
+ onUpdatePhase({
+ startDate,
+ endDate,
+ duration
+ })
+ }
+ }, [startDate])
+
+ if (isVirtual && readOnly) {
+ return (
+
+
+
+
+
+
+ Automated (AI)
+
+
+
+ )
+ }
+
const onStartDateChange = (e) => {
let startDate = moment(e).format(dateFormat)
let endDate = getPhaseEndDate(startDate, duration)
@@ -44,18 +71,6 @@ const PhaseInput = ({ onUpdatePhase, phase, readOnly, phaseIndex }) => {
}
}
- useEffect(() => {
- if (!startDate && onUpdatePhase) {
- let startDate = moment().format(dateFormat)
- let endDate = getPhaseEndDate(startDate, duration)
- onUpdatePhase({
- startDate,
- endDate,
- duration
- })
- }
- }, [startDate])
-
const onDurationChange = (e, isBlur = false) => {
if (`${e}`.length > MAX_LENGTH) return null
@@ -144,13 +159,16 @@ const PhaseInput = ({ onUpdatePhase, phase, readOnly, phaseIndex }) => {
PhaseInput.defaultProps = {
endDate: null,
- readOnly: false
+ readOnly: false,
+ isVirtual: false,
+ phaseIndex: -1
}
PhaseInput.propTypes = {
phase: PropTypes.shape().isRequired,
onUpdatePhase: PropTypes.func,
readOnly: PropTypes.bool,
- phaseIndex: PropTypes.number.isRequired
+ phaseIndex: PropTypes.number,
+ isVirtual: PropTypes.bool
}
export default PhaseInput
diff --git a/src/config/constants.js b/src/config/constants.js
index 59b422ca..ef3b852d 100644
--- a/src/config/constants.js
+++ b/src/config/constants.js
@@ -56,6 +56,7 @@ export const SKILLS_OPTIONAL_BILLING_ACCOUNT_IDS = ['80000062']
*/
export const AI_WORKFLOW_POLL_INTERVAL = 1000 // 1 second in milliseconds
export const AI_WORKFLOW_POLL_TIMEOUT = 5 * 60000 // 5 * 60 seconds in milliseconds
+export const AI_SCREENING_PHASE_NAME = 'AI Screening'
/**
* Filepicker config