Challenge Overview
Topcoder is working hard on a massive upgrade of our beloved community platform. In this challenge you will work on the new challenge details page: you will add proper logic related to Challenge Terms, and you will refactor the sidebar in specifications tab, which was implemented with some issues in the previous challenge.
The work is to be done in Community App, out of the latest commit in develop branch (9837cc0c592d894cfcd922df8a7a042ffdca7000 at the moment of writing). You should follow the best practices established in the repository:
The work is to be done in Community App, out of the latest commit in develop branch (9837cc0c592d894cfcd922df8a7a042ffdca7000 at the moment of writing). You should follow the best practices established in the repository:
- Properly use Redux. Properly split code into reusable, self-contained React components, conveniently grouped inside folder structure;
- Do not violate ESLint rules for JS code, nor StyleLint rules for SCSS;
- Properly use babel-plugin-react-css-modules and / or react-css-themr for styling;
- Use SCSS variables and mixins from the global stylesheets (/src/styles/_tc-styles.scss). Especially, when it relates to colors, fonts, etc;
- Do not break existing unit tests.
- etc.;
Challenge Scope
- Challenge Terms. Right now, the challenge terms URL is hard-coded inside specifications sidebar's code (both for design and development challenges), and the URL leads to the standard TC terms. This is not right, and to properly implement challenge terms flow is the main focus of this challenge
The challenge terms can be fetched and agreed using Topcoder API v2 (the link to the API specs is given in the challenge forum). When challenge details page is loaded, you should use the endpoint /v2/terms/:challengeId?noauth=true&role=Submitter to load the list of relevant challenge terms. If the visitor is an authenticated user, you should call this endpoint passing API v2 auth token, without noauth=true param - in this case the response will contain information about the terms already agreed by the visitor before. There are other endpoints to get the actual terms text, and to agree to the specified terms. In a few words: we need to list the right terms in the specs sidebar; if the visitor is an authenticated user, we want to mark by checkmark icons the terms already agreed by the user; when an authenticated user presses Register button, we check whether he has agreed to all applicable terms: if yes, we just register him; if not, we open in the modal window, one-by-one, the terms he should agree before registering, and only register him after he has accepted them all.
Technically, you are expected:
1.1. Create the new service /src/shared/services/terms.js, which should be organized similarly to the challenges.js service, and should provide all necessary functionality related to the challenge terms.
1.2. Create the new Redux actions (/src/shared/actions/terms.js) and reducer (/src/shared/reducers/terms.js). Again, you can take challenge actions and reducer as an example. Especially, note that when challenge details are loaded, rather than using a boolean flag to indicate they are being loaded, a string field loadingDetailsForChallengeId is used there. It is empty string (thus falsy) when no details is being loaded, otherwise it is set equal to the ID of the challenge for which we are loading the details. Once the details request is resolved, the ID of the challenge from the request is compared against loadingDetailsForChallengeId, and only if they match the result is stored to the Redux store, otherwise it is silently discarted. It allows, if user changes pages faster than data are loaded, to decide whether we need to initiate loading details for the new challenge, and to not worry about previously intiated, but not yet resolved network requests. Please, use the same approach when fetching challenge terms.
1.3. Ensure the terms of service are properly rendered in the sidebar, and when the visitor is authenticated, those already agreed are marked by checkmarks.
1.4. When visitor clicks Register button, if some of required terms are not yet agreed, show them in modal dialogs one-by-one, and do not register, if he does not agree to them all. Note, that Modal component is already present in the repo (/src/components/Modal), and the registration logic (without checking the terms) is already in-place. Thus, this requirement is not that tough, as it might look.
- Refactor specifications sidebar component.
2.1. At the moment the sidebar component is split into two components: DesignSideBar.jsx, and DevelopSideBar.jsx. We should merge these together, ensuring that we re-use the common code, and conditionally render the sidebar sections related only to design, or only to development (datasci) challenges;
2.2. The styling related to the sidebar is located in /srs/shared/challenge-details/Specification/style.scss. You should move related styles to the separate style.scss, placed in the same folder with the sidebar component, similarly to how it is done with all components in the repo (well, some also may violate the rule, do not take it as an example).
2.3. The sidebar-related SCSS code is not good. It relies a lot on parent-child relations between elements (using > selector in SCSS) which is a problem, because small changes in HTML markup (for example, grouping some tags by <div> wrapper, breaks the styling right away). You should fix it (at least, you will likely see lot's of related problem while working on 2.1, so you sould resolve them in a good way, without adding hacky SCSS fixes into this bad stylesheet). Surely, you should not break the design of the sidebar!
- Tooltip component. Finally, you will see that development sidebar uses a simple custom implementation of tooltip component. We already have tooltip solution adopted in the repository (it is used on the challenge listing page): rc-tooltip package, and we have a simple wrapper around it in /src/shared/components/challenge-listing/Tooltips/Tooltip (it does not do much, just adds some custom styling to the default rc-tooltip). Feel free to discuss, if there is a better solution, but in principle you should move that tooltip wrapper to /src/shared/components/Tooltip, ensure that challenge listings code is not broken (i.e. all import paths are properly updated), and ensure that challenge details page uses that tooltip rather than the custom one.