Skip to content

[Ready Release] Bug Bash Round 2 #268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/actions/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
*/

import { createActions } from "redux-actions";
import { decodeToken } from "../utils/token";
import _ from "lodash";
import { decodeToken, readCookie } from "../utils/token";
import { getApiV3, getApiV5 } from "../services/challenge-api";
import { setErrorIcon, ERROR_ICON_TYPES } from "../utils/errors";
import { getAuthUserTokens } from "@topcoder/micro-frontends-navbar-app";
import { TOKEN_COOKIE_KEYS } from "../constants/index";

/**
* Helper method that checks for HTTP error response v5 and throws Error in this case.
Expand Down Expand Up @@ -83,11 +85,27 @@ async function setAuthDone() {
return user;
}

/**
* @static
* @desc Check token cookies to find if a user is logged out:
* This is because all the token cookies are cleared if a user is logged out.
* @return {Action}
*/
function checkIsLoggedOut() {
const tokenKeys = Object.keys(TOKEN_COOKIE_KEYS);
const isLoggedOut = _.every(
tokenKeys,
(k) => readCookie(TOKEN_COOKIE_KEYS[k]) === undefined
);
return { isLoggedOut };
}

export default createActions({
AUTH: {
LOAD_PROFILE: loadProfileDone,
SET_TC_TOKEN_V2: setTcTokenV2,
SET_TC_TOKEN_V3: setTcTokenV3,
SET_AUTH_DONE: setAuthDone,
CHECK_IS_LOGGED_OUT: checkIsLoggedOut,
},
});
19 changes: 19 additions & 0 deletions src/actions/challenge.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,24 @@ function getChallengeDone(challengeId) {
return challengeService.getChallenge(challengeId);
}

/**
* @static
* @desc Check if a user has registered a challenge
* @param {String} challengeId Challenge ID.
* @param {String} userId User Id.
* @return {Action}
*/
async function getIsRegistered(challengeId, userId) {
const registrants = await challengeService.getChallengeRegistrants(
challengeId
);
const isRegistered = _.some(
registrants,
(r) => `${r.memberId}` === `${userId}`
);
return { isRegistered };
}

export default createActions({
CHALLENGE: {
DROP_CHECKPOINTS: dropCheckpoints,
Expand Down Expand Up @@ -483,5 +501,6 @@ export default createActions({
GET_SUBMISSION_INFORMATION_DONE: getSubmissionInformationDone,
GET_CHALLENGE_INIT: _.noop,
GET_CHALLENGE_DONE: getChallengeDone,
GET_IS_REGISTERED: getIsRegistered,
},
});
2 changes: 1 addition & 1 deletion src/components/DateRangePicker/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ function DateRangePicker(props) {
});

setIsComponentVisible(false);
}
};

