From b2192c81b6b6cfda0324ef7f25396fd9cfca9682 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 12 Aug 2022 14:16:35 +0300 Subject: [PATCH 1/4] TCA-299 - update editor UI to match the classic view according to figma --- client/src/components/layouts/global.css | 5 +- client/src/components/layouts/learn.css | 4 ++ .../Challenges/classic/action-row.tsx | 42 ++++++++------- .../Challenges/classic/desktop-layout.tsx | 52 +++++++++---------- .../src/templates/Challenges/classic/show.tsx | 11 +++- .../Challenges/components/side-panel.tsx | 2 +- 6 files changed, 67 insertions(+), 49 deletions(-) diff --git a/client/src/components/layouts/global.css b/client/src/components/layouts/global.css index 1dabb4ee93cee2..68eb41cc25ab24 100644 --- a/client/src/components/layouts/global.css +++ b/client/src/components/layouts/global.css @@ -491,7 +491,10 @@ fieldset[disabled] .btn-primary.focus { } } -.button-group .btn:not(:last-child) { +.button-group { + margin-bottom: -10px; +} +.button-group .btn { margin-bottom: 10px; } strong { diff --git a/client/src/components/layouts/learn.css b/client/src/components/layouts/learn.css index a96b2c77b08f52..292b987c9c36fa 100644 --- a/client/src/components/layouts/learn.css +++ b/client/src/components/layouts/learn.css @@ -24,3 +24,7 @@ #learn-app-wrapper .reflex-container.horizontal > .reflex-splitter { height: 5px; } + +#learn-app-wrapper .reflex-container > .reflex-element:first-child:last-child { + flex: 1 1 auto !important; +} diff --git a/client/src/templates/Challenges/classic/action-row.tsx b/client/src/templates/Challenges/classic/action-row.tsx index 8daaaefa04778f..4025f1b69c4443 100644 --- a/client/src/templates/Challenges/classic/action-row.tsx +++ b/client/src/templates/Challenges/classic/action-row.tsx @@ -8,6 +8,7 @@ import EditorTabs from './editor-tabs'; interface ActionRowProps { block: string; hasNotes: boolean; + hasPreview: boolean; isMultifileCertProject: boolean; showInstructions: boolean; showConsole: boolean; @@ -25,6 +26,7 @@ const mapDispatchToProps = { const ActionRow = ({ hasNotes, + hasPreview, togglePane, showNotes, showPreview, @@ -44,17 +46,15 @@ const ActionRow = ({ )}
- {isMultifileCertProject && ( - - )} + + {hasPreview && ( + + )}
); diff --git a/client/src/templates/Challenges/classic/desktop-layout.tsx b/client/src/templates/Challenges/classic/desktop-layout.tsx index 6fc608c72d7ee3..4bf573240096c7 100644 --- a/client/src/templates/Challenges/classic/desktop-layout.tsx +++ b/client/src/templates/Challenges/classic/desktop-layout.tsx @@ -34,6 +34,7 @@ interface DesktopLayoutProps { resizeProps: ResizeProps; superBlock: string; testOutput: ReactElement; + visibleEditors: { [key: string]: boolean }; } const reflexProps = { @@ -85,20 +86,20 @@ const DesktopLayout = (props: DesktopLayoutProps): JSX.Element => { notes, preview, hasEditableBoundaries, - superBlock + superBlock, + visibleEditors } = props; const challengeFile = getChallengeFile(); const projectBasedChallenge = hasEditableBoundaries; const isMultifileCertProject = challengeType === challengeTypes.multifileCertProject; - const displayPreview = - projectBasedChallenge || isMultifileCertProject - ? showPreview && hasPreview - : hasPreview; + const displayPreview = showPreview && hasPreview; const displayNotes = projectBasedChallenge ? showNotes && hasNotes : false; - const displayConsole = - projectBasedChallenge || isMultifileCertProject ? showConsole : true; + const displayConsole = showConsole; + const displayEditor = Object.entries(visibleEditors).some( + ([, visible]) => visible + ); const { codePane, editorPane, @@ -110,20 +111,19 @@ const DesktopLayout = (props: DesktopLayoutProps): JSX.Element => { return (
- {(projectBasedChallenge || isMultifileCertProject) && ( - - )} +
{!projectBasedChallenge && showInstructions && ( @@ -131,12 +131,12 @@ const DesktopLayout = (props: DesktopLayoutProps): JSX.Element => { {instructions} )} - {!projectBasedChallenge && ( + {!projectBasedChallenge && displayEditor && ( )} - - {challengeFile && ( + {challengeFile && displayEditor && ( + { )} - )} - + + )} {(displayPreview || displayConsole) && ( diff --git a/client/src/templates/Challenges/classic/show.tsx b/client/src/templates/Challenges/classic/show.tsx index ba98af5b9c5fca..487f20dc2065dc 100644 --- a/client/src/templates/Challenges/classic/show.tsx +++ b/client/src/templates/Challenges/classic/show.tsx @@ -38,6 +38,7 @@ import { challengeMounted, challengeTestsSelector, consoleOutputSelector, + visibleEditorsSelector, createFiles, executeChallenge, initConsole, @@ -58,6 +59,10 @@ import MobileLayout from './mobile-layout'; import './classic.css'; import '../components/test-frame.css'; +type VisibleEditors = { + [key: string]: boolean; +}; + // Redux Setup const mapStateToProps = createStructuredSelector({ challengeFiles: challengeFilesSelector, @@ -65,7 +70,8 @@ const mapStateToProps = createStructuredSelector({ testsRunning: testsRunningSelector, output: consoleOutputSelector, isChallengeCompleted: isChallengeCompletedSelector, - savedChallenges: savedChallengesSelector + savedChallenges: savedChallengesSelector, + visibleEditors: visibleEditorsSelector }); const mapDispatchToProps = (dispatch: Dispatch) => @@ -112,6 +118,7 @@ interface ShowClassicProps { setEditorFocusability: (canFocus: boolean) => void; previewMounted: () => void; savedChallenges: CompletedChallenge[]; + visibleEditors: VisibleEditors; } interface ShowClassicState { @@ -429,6 +436,7 @@ class ShowClassic extends Component { challengeMeta: { nextChallengePath, prevChallengePath } }, challengeFiles, + visibleEditors, t } = this.props; @@ -480,6 +488,7 @@ class ShowClassic extends Component { resizeProps={this.resizeProps} superBlock={superBlock} testOutput={this.renderTestOutput()} + visibleEditors={visibleEditors} /> - {showToolPanel && ( + {showToolPanel && tests.length > 10 && ( Date: Fri, 12 Aug 2022 14:30:06 +0300 Subject: [PATCH 2/4] old style editor: do not show completion modal when using ctrl+enter to submit --- client/src/templates/Challenges/components/Hotkeys.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/templates/Challenges/components/Hotkeys.tsx b/client/src/templates/Challenges/components/Hotkeys.tsx index 3354ff7ed2a21f..d3421294b13b49 100644 --- a/client/src/templates/Challenges/components/Hotkeys.tsx +++ b/client/src/templates/Challenges/components/Hotkeys.tsx @@ -85,7 +85,7 @@ function Hotkeys({ executeChallenge(); } } else { - executeChallenge({ showCompletionModal: true }); + executeChallenge(); } }, focusEditor: (e: React.KeyboardEvent) => { From ab3b7d008f0c28085d8d26245b4199e9c8ced872 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Fri, 12 Aug 2022 18:41:36 +0300 Subject: [PATCH 3/4] TCA-299 - improve UI for old style editor --- .../formHelpers/block-save-button.tsx | 2 +- .../components/formHelpers/form-fields.tsx | 51 +++++----- client/src/components/formHelpers/form.tsx | 17 ++-- client/src/components/layouts/global.css | 27 ++++++ client/src/components/layouts/prism.css | 10 ++ client/src/components/layouts/variables.css | 2 + .../templates/Challenges/classic/editor.tsx | 2 +- .../Challenges/classic/simple-editor.tsx | 2 +- .../Challenges/components/challenge-title.tsx | 5 - .../Challenges/components/tool-panel.tsx | 2 +- .../Challenges/projects/frontend/Show.tsx | 50 +++++----- .../Challenges/projects/solution-form.tsx | 8 +- .../src/templates/Challenges/video/Show.tsx | 92 ++++++++++--------- .../src/templates/Challenges/video/show.css | 69 +++++++++++--- 14 files changed, 209 insertions(+), 130 deletions(-) diff --git a/client/src/components/formHelpers/block-save-button.tsx b/client/src/components/formHelpers/block-save-button.tsx index 1a57838e3c2945..2adad66ffd39c1 100644 --- a/client/src/components/formHelpers/block-save-button.tsx +++ b/client/src/components/formHelpers/block-save-button.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; function BlockSaveButton(props?: Record): JSX.Element { const { t } = useTranslation(); return ( - ); diff --git a/client/src/components/formHelpers/form-fields.tsx b/client/src/components/formHelpers/form-fields.tsx index 4b43881894d956..edb8a8e65ac294 100644 --- a/client/src/components/formHelpers/form-fields.tsx +++ b/client/src/components/formHelpers/form-fields.tsx @@ -1,6 +1,5 @@ import { Alert, - Col, ControlLabel, FormControl, FormGroup, @@ -72,7 +71,7 @@ function FormFields(props: FormFieldsProps): JSX.Element { ) : null; }; return ( -
+ <> {formFields .filter(formField => !ignored.includes(formField.name)) .map(({ name, label }) => ( @@ -85,35 +84,33 @@ function FormFields(props: FormFieldsProps): JSX.Element { name in placeholders ? placeholders[name] : ''; const isURL = types[name] === 'url'; return ( - - - {type === 'hidden' ? null : ( - {label} - )} - - {nullOrWarning( - value as string, - !pristine && error, - isURL, - name - )} - - + + {type === 'hidden' ? null : ( + {label} + )} + + {nullOrWarning( + value as string, + !pristine && error, + isURL, + name + )} + ); }} ))} -
+ ); } diff --git a/client/src/components/formHelpers/form.tsx b/client/src/components/formHelpers/form.tsx index 3b9f800c2a1009..c136bd73efcde9 100644 --- a/client/src/components/formHelpers/form.tsx +++ b/client/src/components/formHelpers/form.tsx @@ -6,7 +6,6 @@ import { ValidatedValues, FormFields, BlockSaveButton, - BlockSaveWrapper, formatUrlValues } from '../formHelpers/index'; @@ -54,15 +53,13 @@ function DynamicForm({ style={{ width: '100%' }} > - - {hideButton ? null : ( - - {buttonText ? buttonText : null} - - )} - + {!hideButton && ( + + {buttonText ? buttonText : null} + + )} )} diff --git a/client/src/components/layouts/global.css b/client/src/components/layouts/global.css index 68eb41cc25ab24..038fc6c2f4c5bb 100644 --- a/client/src/components/layouts/global.css +++ b/client/src/components/layouts/global.css @@ -501,6 +501,33 @@ strong { color: var(--secondary-color); } +.form-group.embedded { + border: 1px solid var(--tc-black-40); + padding: 8px 10px 2px; + border-radius: 4px; + position: relative; + max-width: 320px; +} + +.form-group.embedded .control-label { + display: block; + font-size: 11px; + font-family: 'Roboto'; + line-height: 10px; + color: var(--tc-turq-160); + margin-bottom: 4px; +} + +.form-group.embedded .form-control { + border: 0 none; + padding: 0; + height: 22px; + font-size: 14px; + line-height: 22px; + font-family: 'Roboto'; + color: var(--tc-black-100); +} + .form-control { color: var(--primary-color); outline: none; diff --git a/client/src/components/layouts/prism.css b/client/src/components/layouts/prism.css index df0b319f65d4ca..df045354a0089b 100644 --- a/client/src/components/layouts/prism.css +++ b/client/src/components/layouts/prism.css @@ -1,3 +1,9 @@ +pre[class*="language-"].line-numbers.line-numbers { + border-radius: 8px; + font-size: 14px; + line-height: 22px; +} + code .token.operator { background: none; } @@ -7,6 +13,10 @@ pre[class*='language-'] { background: var(--primary-background); } +.line-numbers > p { + color: var(--tc-black-100); +} + .default pre[class*='language-']::selection, .default pre[class*='language-'] ::selection, .default code[class*='language-']::selection, diff --git a/client/src/components/layouts/variables.css b/client/src/components/layouts/variables.css index 294bc1799e77a0..5f7b45774e5367 100644 --- a/client/src/components/layouts/variables.css +++ b/client/src/components/layouts/variables.css @@ -37,6 +37,8 @@ --tc-link-blue-light: #5fb7ee; --tc-black: #000; --tc-black-100: #2a2a2a; + --tc-black-60: #7F7F7F; + --tc-black-40: #aaaaaa; --tc-black-20: #d4d4d4; --tc-black-10: #e9e9e9; --tc-black-5: #f4f4f4; diff --git a/client/src/templates/Challenges/classic/editor.tsx b/client/src/templates/Challenges/classic/editor.tsx index be63d9783a9381..ba1a69ae3002a6 100644 --- a/client/src/templates/Challenges/classic/editor.tsx +++ b/client/src/templates/Challenges/classic/editor.tsx @@ -573,7 +573,7 @@ const Editor = (props: EditorProps): JSX.Element => { attemptRef.current.attempts++; } - const tryToSubmitChallenge = debounce(props.submitChallenge, 2000); + const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, {leading: true}); function createLowerJaw(outputNode: HTMLElement, callback?: () => void) { const { output } = props; diff --git a/client/src/templates/Challenges/classic/simple-editor.tsx b/client/src/templates/Challenges/classic/simple-editor.tsx index 63f5399c80b887..abafe4feb36d10 100755 --- a/client/src/templates/Challenges/classic/simple-editor.tsx +++ b/client/src/templates/Challenges/classic/simple-editor.tsx @@ -513,7 +513,7 @@ const SimpleEditor = (props: EditorProps): JSX.Element => { attemptRef.current.attempts++; } - const tryToSubmitChallenge = debounce(props.submitChallenge, 2000); + const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, {leading: true}); function resetMarginDecorations() { const { model, insideEditDecId } = dataRef.current; diff --git a/client/src/templates/Challenges/components/challenge-title.tsx b/client/src/templates/Challenges/components/challenge-title.tsx index f1ecf699a63023..97453deb051dbe 100644 --- a/client/src/templates/Challenges/components/challenge-title.tsx +++ b/client/src/templates/Challenges/components/challenge-title.tsx @@ -2,7 +2,6 @@ import i18next from 'i18next'; import React from 'react'; import GreenPass from '../../../assets/icons/green-pass'; import { Link } from '../../../components/helpers/index'; -import BreadCrumb from './bread-crumb'; import './challenge-title.css'; @@ -16,11 +15,8 @@ interface ChallengeTitleProps { } function ChallengeTitle({ - block, children, isCompleted, - showBreadCrumbs = true, - superBlock, translationPending }: ChallengeTitleProps): JSX.Element { return ( @@ -36,7 +32,6 @@ function ChallengeTitle({ )} - {showBreadCrumbs && }

{children}

diff --git a/client/src/templates/Challenges/components/tool-panel.tsx b/client/src/templates/Challenges/components/tool-panel.tsx index 371973da6a2a18..0195124909ee8a 100644 --- a/client/src/templates/Challenges/components/tool-panel.tsx +++ b/client/src/templates/Challenges/components/tool-panel.tsx @@ -74,7 +74,7 @@ function ToolPanel({ const { t } = useTranslation(); - const tryToSubmitChallenge = debounce(submitChallenge, 2000); + const tryToSubmitChallenge = debounce(submitChallenge, 2000, {leading: true}); return (
bindActionCreators( { + submitChallenge, updateChallengeMeta, challengeMounted, updateSolutionFormValues, - openCompletionModal: () => openModal('completion') }, dispatch ); @@ -51,7 +47,7 @@ interface ProjectProps { challengeMounted: (arg0: string) => void; data: { challengeNode: ChallengeNode }; isChallengeCompleted: boolean; - openCompletionModal: () => void; + submitChallenge: () => void; pageContext: { challengeMeta: ChallengeMeta; }; @@ -60,13 +56,24 @@ interface ProjectProps { updateSolutionFormValues: () => void; } +interface ProjectState { + completed: boolean; + hasErrors: boolean; +} + // Component -class Project extends Component { +class Project extends Component { static displayName: string; private _container: HTMLElement | null = null; constructor(props: ProjectProps) { super(props); + + this.state = { + completed: false, + hasErrors: false, + }; + this.handleSubmit = this.handleSubmit.bind(this); } componentDidMount() { @@ -120,12 +127,15 @@ class Project extends Component { } handleSubmit({ - showCompletionModal + completed }: { - showCompletionModal: boolean; + completed: boolean; }): void { - if (showCompletionModal) { - this.props.openCompletionModal(); + this.setState({completed, hasErrors: !completed}); + + const { submitChallenge } = this.props; + if (completed) { + submitChallenge(); } } @@ -135,13 +145,10 @@ class Project extends Component { challengeNode: { challenge: { challengeType, - fields: { blockName }, - forumTopicId, title, description, instructions, superBlock, - certification, block, translationPending } @@ -192,19 +199,8 @@ class Project extends Component { onSubmit={this.handleSubmit} updateSolutionForm={updateSolutionFormValues} /> - -
- - diff --git a/client/src/templates/Challenges/projects/solution-form.tsx b/client/src/templates/Challenges/projects/solution-form.tsx index b5a43cce74986a..712081077fb0a0 100644 --- a/client/src/templates/Challenges/projects/solution-form.tsx +++ b/client/src/templates/Challenges/projects/solution-form.tsx @@ -12,7 +12,7 @@ import { import { Form, ValidatedValues } from '../../../components/formHelpers'; interface SubmitProps { - showCompletionModal: boolean; + completed: boolean; } interface FormProps extends WithTranslation { @@ -38,9 +38,9 @@ export class SolutionForm extends Component { // updates values on store this.props.updateSolutionForm(validatedValues.values); if (validatedValues.invalidValues.length === 0) { - this.props.onSubmit({ showCompletionModal: true }); + this.props.onSubmit({ completed: true }); } else { - this.props.onSubmit({ showCompletionModal: false }); + this.props.onSubmit({ completed: false }); } } }; @@ -57,7 +57,7 @@ export class SolutionForm extends Component { { name: 'githubLink', label: t('learn.github-link') } ]; - const buttonCopy = t('learn.i-completed'); + const buttonCopy = t('learn.submit-and-go'); const options = { types: { diff --git a/client/src/templates/Challenges/video/Show.tsx b/client/src/templates/Challenges/video/Show.tsx index ecf7bda07b9190..b414ace77f6a81 100644 --- a/client/src/templates/Challenges/video/Show.tsx +++ b/client/src/templates/Challenges/video/Show.tsx @@ -11,6 +11,8 @@ import type { Dispatch } from 'redux'; import { createSelector } from 'reselect'; // Local Utilities +import Fail from '../../../assets/icons/test-fail'; +import GreenPass from '../../../assets/icons/test-pass'; import Loader from '../../../components/helpers/loader'; import Spacer from '../../../components/helpers/spacer'; import LearnLayout from '../../../components/layouts/learn'; @@ -18,14 +20,13 @@ import { ChallengeNode, ChallengeMeta } from '../../../redux/prop-types'; import ChallengeDescription from '../components/Challenge-Description'; import Hotkeys from '../components/Hotkeys'; import VideoPlayer from '../components/VideoPlayer'; -import ChallengeTitle from '../components/challenge-title'; import CompletionModal from '../components/completion-modal'; import PrismFormatted from '../components/prism-formatted'; import { isChallengeCompletedSelector, challengeMounted, updateChallengeMeta, - openModal, + submitChallenge, updateSolutionFormValues } from '../redux'; @@ -42,10 +43,10 @@ const mapStateToProps = createSelector( const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators( { + submitChallenge, updateChallengeMeta, challengeMounted, updateSolutionFormValues, - openCompletionModal: () => openModal('completion') }, dispatch ); @@ -56,16 +57,17 @@ interface ShowVideoProps { data: { challengeNode: ChallengeNode }; description: string; isChallengeCompleted: boolean; - openCompletionModal: () => void; pageContext: { challengeMeta: ChallengeMeta; }; + submitChallenge: () => void; t: TFunction; updateChallengeMeta: (arg0: ChallengeMeta) => void; updateSolutionFormValues: () => void; } interface ShowVideoState { + completed: boolean; subtitles: string; downloadURL: string | null; selectedOption: number | null; @@ -87,7 +89,8 @@ class ShowVideo extends Component { selectedOption: null, answer: 1, showWrong: false, - videoIsLoaded: false + videoIsLoaded: false, + completed: false }; this.handleSubmit = this.handleSubmit.bind(this); @@ -143,12 +146,12 @@ class ShowVideo extends Component { } } - handleSubmit(solution: number, openCompletionModal: () => void) { + handleSubmit(solution: number) { if (solution - 1 === this.state.selectedOption) { this.setState({ + completed: true, showWrong: false }); - openCompletionModal(); } else { this.setState({ showWrong: true @@ -190,11 +193,11 @@ class ShowVideo extends Component { } } }, - openCompletionModal, pageContext: { challengeMeta: { nextChallengePath, prevChallengePath } }, t, + submitChallenge, isChallengeCompleted } = this.props; @@ -203,9 +206,7 @@ class ShowVideo extends Component { )} - ${title}`; return ( { - this.handleSubmit(solution, openCompletionModal); - }} + executeChallenge={() => this.handleSubmit(solution)} innerRef={(c: HTMLElement | null) => (this._container = c)} nextChallengePath={nextChallengePath} prevChallengePath={prevChallengePath} @@ -216,16 +217,6 @@ class ShowVideo extends Component { /> - - - {title} - -
{!this.state.videoIsLoaded ? ( @@ -243,9 +234,15 @@ class ShowVideo extends Component { />
+ +

+ Question +

+ + - +
@@ -276,28 +273,41 @@ class ShowVideo extends Component {
-
- {this.state.showWrong ? ( - {t('learn.wrong-answer')} - ) : ( +
+ {this.state.showWrong && ( + + + {t('learn.wrong-answer')} + + )} + {this.state.completed && ( + + + Great Job! + + )} + + {!this.state.completed && !this.state.showWrong && ( {t('learn.check-answer')} )}
- - + {this.state.completed ? ( + + ) : ( + + )} label { margin: 0; - align-items: center; + align-items: flex-start; overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--quaternary-background) var(--secondary-background); @@ -54,31 +54,28 @@ } .video-quiz-option-label { - padding: 20px; + padding: 10px 0; cursor: pointer; display: flex; font-weight: normal; - border-left: 4px solid var(--tertiary-background); - border-right: 4px solid var(--tertiary-background); - border-top: 2px solid var(--tertiary-background); - border-bottom: 2px solid var(--tertiary-background); } .video-quiz-option-label:first-child { - border-top: 4px solid var(--tertiary-background); + padding-top: 0; } .video-quiz-option-label:last-child { - border-bottom: 4px solid var(--tertiary-background); + padding-bottom: 0; } + .video-quiz-input-hidden { position: absolute; left: -9999px; } .video-quiz-input-visible { - margin-right: 15px; + margin-right: 8px; position: relative; top: 2px; display: inline-block; @@ -87,8 +84,12 @@ max-width: 20px; max-height: 20px; border-radius: 50%; - background-color: var(--secondary-background); - border: 2px solid var(--primary-color); + background-color: var(--tc-white); + border: 1px solid var(--tc-black-60); +} + +.video-quiz-input-visible:not(:empty) { + border-color: var(--tc-turq-160); } .video-quiz-selected-input { @@ -97,7 +98,7 @@ position: absolute; top: 50%; left: 50%; - background-color: var(--primary-color); + background-color: var(--tc-turq-160); border-radius: 50%; transform: translate(-50%, -50%); } @@ -114,3 +115,47 @@ /* remove default prism background */ background: none; } + +.challenge-instructions { + color: var(--tc-black-100); +} + +.challenge-instructions:not(:empty) { + margin-bottom: 18px; +} + +.video-description .line-numbers > p:first-child { + font-family: 'Roboto'; + font-weight: bold; + line-height: 26px; + font-size: 20px; + color: var(--tc-black-100); +} + +.video-quiz-cta-text { + font-size: 16px; + line-height: 24px; + font-family: 'Roboto'; + color: var(--tc-black-100); + margin-bottom: 24px; +} + +.video-quiz-cta-text > span { + display: flex; + align-items: center; + gap: 12px; +} + +.video-section-label { + font-size: 18px; + font-weight: 600; + font-family: 'Barlow', 'sans-serif'; + line-height: 22px; + color: var(--tc-black-100); + text-transform: uppercase; + + border-top: 1px solid var(--tc-black-10); + margin-top: 32px; + padding-top: 18px; + margin-bottom: 24px; +} From f68c31ab574d33409e977df0a681a423b3596134 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Mon, 15 Aug 2022 11:32:22 +0300 Subject: [PATCH 4/4] TCA-299 - handle lint fixes --- .../components/formHelpers/form-fields.tsx | 2 +- client/src/components/layouts/prism.css | 2 +- client/src/components/layouts/variables.css | 2 +- .../Challenges/classic/action-row.tsx | 1 - .../templates/Challenges/classic/editor.tsx | 4 +++- .../Challenges/classic/simple-editor.tsx | 4 +++- .../templates/Challenges/codeally/show.tsx | 15 ++++++------ .../Challenges/components/tool-panel.tsx | 4 +++- .../Challenges/projects/backend/Show.tsx | 8 ++----- .../Challenges/projects/frontend/Show.tsx | 14 ++++------- .../src/templates/Challenges/video/Show.tsx | 24 ++++++++++++------- .../src/templates/Challenges/video/show.css | 1 - 12 files changed, 41 insertions(+), 40 deletions(-) diff --git a/client/src/components/formHelpers/form-fields.tsx b/client/src/components/formHelpers/form-fields.tsx index edb8a8e65ac294..a34fd4c669f1c6 100644 --- a/client/src/components/formHelpers/form-fields.tsx +++ b/client/src/components/formHelpers/form-fields.tsx @@ -84,7 +84,7 @@ function FormFields(props: FormFieldsProps): JSX.Element { name in placeholders ? placeholders[name] : ''; const isURL = types[name] === 'url'; return ( - + {type === 'hidden' ? null : ( {label} )} diff --git a/client/src/components/layouts/prism.css b/client/src/components/layouts/prism.css index df045354a0089b..5a165b2581bdd6 100644 --- a/client/src/components/layouts/prism.css +++ b/client/src/components/layouts/prism.css @@ -1,4 +1,4 @@ -pre[class*="language-"].line-numbers.line-numbers { +pre[class*='language-'].line-numbers.line-numbers { border-radius: 8px; font-size: 14px; line-height: 22px; diff --git a/client/src/components/layouts/variables.css b/client/src/components/layouts/variables.css index 5f7b45774e5367..2d757df343facc 100644 --- a/client/src/components/layouts/variables.css +++ b/client/src/components/layouts/variables.css @@ -37,7 +37,7 @@ --tc-link-blue-light: #5fb7ee; --tc-black: #000; --tc-black-100: #2a2a2a; - --tc-black-60: #7F7F7F; + --tc-black-60: #7f7f7f; --tc-black-40: #aaaaaa; --tc-black-20: #d4d4d4; --tc-black-10: #e9e9e9; diff --git a/client/src/templates/Challenges/classic/action-row.tsx b/client/src/templates/Challenges/classic/action-row.tsx index 4025f1b69c4443..e90562294d767a 100644 --- a/client/src/templates/Challenges/classic/action-row.tsx +++ b/client/src/templates/Challenges/classic/action-row.tsx @@ -30,7 +30,6 @@ const ActionRow = ({ togglePane, showNotes, showPreview, - isMultifileCertProject, showInstructions, showConsole, superBlock, diff --git a/client/src/templates/Challenges/classic/editor.tsx b/client/src/templates/Challenges/classic/editor.tsx index ba1a69ae3002a6..58174c3309e202 100644 --- a/client/src/templates/Challenges/classic/editor.tsx +++ b/client/src/templates/Challenges/classic/editor.tsx @@ -573,7 +573,9 @@ const Editor = (props: EditorProps): JSX.Element => { attemptRef.current.attempts++; } - const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, {leading: true}); + const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, { + leading: true + }); function createLowerJaw(outputNode: HTMLElement, callback?: () => void) { const { output } = props; diff --git a/client/src/templates/Challenges/classic/simple-editor.tsx b/client/src/templates/Challenges/classic/simple-editor.tsx index abafe4feb36d10..1049bcf8e05f8b 100755 --- a/client/src/templates/Challenges/classic/simple-editor.tsx +++ b/client/src/templates/Challenges/classic/simple-editor.tsx @@ -513,7 +513,9 @@ const SimpleEditor = (props: EditorProps): JSX.Element => { attemptRef.current.attempts++; } - const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, {leading: true}); + const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, { + leading: true + }); function resetMarginDecorations() { const { model, insideEditDecId } = dataRef.current; diff --git a/client/src/templates/Challenges/codeally/show.tsx b/client/src/templates/Challenges/codeally/show.tsx index 6fd66637a15a8b..1a5c33315b13d5 100644 --- a/client/src/templates/Challenges/codeally/show.tsx +++ b/client/src/templates/Challenges/codeally/show.tsx @@ -33,6 +33,7 @@ import { isChallengeCompletedSelector, updateChallengeMeta, openModal, + submitChallenge, updateSolutionFormValues } from '../redux'; import { createFlashMessage } from '../../../components/Flash/redux'; @@ -76,6 +77,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators( { challengeMounted, + submitChallenge, createFlashMessage, hideCodeAlly, openCompletionModal: () => openModal('completion'), @@ -93,6 +95,7 @@ interface ShowCodeAllyProps { createFlashMessage: typeof createFlashMessage; data: { challengeNode: ChallengeNode }; hideCodeAlly: () => void; + submitChallenge: () => void; isChallengeCompleted: boolean; isSignedIn: boolean; openCompletionModal: () => void; @@ -138,11 +141,7 @@ class ShowCodeAlly extends Component { this.props.hideCodeAlly(); } - handleSubmit = ({ - showCompletionModal - }: { - showCompletionModal: boolean; - }) => { + handleSubmit = ({ completed }: { completed: boolean }) => { const { completedChallenges, createFlashMessage, @@ -151,7 +150,7 @@ class ShowCodeAlly extends Component { challenge: { id: challengeId } } }, - openCompletionModal, + submitChallenge, partiallyCompletedChallenges } = this.props; @@ -168,8 +167,8 @@ class ShowCodeAlly extends Component { type: 'danger', message: FlashMessages.CompleteProjectFirst }); - } else if (showCompletionModal) { - openCompletionModal(); + } else if (completed) { + submitChallenge(); } }; diff --git a/client/src/templates/Challenges/components/tool-panel.tsx b/client/src/templates/Challenges/components/tool-panel.tsx index 0195124909ee8a..47afd0ed8256d1 100644 --- a/client/src/templates/Challenges/components/tool-panel.tsx +++ b/client/src/templates/Challenges/components/tool-panel.tsx @@ -74,7 +74,9 @@ function ToolPanel({ const { t } = useTranslation(); - const tryToSubmitChallenge = debounce(submitChallenge, 2000, {leading: true}); + const tryToSubmitChallenge = debounce(submitChallenge, 2000, { + leading: true + }); return (
{ challengeMounted(challengeMeta.id); } - handleSubmit({ - showCompletionModal - }: { - showCompletionModal: boolean; - }): void { + handleSubmit(): void { this.props.executeChallenge({ - showCompletionModal + showCompletionModal: false }); } diff --git a/client/src/templates/Challenges/projects/frontend/Show.tsx b/client/src/templates/Challenges/projects/frontend/Show.tsx index 5e559f76f5fb0a..a7e8dccf6dd29a 100644 --- a/client/src/templates/Challenges/projects/frontend/Show.tsx +++ b/client/src/templates/Challenges/projects/frontend/Show.tsx @@ -1,4 +1,4 @@ -import { Button, Grid, Col, Row } from '@freecodecamp/react-bootstrap'; +import { Grid, Col, Row } from '@freecodecamp/react-bootstrap'; import { graphql } from 'gatsby'; import React, { Component } from 'react'; import Helmet from 'react-helmet'; @@ -37,7 +37,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => submitChallenge, updateChallengeMeta, challengeMounted, - updateSolutionFormValues, + updateSolutionFormValues }, dispatch ); @@ -71,7 +71,7 @@ class Project extends Component { this.state = { completed: false, - hasErrors: false, + hasErrors: false }; this.handleSubmit = this.handleSubmit.bind(this); @@ -126,12 +126,8 @@ class Project extends Component { } } - handleSubmit({ - completed - }: { - completed: boolean; - }): void { - this.setState({completed, hasErrors: !completed}); + handleSubmit({ completed }: { completed: boolean }): void { + this.setState({ completed, hasErrors: !completed }); const { submitChallenge } = this.props; if (completed) { diff --git a/client/src/templates/Challenges/video/Show.tsx b/client/src/templates/Challenges/video/Show.tsx index b414ace77f6a81..d95b72a2026502 100644 --- a/client/src/templates/Challenges/video/Show.tsx +++ b/client/src/templates/Challenges/video/Show.tsx @@ -46,7 +46,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => submitChallenge, updateChallengeMeta, challengeMounted, - updateSolutionFormValues, + updateSolutionFormValues }, dispatch ); @@ -185,7 +185,6 @@ class ShowVideo extends Component { superBlock, certification, block, - translationPending, videoId, videoLocaleIds, bilibiliIds, @@ -197,8 +196,7 @@ class ShowVideo extends Component { challengeMeta: { nextChallengePath, prevChallengePath } }, t, - submitChallenge, - isChallengeCompleted + submitChallenge } = this.props; const blockNameTitle = `${t( @@ -236,13 +234,21 @@ class ShowVideo extends Component { -

- Question -

+

Question

- + - +
diff --git a/client/src/templates/Challenges/video/show.css b/client/src/templates/Challenges/video/show.css index 577c462fdcd6ad..9fe0605dfe4376 100644 --- a/client/src/templates/Challenges/video/show.css +++ b/client/src/templates/Challenges/video/show.css @@ -68,7 +68,6 @@ padding-bottom: 0; } - .video-quiz-input-hidden { position: absolute; left: -9999px;