feat(client): styling for project cards (#44771)
* feat: project -> certification project * feat: add certification icon * feat: cert project banner * feat: combine new cert detection methods * feat: add a dynamic tag * feat: replace blocks with grid bloks for new RWD * feat: adjust individual progress bar * feat: add dropdown icon * feat: add conditional rendering * feat: add local and fix cert card link Co-authored-by: ahmad abdolsaheb <ahmad.abdolsaheb@gmail.com>
This commit is contained in:
@ -76,31 +76,31 @@
|
|||||||
"note": "Note: Some browser extensions, such as ad-blockers and dark mode extensions can interfere with the tests. If you face issues, we recommend disabling extensions that modify the content or layout of pages, while taking the course.",
|
"note": "Note: Some browser extensions, such as ad-blockers and dark mode extensions can interfere with the tests. If you face issues, we recommend disabling extensions that modify the content or layout of pages, while taking the course.",
|
||||||
"blocks": {
|
"blocks": {
|
||||||
"build-a-tribute-page-project": {
|
"build-a-tribute-page-project": {
|
||||||
"title": "Build a Tribute Page Project",
|
"title": "Tribute Page",
|
||||||
"intro": [
|
"intro": [
|
||||||
"This is one of the required projects to earn your certification.",
|
"This is one of the required projects to earn your certification.",
|
||||||
"For this project, you will build a tribute page for a subject of your choosing, fictional or real."
|
"For this project, you will build a tribute page for a subject of your choosing, fictional or real."
|
||||||
] },
|
] },
|
||||||
"build-a-personal-portfolio-webpage-project": {
|
"build-a-personal-portfolio-webpage-project": {
|
||||||
"title": "Build a Personal Portfolio Webpage Project",
|
"title": "Personal Portfolio Webpage",
|
||||||
"intro": [
|
"intro": [
|
||||||
"This is one of the required projects to earn your certification.",
|
"This is one of the required projects to earn your certification.",
|
||||||
"For this project, you will build your own personal portfolio page."
|
"For this project, you will build your own personal portfolio page."
|
||||||
] },
|
] },
|
||||||
"build-a-product-landing-page-project": {
|
"build-a-product-landing-page-project": {
|
||||||
"title": "Build a Product Landing Page Project",
|
"title": "Product Landing Page",
|
||||||
"intro": [
|
"intro": [
|
||||||
"This is one of the required projects to earn your certification.",
|
"This is one of the required projects to earn your certification.",
|
||||||
"For this project, you will build a product landing page to market a product of your choice."
|
"For this project, you will build a product landing page to market a product of your choice."
|
||||||
] },
|
] },
|
||||||
"build-a-survey-form-project": {
|
"build-a-survey-form-project": {
|
||||||
"title": "Build a Survey Form Project",
|
"title": "Survey Form",
|
||||||
"intro": [
|
"intro": [
|
||||||
"This is one of the required projects to earn your certification.",
|
"This is one of the required projects to earn your certification.",
|
||||||
"For this project, you will build a survey form to collect data from your users."
|
"For this project, you will build a survey form to collect data from your users."
|
||||||
] },
|
] },
|
||||||
"build-a-technical-documentation-page-project": {
|
"build-a-technical-documentation-page-project": {
|
||||||
"title": "Build a Technical Documentation Page Project",
|
"title": "Technical Documentation Page",
|
||||||
"intro": [
|
"intro": [
|
||||||
"This is one of the required projects to earn your certification.",
|
"This is one of the required projects to earn your certification.",
|
||||||
"For this project, you will build a technical documentation page to serve as instruction or reference for a topic."
|
"For this project, you will build a technical documentation page to serve as instruction or reference for a topic."
|
||||||
|
@ -418,7 +418,8 @@
|
|||||||
"email": "Email",
|
"email": "Email",
|
||||||
"and": "and",
|
"and": "and",
|
||||||
"change-theme": "Sign in to change theme.",
|
"change-theme": "Sign in to change theme.",
|
||||||
"translation-pending": "Help us translate"
|
"translation-pending": "Help us translate",
|
||||||
|
"certification-project": "Certification Project"
|
||||||
},
|
},
|
||||||
"icons": {
|
"icons": {
|
||||||
"gold-cup": "Gold Cup",
|
"gold-cup": "Gold Cup",
|
||||||
|
26
client/src/assets/icons/dropdown.tsx
Normal file
26
client/src/assets/icons/dropdown.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function DropDown(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
width='10'
|
||||||
|
height='10'
|
||||||
|
viewBox='0 0 389 254'
|
||||||
|
fill='none'
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d='M194.5 0L388.5 254H307.5L194.5 99L78.5 254H0.5L194.5 0Z'
|
||||||
|
style={{
|
||||||
|
stroke: 'var(--primary-color)',
|
||||||
|
fill: 'var(--primary-color)',
|
||||||
|
strokeWidth: '1px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DropDown.displayName = 'DropDown';
|
||||||
|
|
||||||
|
export default DropDown;
|
@ -1,22 +1,25 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { withTranslation, TFunction } from 'react-i18next';
|
import { withTranslation, TFunction } from 'react-i18next';
|
||||||
|
import { ProgressBar } from '@freecodecamp/react-bootstrap';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ScrollableAnchor from 'react-scrollable-anchor';
|
import ScrollableAnchor from 'react-scrollable-anchor';
|
||||||
import { bindActionCreators, Dispatch } from 'redux';
|
import { bindActionCreators, Dispatch } from 'redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { SuperBlocks } from '../../../../../config/certification-settings';
|
import { SuperBlocks } from '../../../../../config/certification-settings';
|
||||||
|
|
||||||
import envData from '../../../../../config/env.json';
|
import envData from '../../../../../config/env.json';
|
||||||
import { isAuditedCert } from '../../../../../utils/is-audited';
|
import { isAuditedCert } from '../../../../../utils/is-audited';
|
||||||
import Caret from '../../../assets/icons/caret';
|
import Caret from '../../../assets/icons/caret';
|
||||||
|
import DropDown from '../../../assets/icons/dropdown';
|
||||||
import GreenNotCompleted from '../../../assets/icons/green-not-completed';
|
import GreenNotCompleted from '../../../assets/icons/green-not-completed';
|
||||||
import GreenPass from '../../../assets/icons/green-pass';
|
import GreenPass from '../../../assets/icons/green-pass';
|
||||||
import { Link } from '../../../components/helpers';
|
import { Link, Spacer } from '../../../components/helpers';
|
||||||
import { completedChallengesSelector, executeGA } from '../../../redux';
|
import { completedChallengesSelector, executeGA } from '../../../redux';
|
||||||
import { ChallengeNode, CompletedChallenge } from '../../../redux/prop-types';
|
import { ChallengeNode, CompletedChallenge } from '../../../redux/prop-types';
|
||||||
import { playTone } from '../../../utils/tone';
|
import { playTone } from '../../../utils/tone';
|
||||||
import { makeExpandedBlockSelector, toggleBlock } from '../redux';
|
import { makeExpandedBlockSelector, toggleBlock } from '../redux';
|
||||||
|
import IsNewRespCert from '../../../utils/is-new-responsive-web-design-cert';
|
||||||
import Challenges from './challenges';
|
import Challenges from './challenges';
|
||||||
|
import '../intro.css';
|
||||||
|
|
||||||
const { curriculumLocale } = envData;
|
const { curriculumLocale } = envData;
|
||||||
|
|
||||||
@ -101,6 +104,8 @@ export class Block extends Component<BlockProps> {
|
|||||||
t
|
t
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const isNewResponsiveWebDesign = IsNewRespCert(superBlock);
|
||||||
|
|
||||||
let completedCount = 0;
|
let completedCount = 0;
|
||||||
const challengesWithCompleted = challenges.map(({ challenge }) => {
|
const challengesWithCompleted = challenges.map(({ challenge }) => {
|
||||||
const { id } = challenge;
|
const { id } = challenge;
|
||||||
@ -143,84 +148,191 @@ export class Block extends Component<BlockProps> {
|
|||||||
collapse: string;
|
collapse: string;
|
||||||
} = t('intro:misc-text');
|
} = t('intro:misc-text');
|
||||||
|
|
||||||
return isProjectBlock ? (
|
const isBlockCompleted = completedCount === challengesWithCompleted.length;
|
||||||
<ScrollableAnchor id={blockDashedName}>
|
|
||||||
<div className='block'>
|
const percentageComplated = Math.floor(
|
||||||
<div className='block-title-wrapper'>
|
(completedCount / challengesWithCompleted.length) * 100
|
||||||
<a className='block-link' href={`#${blockDashedName}`}>
|
);
|
||||||
<h3 className='big-block-title'>
|
|
||||||
{blockTitle}
|
const progressBarRender = (
|
||||||
<span className='block-link-icon'>#</span>
|
<div className='progress-wrapper'>
|
||||||
</h3>
|
<ProgressBar now={percentageComplated} />
|
||||||
</a>
|
<span>{`${percentageComplated}%`}</span>
|
||||||
{!isAuditedCert(curriculumLocale, superBlock) && (
|
</div>
|
||||||
<div className='block-cta-wrapper'>
|
);
|
||||||
<Link
|
|
||||||
className='block-title-translation-cta'
|
const Block = (
|
||||||
to={t('links:help-translate-link-url')}
|
<>
|
||||||
>
|
{' '}
|
||||||
{t('misc.translation-pending')}
|
<ScrollableAnchor id={blockDashedName}>
|
||||||
</Link>
|
<div className={`block ${isExpanded ? 'open' : ''}`}>
|
||||||
</div>
|
<div className='block-header'>
|
||||||
)}
|
<a className='block-link' href={`#${blockDashedName}`}>
|
||||||
</div>
|
<h3 className='big-block-title'>
|
||||||
{this.renderBlockIntros(blockIntroArr)}
|
{blockTitle}
|
||||||
<Challenges
|
<span className='block-link-icon'>#</span>
|
||||||
challengesWithCompleted={challengesWithCompleted}
|
</h3>
|
||||||
isProjectBlock={isProjectBlock}
|
</a>
|
||||||
superBlock={superBlock}
|
{!isAuditedCert(curriculumLocale, superBlock) && (
|
||||||
/>
|
<div className='block-cta-wrapper'>
|
||||||
</div>
|
<Link
|
||||||
</ScrollableAnchor>
|
className='block-title-translation-cta'
|
||||||
) : (
|
to={t('links:help-translate-link-url')}
|
||||||
<ScrollableAnchor id={blockDashedName}>
|
>
|
||||||
<div className={`block ${isExpanded ? 'open' : ''}`}>
|
{t('misc.translation-pending')}
|
||||||
<div className='block-title-wrapper'>
|
</Link>
|
||||||
<a className='block-link' href={`#${blockDashedName}`}>
|
</div>
|
||||||
<h3 className='big-block-title'>
|
|
||||||
{blockTitle}
|
|
||||||
<span className='block-link-icon'>#</span>
|
|
||||||
</h3>
|
|
||||||
</a>
|
|
||||||
{!isAuditedCert(curriculumLocale, superBlock) && (
|
|
||||||
<div className='block-cta-wrapper'>
|
|
||||||
<Link
|
|
||||||
className='block-title-translation-cta'
|
|
||||||
to={t('links:help-translate-link-url')}
|
|
||||||
>
|
|
||||||
{t('misc.translation-pending')}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{this.renderBlockIntros(blockIntroArr)}
|
|
||||||
<button
|
|
||||||
aria-expanded={isExpanded}
|
|
||||||
className='map-title'
|
|
||||||
onClick={() => {
|
|
||||||
this.handleBlockClick();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Caret />
|
|
||||||
<h4 className='course-title'>
|
|
||||||
{`${isExpanded ? collapseText : expandText}`}
|
|
||||||
</h4>
|
|
||||||
<div className='map-title-completed course-title'>
|
|
||||||
{this.renderCheckMark(
|
|
||||||
completedCount === challengesWithCompleted.length
|
|
||||||
)}
|
)}
|
||||||
<span className='map-completed-count'>{`${completedCount}/${challengesWithCompleted.length}`}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
{this.renderBlockIntros(blockIntroArr)}
|
||||||
{isExpanded && (
|
<button
|
||||||
|
aria-expanded={isExpanded}
|
||||||
|
className='map-title'
|
||||||
|
onClick={() => {
|
||||||
|
this.handleBlockClick();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Caret />
|
||||||
|
<h4 className='course-title'>
|
||||||
|
{`${isExpanded ? collapseText : expandText}`}
|
||||||
|
</h4>
|
||||||
|
<div className='map-title-completed course-title'>
|
||||||
|
{this.renderCheckMark(isBlockCompleted)}
|
||||||
|
<span className='map-completed-count'>{`${completedCount}/${challengesWithCompleted.length}`}</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
{isExpanded && (
|
||||||
|
<Challenges
|
||||||
|
challengesWithCompleted={challengesWithCompleted}
|
||||||
|
isProjectBlock={isProjectBlock}
|
||||||
|
superBlock={superBlock}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ScrollableAnchor>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const ProjectBlock = (
|
||||||
|
<>
|
||||||
|
<ScrollableAnchor id={blockDashedName}>
|
||||||
|
<div className='block'>
|
||||||
|
<div className='block-header'>
|
||||||
|
<a className='block-link' href={`#${blockDashedName}`}>
|
||||||
|
<h3 className='big-block-title'>
|
||||||
|
{blockTitle}
|
||||||
|
<span className='block-link-icon'>#</span>
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
{!isAuditedCert(curriculumLocale, superBlock) && (
|
||||||
|
<div className='block-cta-wrapper'>
|
||||||
|
<Link
|
||||||
|
className='block-title-translation-cta'
|
||||||
|
to={t('links:help-translate-link-url')}
|
||||||
|
>
|
||||||
|
{t('misc.translation-pending')}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{this.renderBlockIntros(blockIntroArr)}
|
||||||
<Challenges
|
<Challenges
|
||||||
challengesWithCompleted={challengesWithCompleted}
|
challengesWithCompleted={challengesWithCompleted}
|
||||||
isProjectBlock={isProjectBlock}
|
isProjectBlock={isProjectBlock}
|
||||||
superBlock={superBlock}
|
superBlock={superBlock}
|
||||||
/>
|
/>
|
||||||
)}
|
</div>
|
||||||
</div>
|
</ScrollableAnchor>
|
||||||
</ScrollableAnchor>
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const GridBlock = (
|
||||||
|
<>
|
||||||
|
{' '}
|
||||||
|
<ScrollableAnchor id={blockDashedName}>
|
||||||
|
<div className={`block block-grid ${isExpanded ? 'open' : ''}`}>
|
||||||
|
<a
|
||||||
|
className='block-header'
|
||||||
|
onClick={() => {
|
||||||
|
this.handleBlockClick();
|
||||||
|
}}
|
||||||
|
href={`#${blockDashedName}`}
|
||||||
|
>
|
||||||
|
<div className='tags-wrapper'>
|
||||||
|
{!isAuditedCert(curriculumLocale, superBlock) && (
|
||||||
|
<Link
|
||||||
|
className='cert-tag'
|
||||||
|
to={t('links:help-translate-link-url')}
|
||||||
|
>
|
||||||
|
{t('misc.translation-pending')}
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className='title-wrapper map-title'>
|
||||||
|
{this.renderCheckMark(isBlockCompleted)}
|
||||||
|
<h3 className='block-grid-title'>{blockTitle}</h3>
|
||||||
|
<DropDown />
|
||||||
|
</div>
|
||||||
|
{isExpanded && this.renderBlockIntros(blockIntroArr)}
|
||||||
|
{!isExpanded &&
|
||||||
|
!isBlockCompleted &&
|
||||||
|
completedCount > 0 &&
|
||||||
|
progressBarRender}
|
||||||
|
</a>
|
||||||
|
{isExpanded && (
|
||||||
|
<>
|
||||||
|
<Challenges
|
||||||
|
challengesWithCompleted={challengesWithCompleted}
|
||||||
|
isProjectBlock={isProjectBlock}
|
||||||
|
superBlock={superBlock}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ScrollableAnchor>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const GridProjectBlock = (
|
||||||
|
<div className='block block-grid grid-project-block'>
|
||||||
|
<a
|
||||||
|
className='block-header'
|
||||||
|
onClick={() => {
|
||||||
|
this.handleBlockClick();
|
||||||
|
}}
|
||||||
|
href={challengesWithCompleted[0].fields.slug}
|
||||||
|
>
|
||||||
|
<div className='tags-wrapper'>
|
||||||
|
<span className='cert-tag'>{t('misc.certification-project')}</span>
|
||||||
|
{!isAuditedCert(curriculumLocale, superBlock) && (
|
||||||
|
<Link
|
||||||
|
className='cert-tag'
|
||||||
|
to={t('links:help-translate-link-url')}
|
||||||
|
>
|
||||||
|
{t('misc.translation-pending')}
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className='title-wrapper map-title'>
|
||||||
|
{this.renderCheckMark(isBlockCompleted)}
|
||||||
|
<h3 className='block-grid-title'>{blockTitle}</h3>
|
||||||
|
</div>
|
||||||
|
{this.renderBlockIntros(blockIntroArr)}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const blockrenderer = () => {
|
||||||
|
if (isProjectBlock)
|
||||||
|
return isNewResponsiveWebDesign ? GridProjectBlock : ProjectBlock;
|
||||||
|
return isNewResponsiveWebDesign ? GridBlock : Block;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{blockrenderer()}
|
||||||
|
{isNewResponsiveWebDesign && !isProjectBlock ? null : <Spacer />}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { executeGA } from '../../../redux';
|
|||||||
import { SuperBlocks } from '../../../../../config/certification-settings';
|
import { SuperBlocks } from '../../../../../config/certification-settings';
|
||||||
import { ExecuteGaArg } from '../../../pages/donate';
|
import { ExecuteGaArg } from '../../../pages/donate';
|
||||||
import { ChallengeWithCompletedNode } from '../../../redux/prop-types';
|
import { ChallengeWithCompletedNode } from '../../../redux/prop-types';
|
||||||
|
import isNewRespCert from '../../../utils/is-new-responsive-web-design-cert';
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: Dispatch) =>
|
const mapDispatchToProps = (dispatch: Dispatch) =>
|
||||||
bindActionCreators({ executeGA }, dispatch);
|
bindActionCreators({ executeGA }, dispatch);
|
||||||
@ -46,7 +47,7 @@ function Challenges({
|
|||||||
<GreenNotCompleted style={mapIconStyle} />
|
<GreenNotCompleted style={mapIconStyle} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const isGridMap = superBlock === SuperBlocks.RespWebDesignNew;
|
const isGridMap = isNewRespCert(superBlock);
|
||||||
|
|
||||||
return isGridMap ? (
|
return isGridMap ? (
|
||||||
<ul className={`map-challenges-ul map-challenges-grid `}>
|
<ul className={`map-challenges-ul map-challenges-grid `}>
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Alert } from '@freecodecamp/react-bootstrap';
|
import { Alert } from '@freecodecamp/react-bootstrap';
|
||||||
import { SuperBlocks } from '../../../../../config/certification-settings';
|
import { SuperBlocks } from '../../../../../config/certification-settings';
|
||||||
|
import IsNewRespCert from '../../../utils/is-new-responsive-web-design-cert';
|
||||||
import { Link } from '../../../components/helpers';
|
import { Link } from '../../../components/helpers';
|
||||||
|
|
||||||
interface LegacyLinksProps {
|
interface LegacyLinksProps {
|
||||||
@ -12,7 +13,7 @@ function LegacyLinks({ superBlock }: LegacyLinksProps): JSX.Element {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{superBlock === SuperBlocks.RespWebDesignNew && (
|
{IsNewRespCert(superBlock) && (
|
||||||
<Alert bsStyle='info'>
|
<Alert bsStyle='info'>
|
||||||
<p>
|
<p>
|
||||||
{t('intro:misc-text.viewing-upcoming-change')}{' '}
|
{t('intro:misc-text.viewing-upcoming-change')}{' '}
|
||||||
|
@ -13,15 +13,16 @@
|
|||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-title-wrapper {
|
.block-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-title-wrapper .block-link {
|
.block-header .block-link {
|
||||||
flex-grow: 3;
|
flex-grow: 3;
|
||||||
flex-basis: 0;
|
flex-basis: 0;
|
||||||
|
padding: 25px 15px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-link:hover,
|
.block-link:hover,
|
||||||
@ -30,6 +31,13 @@
|
|||||||
background-color: var(--primary-background);
|
background-color: var(--primary-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.cert-tag:hover,
|
||||||
|
a.cert-tag:focus,
|
||||||
|
a.cert-tag:active {
|
||||||
|
color: var(--highlight-background);
|
||||||
|
background-color: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
.block-link {
|
.block-link {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -48,6 +56,12 @@
|
|||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.block-grid-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin: 0;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
.block-title-translation-cta {
|
.block-title-translation-cta {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding: 0.2em 0.5em;
|
padding: 0.2em 0.5em;
|
||||||
@ -162,9 +176,6 @@ button.map-title {
|
|||||||
background: var(--primary-background);
|
background: var(--primary-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-ui .block .big-block-title {
|
|
||||||
padding: 25px 15px 10px;
|
|
||||||
}
|
|
||||||
.block-ui .block .block-description {
|
.block-ui .block .block-description {
|
||||||
padding: 0 15px 15px;
|
padding: 0 15px 15px;
|
||||||
border-bottom: 3px solid var(--secondary-background);
|
border-bottom: 3px solid var(--secondary-background);
|
||||||
@ -212,6 +223,14 @@ button.map-title {
|
|||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.block-grid .map-title > svg:last-child {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid.open .map-title > svg:last-child {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
.map-challenges-ul {
|
.map-challenges-ul {
|
||||||
padding-inline-start: 0;
|
padding-inline-start: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@ -269,7 +288,7 @@ button.map-title {
|
|||||||
font-size: 1.17rem;
|
font-size: 1.17rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-title-wrapper {
|
.block-header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,3 +344,98 @@ button.map-title {
|
|||||||
text-decoration-style: none;
|
text-decoration-style: none;
|
||||||
color: var(--secondary-color);
|
color: var(--secondary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cert-tag {
|
||||||
|
text-align: left;
|
||||||
|
width: fit-content;
|
||||||
|
font-size: 1rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
color: var(--highlight-color);
|
||||||
|
background-color: var(--highlight-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid {
|
||||||
|
border-bottom: 3px solid var(--secondary-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .block-header {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .block-header {
|
||||||
|
display: flex;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 18px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .block-header:hover {
|
||||||
|
color: var(--tertiary-color);
|
||||||
|
background-color: var(--tertiary-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .block-header .block-link {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-ui .block-grid .block-description {
|
||||||
|
border: none;
|
||||||
|
padding: 0 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .map-title > svg:last-child {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .map-title > svg {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .progress-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .progress-wrapper span {
|
||||||
|
color: var(--quaternary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .progress {
|
||||||
|
height: 15px;
|
||||||
|
background-color: var(--secondary-background);
|
||||||
|
margin: 0 10px;
|
||||||
|
width: 80%;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-grid .progress-bar {
|
||||||
|
background-color: var(--blue-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 10px 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-project-block {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
@ -217,7 +217,6 @@ const SuperBlockIntroductionPage = (props: SuperBlockProp) => {
|
|||||||
)}
|
)}
|
||||||
superBlock={superBlock}
|
superBlock={superBlock}
|
||||||
/>
|
/>
|
||||||
{blockDashedName !== 'project-euler' ? <Spacer /> : null}
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
{superBlock !== SuperBlocks.CodingInterviewPrep && (
|
{superBlock !== SuperBlocks.CodingInterviewPrep && (
|
||||||
|
5
client/src/utils/is-new-responsive-web-design-cert.ts
Normal file
5
client/src/utils/is-new-responsive-web-design-cert.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { SuperBlocks } from '../../../config/certification-settings';
|
||||||
|
|
||||||
|
export default function IsNewRespCert(superBlock: string): boolean {
|
||||||
|
return superBlock === SuperBlocks.RespWebDesignNew;
|
||||||
|
}
|
Reference in New Issue
Block a user