Skip to content

Commit

Permalink
fix(client): map progress ui (#54576)
Browse files Browse the repository at this point in the history
Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com>
  • Loading branch information
ahmaxed and moT01 committed May 1, 2024
1 parent 684ce99 commit c075247
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 102 deletions.
105 changes: 50 additions & 55 deletions client/src/assets/icons/completion-ribbon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,87 @@ interface RibbonProps {
value: number;
isClaimed: boolean;
isCompleted: boolean;
showNumbers?: boolean;
}

export const Arrow = () => (
<svg width={70} height={40} xmlns='http://www.w3.org/2000/svg'>
<line
x1={50}
y1={0}
x2={50}
y2={35}
stroke='black'
strokeWidth={3}
strokeDasharray='6,1.3'
className='map-arrow-icon'
/>
<rect
x={36}
y={35}
width={15}
height={2}
fill='black'
transform='rotate(45, 50, 36)'
className='map-arrow-icon'
/>
<rect
x={49}
y={35}
width={15}
height={2}
fill='black'
transform='rotate(-45, 50, 36)'
className='map-arrow-icon'
/>
<svg
width='14'
height='35'
viewBox='0 0 14 35'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M7 0V30' stroke='var(--secondary-color)' strokeWidth='2' />
</svg>
);

export const RibbonIcon = ({
value,
isCompleted: completed,
showNumbers = false,
isClaimed
}: RibbonProps): JSX.Element => {
const properClassName = completed ? 'completeIcon' : 'incompleteIcon';
const fillColor = completed ? 'black' : 'gray';
const textColor = completed
? 'var(--secondary-background)'
: 'var(--secondary-color)';

return (
<svg
xmlns='http://www.w3.org/2000/svg'
width='75%'
height='75%'
width='45'
height='51'
viewBox='0 0 45 50'
fill='none'
xmlns='http://www.w3.org/2000/svg'
className={properClassName}
aria-hidden='true'
>
{isClaimed && (
<>
<path
d='M25 35.3418L35.4851 28L44.5957 41.0113L36.2658 39.7151L34.1106 48.353L25 35.3418Z'
className='map-icon'
fill='var(--secondary-color)'
/>
<path
d='M9.11059 29L19.5957 36.3418L10.4851 49.353L8.85418 41.0821L-4.67677e-07 42.0113L9.11059 29Z'
className='map-icon'
fill='var(--secondary-color)'
/>
</>
)}

<circle cx={21.9999} cy={21} r={20} fill={fillColor} />
<circle
cx={22.5}
cy={21}
r={17.5}
fill={fillColor}
stroke='white'
strokeWidth={2}
cx='22'
cy='21'
r='20'
fill='var(--secondary-background)'
stroke='var(--secondary-color)'
strokeWidth='3'
/>
<text
x='50%'
y='50%'
fontFamily='Verdana'
color={fillColor}
fontSize='1.0rem'
fill='#fff'
textAnchor='middle'
alignmentBaseline='central'
>
{value}
</text>
{completed && (
<circle
cx='22'
cy='21'
r='17.5'
fill='var(--secondary-color)'
stroke='var(--secondary-background)'
strokeWidth='3'
/>
)}
{showNumbers && (
<g>
<text
x='48%'
y='55%'
fontFamily='lato'
color={textColor}
fontSize='1.0rem'
fill={textColor}
textAnchor='middle'
>
{value}
</text>
</g>
)}
</svg>
);
};
Expand Down
111 changes: 66 additions & 45 deletions client/src/components/Map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { graphql, useStaticQuery } from 'gatsby';
import { useTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
Expand All @@ -22,17 +23,23 @@ import {

import { RibbonIcon, Arrow } from '../../assets/icons/completion-ribbon';

import { CurrentCert, ClaimedCertifications } from '../../redux/prop-types';
import {
CurrentCert,
ClaimedCertifications,
AllChallengeNode
} from '../../redux/prop-types';
import {
certSlugTypeMap,
superBlockCertTypeMap
} from '../../../../shared/config/certification-settings';
import { completedChallengesIdsSelector } from '../../templates/Challenges/redux/selectors';

interface MapProps {
forLanding?: boolean;
isSignedIn: boolean;
currentCerts: CurrentCert[];
claimedCertifications?: ClaimedCertifications;
completedChallengeIds: string[];
}

const linkSpacingStyle = {
Expand All @@ -51,27 +58,31 @@ const coreCurriculum = [
const mapStateToProps = createSelector(
isSignedInSelector,
currentCertsSelector,
(isSignedIn: boolean, currentCerts) => ({
completedChallengesIdsSelector,
(isSignedIn: boolean, currentCerts, completedChallengeIds: string[]) => ({
isSignedIn,
currentCerts
currentCerts,
completedChallengeIds
})
);

function MapLi({
superBlock,
landing = false,
last = false,
trackProgress,
completed,
claimed,
showArrows = false,
showNumbers = false,
index
}: {
superBlock: SuperBlocks;
landing: boolean;
last?: boolean;
trackProgress: boolean;
completed: boolean;
claimed: boolean;
showArrows?: boolean;
showNumbers?: boolean;
index: number;
}) {
return (
Expand All @@ -80,18 +91,17 @@ function MapLi({
data-test-label='curriculum-map-button'
data-playwright-test-label='curriculum-map-button'
>
{trackProgress && (
<>
<div className='progress-icon'>
<RibbonIcon
value={index + 1}
isCompleted={completed}
isClaimed={claimed}
/>
</div>
<div className='progression-arrow'>{!last && <Arrow />}</div>
</>
)}
<div className='progress-icon'>
<RibbonIcon
value={index + 1}
showNumbers={showNumbers}
isCompleted={completed}
isClaimed={claimed}
/>
</div>
<div className='progression-arrow'>
{!last && showArrows && <Arrow />}
</div>

<Link className='btn link-btn btn-lg' to={`/learn/${superBlock}/`}>
<div style={linkSpacingStyle}>
Expand All @@ -108,26 +118,41 @@ function MapLi({
function Map({
forLanding = false,
isSignedIn,
currentCerts
currentCerts,
completedChallengeIds
}: MapProps): React.ReactElement {
const {
allChallengeNode: { edges }
}: {
allChallengeNode: AllChallengeNode;
} = useStaticQuery(graphql`
query allChallenges {
allChallengeNode {
edges {
node {
challenge {
id
superBlock
}
}
}
}
}
`);

const allChallenges = edges.map(edge => edge.node.challenge);

const { t } = useTranslation();

const isTracking = (stage: SuperBlocks) =>
![
...superBlockOrder[SuperBlockStages.Upcoming],
...superBlockOrder[SuperBlockStages.Extra]
].includes(stage);
const allSuperblockChallengesCompleted = (superblock: SuperBlocks) => {
// array of all challenge ID's in the superblock
const allSuperblockChallenges = allChallenges
.filter(challenge => challenge.superBlock === superblock)
.map(challenge => challenge.id);

const isCompleted = (stage: SuperBlocks) => {
return isSignedIn
? Boolean(
currentCerts?.find(
(cert: { certSlug: string }) =>
(certSlugTypeMap as { [key: string]: string })[cert.certSlug] ===
(superBlockCertTypeMap as { [key: string]: string })[stage]
)
)
: false;
return allSuperblockChallenges.every(id =>
completedChallengeIds.includes(id)
);
};

const isClaimed = (stage: SuperBlocks) => {
Expand All @@ -153,10 +178,11 @@ function Map({
key={i}
superBlock={superBlock}
landing={forLanding}
trackProgress={isTracking(superBlock)}
index={i}
claimed={isClaimed(superBlock)}
completed={isCompleted(superBlock)}
showArrows={true}
showNumbers={true}
completed={allSuperblockChallengesCompleted(superBlock)}
last={i + 1 == coreCurriculum.length}
/>
))}
Expand All @@ -171,8 +197,7 @@ function Map({
key={i}
superBlock={superBlock}
landing={forLanding}
trackProgress={isTracking(superBlock)}
completed={isCompleted(superBlock)}
completed={allSuperblockChallengesCompleted(superBlock)}
claimed={isClaimed(superBlock)}
index={i}
last={i + 1 == superBlockOrder[SuperBlockStages.English].length}
Expand All @@ -189,8 +214,7 @@ function Map({
key={i}
superBlock={superBlock}
landing={forLanding}
trackProgress={isTracking(superBlock)}
completed={isCompleted(superBlock)}
completed={allSuperblockChallengesCompleted(superBlock)}
claimed={isClaimed(superBlock)}
index={i}
last={
Expand All @@ -209,8 +233,7 @@ function Map({
key={i}
superBlock={superBlock}
landing={forLanding}
trackProgress={isTracking(superBlock)}
completed={isCompleted(superBlock)}
completed={allSuperblockChallengesCompleted(superBlock)}
claimed={isClaimed(superBlock)}
index={i}
last={i + 1 == superBlockOrder[SuperBlockStages.Extra].length}
Expand All @@ -227,8 +250,7 @@ function Map({
key={i}
superBlock={superBlock}
landing={forLanding}
trackProgress={isTracking(superBlock)}
completed={isCompleted(superBlock)}
completed={allSuperblockChallengesCompleted(superBlock)}
claimed={isClaimed(superBlock)}
index={i}
last={i + 1 == superBlockOrder[SuperBlockStages.Legacy].length}
Expand All @@ -247,8 +269,7 @@ function Map({
key={i}
superBlock={superBlock}
landing={forLanding}
trackProgress={isTracking(superBlock)}
completed={isCompleted(superBlock)}
completed={allSuperblockChallengesCompleted(superBlock)}
index={i}
claimed={isClaimed(superBlock)}
last={
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/Map/map.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

.progression-arrow {
position: absolute;
bottom: -18px;
left: -18px;
bottom: -16px;
left: 25px;
}

.map-ui ul .progress-icon {
Expand Down

0 comments on commit c075247

Please sign in to comment.