diff --git a/.gitignore b/.gitignore index c4b8ad9b..9bafbdb2 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ yarn-debug.log* yarn-error.log* *.env - +*.pem *.vscode # e2e test case diff --git a/config/constants/development.js b/config/constants/development.js index e418af3c..e06c0902 100644 --- a/config/constants/development.js +++ b/config/constants/development.js @@ -19,11 +19,9 @@ module.exports = { CHALLENGE_TRACKS_URL: `${DEV_API_HOSTNAME}/v5/challenge-tracks`, CHALLENGE_PHASES_URL: `${DEV_API_HOSTNAME}/v5/challenge-phases`, CHALLENGE_TIMELINES_URL: `${DEV_API_HOSTNAME}/v5/challenge-timelines`, - COPILOTS_URL: `https://copilots.${DOMAIN}`, PROJECT_API_URL: `${DEV_API_HOSTNAME}/v5/projects`, GROUPS_API_URL: `${DEV_API_HOSTNAME}/v5/groups`, TERMS_API_URL: `${DEV_API_HOSTNAME}/v5/terms`, - MEMBERS_API_URL: `${DEV_API_HOSTNAME}/v5/members`, RESOURCES_API_URL: `${DEV_API_HOSTNAME}/v5/resources`, RESOURCE_ROLES_API_URL: `${DEV_API_HOSTNAME}/v5/resource-roles`, SUBMISSIONS_API_URL: `${DEV_API_HOSTNAME}/v5/submissions`, diff --git a/package-lock.json b/package-lock.json index 60545c25..a5aedfe4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3280,30 +3280,6 @@ "@types/unist": "*" } }, - "@types/hoist-non-react-statics": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", - "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - } - } - }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, "@types/katex": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.11.1.tgz", @@ -3367,10 +3343,10 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, - "@types/react": { - "version": "19.0.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", - "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "requires": { "csstype": "^3.0.2" }, @@ -5909,11 +5885,6 @@ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, - "codemirror": { - "version": "5.65.18", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.18.tgz", - "integrity": "sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==" - }, "codemirror-spell-checker": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/codemirror-spell-checker/-/codemirror-spell-checker-1.1.2.tgz", @@ -8940,60 +8911,9 @@ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" }, "formidable": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", - "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", - "requires": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0", - "qs": "^6.11.0" - }, - "dependencies": { - "qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "requires": { - "side-channel": "^1.1.0" - } - } - } - }, - "formik": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", - "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.1", - "deepmerge": "^2.1.1", - "hoist-non-react-statics": "^3.3.0", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "react-fast-compare": "^2.0.1", - "tiny-warning": "^1.0.2", - "tslib": "^2.0.0" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" }, "forwarded": { "version": "0.1.2", diff --git a/src/components/ChallengeEditor/ChallengeName-Field/index.js b/src/components/ChallengeEditor/ChallengeName-Field/index.js index 4b4feebb..470bb7e7 100644 --- a/src/components/ChallengeEditor/ChallengeName-Field/index.js +++ b/src/components/ChallengeEditor/ChallengeName-Field/index.js @@ -4,22 +4,47 @@ import styles from './ChallengeName-Field.module.scss' import cn from 'classnames' const ChallengeNameField = ({ challenge, onUpdateInput }) => { + const handleChange = (e) => { + // Remove any characters that are NOT letters, numbers, or spaces + const sanitizedValue = e.target.value.replace(/[^a-zA-Z0-9 ]/g, '') + onUpdateInput({ + target: { + name: e.target.name, + value: sanitizedValue + } + }) + } + return ( <>
- +
- +
- { challenge.submitTriggered && !challenge.name &&
-
-
- Work Name is required field + {challenge.submitTriggered && !challenge.name && ( +
+
+
+ Work Name is required field +
-
} + )} ) } diff --git a/src/components/ChallengesComponent/index.js b/src/components/ChallengesComponent/index.js index 038461b1..b9181c20 100644 --- a/src/components/ChallengesComponent/index.js +++ b/src/components/ChallengesComponent/index.js @@ -7,7 +7,7 @@ import PropTypes from 'prop-types' import { Helmet } from 'react-helmet' import { Link } from 'react-router-dom' import ProjectStatus from './ProjectStatus' -import { PROJECT_ROLES, PROJECT_STATUS, COPILOTS_URL } from '../../config/constants' +import { PROJECT_ROLES, PROJECT_STATUS, COPILOTS_URL, CHALLENGE_STATUS } from '../../config/constants' import { PrimaryButton, OutlineButton } from '../Buttons' import ChallengeList from './ChallengeList' import styles from './ChallengesComponent.module.scss' @@ -53,6 +53,12 @@ const ChallengesComponent = ({ const isReadOnly = checkReadOnlyRoles(auth.token) || loginUserRoleInProject === PROJECT_ROLES.READ const isAdminOrCopilot = checkAdminOrCopilot(auth.token, activeProject) + const projectStatus = activeProject && activeProject.status + ? activeProject.status.toUpperCase() + : '' + const isCompletedOrCancelled = + projectStatus === CHALLENGE_STATUS.CANCELLED || projectStatus === CHALLENGE_STATUS.COMPLETED + useEffect(() => { const loggedInUser = auth.user const projectMembers = activeProject.members @@ -94,7 +100,7 @@ const ChallengesComponent = ({ className={styles.btnOutline} /> )} - {(checkAdmin(auth.token) || checkManager(auth.token)) && ( + {(checkAdmin(auth.token) || checkManager(auth.token)) && !isCompletedOrCancelled && (