/**
* Event handler on date selection changes
Expand Down
4 changes: 3 additions & 1 deletion src/components/challenge-detail/Header/ChallengeTags.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ export default function ChallengeTags(props) {
onClick={() =>
setImmediate(() => setChallengeListingFilter({ tags: [tag] }))
}
to={`${challengesUrl}${filterByTag}&tags[]=${encodeURIComponent(tag)}`}
to={`${challengesUrl}${filterByTag}&tags[]=${encodeURIComponent(
tag
)}`}
>
{tag}
</Tag>
Expand Down
19 changes: 19 additions & 0 deletions src/components/challenge-listing/ChallengeLoading/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import "./styles.module.scss";

export default function ChallengeLoading() {
return (
<div styleName="challenge-loading">
<div styleName="track placeholder-template"></div>
<div styleName="main">
<div styleName="title placeholder-template"></div>
<div styleName="info placeholder-template"></div>
<div styleName="footer placeholder-template"></div>
</div>
<div>
<div styleName="prize placeholder-template"></div>
<div styleName="prize-nominal placeholder-template"></div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
@import "~styles/mixins";

@keyframes placeholderAnim {
0% {
background-position: -$base-unit * 94 0;
}

100% {
background-position: $base-unit * 94 0;
}
}

.animated-placeholder-template {
animation-duration: 1.25s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeholderAnim;
animation-timing-function: linear;
background: $tc-gray-neutral-dark;
background: linear-gradient(to right, $tc-gray-neutral-dark 8%, $tc-gray-10 18%, $tc-gray-neutral-dark 33%);
background-size: $base-unit * 256 $base-unit * 20;
position: relative;
}

.placeholder-template {
border-radius: $corner-radius;

@extend .animated-placeholder-template;
}

.challenge-loading {
height: 126px;
padding: 16px;
margin: 0 24px;
display: flex;
border-bottom: 1px solid #E9E9E9;
border-top: 1px solid #E9E9E9;

> div {
margin-right: 16px;
}

&:nth-child(even) {
background: #FBFBFB;
}
.track {
flex: 1 0 46px;
width: 46px;
height: 44px;
}

.main {
flex: 1 1 70%;
}

.title {
height: 22px;
width: 100px;
margin-bottom: 8px;
}

.info {
height: 18px;
width: 200px;
margin-bottom: 16px;
}

.footer {
height: 18px;
width: 70%;
}

.prize {
height: 18px;
width: 60px;
margin-bottom: 8px;
margin-right: 40px;
}

.prize-nominal {
height: 42px;
width: 40px;
}
}
6 changes: 6 additions & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,9 @@ export const COMPETITION_TRACKS = {
DEV: "Development",
QA: "Quality Assurance",
};

export const TOKEN_COOKIE_KEYS = {
V3JWT: "v3jwt",
TCJWT: "tcjwt",
TCSSO: "tcsso",
};
12 changes: 4 additions & 8 deletions src/containers/Challenges/Listing/ChallengeItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import * as utils from "../../../../utils";
import ProgressTooltip from "../tooltips/ProgressTooltip";
import PlacementsTooltip from "../tooltips/PlacementsTooltip";
import TagsMoreTooltip from "../tooltips/TagsMoreTooltip";
import { CHALLENGES_URL } from 'constants';
import { Link } from '@reach/router';
import { CHALLENGES_URL } from "constants";
import { Link } from "@reach/router";

import "./styles.scss";

Expand Down Expand Up @@ -45,9 +45,7 @@ const ChallengeItem = ({ challenge, onClickTag, onClickTrack, isLoggedIn }) => {
<div styleName="info">
<div styleName="name-container">
<h6 styleName="name">
<Link
to={`${CHALLENGES_URL}/${challenge.id}`}
>
<Link to={`${CHALLENGES_URL}/${challenge.id}`}>
{challenge.name}
</Link>
</h6>
Expand All @@ -72,9 +70,7 @@ const ChallengeItem = ({ challenge, onClickTag, onClickTrack, isLoggedIn }) => {
/>
</div>
<div styleName="nums">
<Link
to={`${CHALLENGES_URL}/${challenge.id}?tab=registrants`}
>
<Link to={`${CHALLENGES_URL}/${challenge.id}?tab=registrants`}>
<NumRegistrants numOfRegistrants={challenge.numOfRegistrants} />
</Link>
<Link to={submissionLink}>
Expand Down
9 changes: 7 additions & 2 deletions src/containers/Challenges/Listing/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import ChallengeItem from "./ChallengeItem";
import TextInput from "../../../components/TextInput";
import Dropdown from "../../../components/Dropdown";
import DateRangePicker from "../../../components/DateRangePicker";
import ChallengeLoading from "../../../components/challenge-listing/ChallengeLoading";
import * as utils from "../../../utils";

import * as constants from "../../../constants";
import IconSearch from "../../../assets/icons/search.svg";

import "./styles.scss";

const Listing = ({
challenges,
loadingChallenges,
search,
page,
perPage,
Expand Down Expand Up @@ -111,7 +113,9 @@ const Listing = ({
</div>
</div>
</Panel.Header>
{challenges.length ? (
{loadingChallenges ? (
_.times(3, () => <ChallengeLoading />)
) : challenges.length ? (
<Panel.Body>
{challenges.map((challenge, index) => (
<div
Expand Down Expand Up @@ -162,6 +166,7 @@ const Listing = ({

Listing.propTypes = {
challenges: PT.arrayOf(PT.shape()),
loadingChallenges: PT.bool,
search: PT.string,
page: PT.number,
perPage: PT.number,
Expand Down
24 changes: 18 additions & 6 deletions src/containers/Challenges/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { connect } from "react-redux";
import Listing from "./Listing";
import actions from "../../actions";
// import ChallengeRecommendedError from "./Listing/errors/ChallengeRecommendedError";
import LoadingIndicator from "../../components/LoadingIndicator";
import Panel from "../../components/Panel";
import * as constants from "../../constants";
import IconListView from "../../assets/icons/list-view.svg";
import IconCardView from "../../assets/icons/card-view.svg";
// import IconListView from "../../assets/icons/list-view.svg";
// import IconCardView from "../../assets/icons/card-view.svg";
import { Banner } from "@topcoder/micro-frontends-earn-app";
import * as utils from "../../utils";

import * as utils from "../../utils";
import "./styles.scss";

const Challenges = ({
Expand All @@ -29,6 +31,7 @@ const Challenges = ({
initialized,
updateQuery,
tags,
loadingChallenges,
}) => {
const [isLoggedIn, setIsLoggedIn] = useState(null);

Expand Down Expand Up @@ -76,20 +79,21 @@ const Challenges = ({
<Banner />
<h1 styleName="title">
<span>CHALLENGES</span>
<span styleName="view-mode">
{/* <span styleName="view-mode">
<button styleName="button-icon active">
<IconListView />
</button>
<button styleName="button-icon">
<IconCardView />
</button>
</span>
</span> */}
</h1>
{initialized && (
{initialized ? (
<>
{/*noRecommendedChallenges && <ChallengeRecommendedError />*/}
<Listing
challenges={challenges}
loadingChallenges={loadingChallenges}
search={search}
page={page}
perPage={perPage}
Expand All @@ -107,6 +111,12 @@ const Challenges = ({
isLoggedIn={isLoggedIn}
/>
</>
) : (
<Panel>
<Panel.Body>
<LoadingIndicator />
</Panel.Body>
</Panel>
)}
</div>
);
Expand All @@ -128,6 +138,7 @@ Challenges.propTypes = {
initialized: PT.bool,
updateQuery: PT.func,
tags: PT.arrayOf(PT.string),
loadingChallenges: PT.bool,
};

const mapStateToProps = (state) => ({
Expand All @@ -146,6 +157,7 @@ const mapStateToProps = (state) => ({
recommendedChallenges: state.challenges.recommendedChallenges,
initialized: state.challenges.initialized,
tags: state.filter.challenge.tags,
loadingChallenges: state.challenges.loadingChallenges,
});

const mapDispatchToProps = {
Expand Down
2 changes: 1 addition & 1 deletion src/containers/Filter/ChallengeFilter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const ChallengeFilter = ({
updateFilter(filterChange);
}}
/>
<span>{track.replace('Quality Assurance', 'QA')}</span>
<span>{track.replace("Quality Assurance", "QA")}</span>
</span>
))}
</div>
Expand Down
Loading