Skip to content

Commit ab3b7d0

Browse files
committed
TCA-299 - improve UI for old style editor
1 parent 7235bfc commit ab3b7d0

File tree

14 files changed

+209
-130
lines changed

14 files changed

+209
-130
lines changed

client/src/components/formHelpers/block-save-button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
55
function BlockSaveButton(props?: Record<string, unknown>): JSX.Element {
66
const { t } = useTranslation();
77
return (
8-
<Button block={true} bsStyle='primary' {...props} type='submit'>
8+
<Button bsStyle='primary' {...props} type='submit'>
99
{props?.children || t('buttons.save')}
1010
</Button>
1111
);

client/src/components/formHelpers/form-fields.tsx

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
Alert,
3-
Col,
43
ControlLabel,
54
FormControl,
65
FormGroup,
@@ -72,7 +71,7 @@ function FormFields(props: FormFieldsProps): JSX.Element {
7271
) : null;
7372
};
7473
return (
75-
<div>
74+
<>
7675
{formFields
7776
.filter(formField => !ignored.includes(formField.name))
7877
.map(({ name, label }) => (
@@ -85,35 +84,33 @@ function FormFields(props: FormFieldsProps): JSX.Element {
8584
name in placeholders ? placeholders[name] : '';
8685
const isURL = types[name] === 'url';
8786
return (
88-
<Col key={key} xs={12}>
89-
<FormGroup>
90-
{type === 'hidden' ? null : (
91-
<ControlLabel htmlFor={key}>{label}</ControlLabel>
92-
)}
93-
<FormControl
94-
componentClass={type === 'textarea' ? type : 'input'}
95-
id={key}
96-
name={name}
97-
onChange={onChange}
98-
placeholder={placeholder}
99-
required={required.includes(name)}
100-
rows={4}
101-
type={type}
102-
value={value as string}
103-
/>
104-
{nullOrWarning(
105-
value as string,
106-
!pristine && error,
107-
isURL,
108-
name
109-
)}
110-
</FormGroup>
111-
</Col>
87+
<FormGroup key={key} className="embedded">
88+
{type === 'hidden' ? null : (
89+
<ControlLabel htmlFor={key}>{label}</ControlLabel>
90+
)}
91+
<FormControl
92+
componentClass={type === 'textarea' ? type : 'input'}
93+
id={key}
94+
name={name}
95+
onChange={onChange}
96+
placeholder={placeholder}
97+
required={required.includes(name)}
98+
rows={4}
99+
type={type}
100+
value={value as string}
101+
/>
102+
{nullOrWarning(
103+
value as string,
104+
!pristine && error,
105+
isURL,
106+
name
107+
)}
108+
</FormGroup>
112109
);
113110
}}
114111
</Field>
115112
))}
116-
</div>
113+
</>
117114
);
118115
}
119116

client/src/components/formHelpers/form.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
ValidatedValues,
77
FormFields,
88
BlockSaveButton,
9-
BlockSaveWrapper,
109
formatUrlValues
1110
} from '../formHelpers/index';
1211

@@ -54,15 +53,13 @@ function DynamicForm({
5453
style={{ width: '100%' }}
5554
>
5655
<FormFields formFields={formFields} options={options} />
57-
<BlockSaveWrapper>
58-
{hideButton ? null : (
59-
<BlockSaveButton
60-
disabled={(pristine && !enableSubmit) || (error as boolean)}
61-
>
62-
{buttonText ? buttonText : null}
63-
</BlockSaveButton>
64-
)}
65-
</BlockSaveWrapper>
56+
{!hideButton && (
57+
<BlockSaveButton
58+
disabled={(pristine && !enableSubmit) || (error as boolean)}
59+
>
60+
{buttonText ? buttonText : null}
61+
</BlockSaveButton>
62+
)}
6663
</form>
6764
)}
6865
</Form>

client/src/components/layouts/global.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,33 @@ strong {
501501
color: var(--secondary-color);
502502
}
503503

504+
.form-group.embedded {
505+
border: 1px solid var(--tc-black-40);
506+
padding: 8px 10px 2px;
507+
border-radius: 4px;
508+
position: relative;
509+
max-width: 320px;
510+
}
511+
512+
.form-group.embedded .control-label {
513+
display: block;
514+
font-size: 11px;
515+
font-family: 'Roboto';
516+
line-height: 10px;
517+
color: var(--tc-turq-160);
518+
margin-bottom: 4px;
519+
}
520+
521+
.form-group.embedded .form-control {
522+
border: 0 none;
523+
padding: 0;
524+
height: 22px;
525+
font-size: 14px;
526+
line-height: 22px;
527+
font-family: 'Roboto';
528+
color: var(--tc-black-100);
529+
}
530+
504531
.form-control {
505532
color: var(--primary-color);
506533
outline: none;

client/src/components/layouts/prism.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
pre[class*="language-"].line-numbers.line-numbers {
2+
border-radius: 8px;
3+
font-size: 14px;
4+
line-height: 22px;
5+
}
6+
17
code .token.operator {
28
background: none;
39
}
@@ -7,6 +13,10 @@ pre[class*='language-'] {
713
background: var(--primary-background);
814
}
915

16+
.line-numbers > p {
17+
color: var(--tc-black-100);
18+
}
19+
1020
.default pre[class*='language-']::selection,
1121
.default pre[class*='language-'] ::selection,
1222
.default code[class*='language-']::selection,

client/src/components/layouts/variables.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
--tc-link-blue-light: #5fb7ee;
3838
--tc-black: #000;
3939
--tc-black-100: #2a2a2a;
40+
--tc-black-60: #7F7F7F;
41+
--tc-black-40: #aaaaaa;
4042
--tc-black-20: #d4d4d4;
4143
--tc-black-10: #e9e9e9;
4244
--tc-black-5: #f4f4f4;

client/src/templates/Challenges/classic/editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ const Editor = (props: EditorProps): JSX.Element => {
573573
attemptRef.current.attempts++;
574574
}
575575

576-
const tryToSubmitChallenge = debounce(props.submitChallenge, 2000);
576+
const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, {leading: true});
577577

578578
function createLowerJaw(outputNode: HTMLElement, callback?: () => void) {
579579
const { output } = props;

client/src/templates/Challenges/classic/simple-editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ const SimpleEditor = (props: EditorProps): JSX.Element => {
513513
attemptRef.current.attempts++;
514514
}
515515

516-
const tryToSubmitChallenge = debounce(props.submitChallenge, 2000);
516+
const tryToSubmitChallenge = debounce(props.submitChallenge, 2000, {leading: true});
517517

518518
function resetMarginDecorations() {
519519
const { model, insideEditDecId } = dataRef.current;

client/src/templates/Challenges/components/challenge-title.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import i18next from 'i18next';
22
import React from 'react';
33
import GreenPass from '../../../assets/icons/green-pass';
44
import { Link } from '../../../components/helpers/index';
5-
import BreadCrumb from './bread-crumb';
65

76
import './challenge-title.css';
87

@@ -16,11 +15,8 @@ interface ChallengeTitleProps {
1615
}
1716

1817
function ChallengeTitle({
19-
block,
2018
children,
2119
isCompleted,
22-
showBreadCrumbs = true,
23-
superBlock,
2420
translationPending
2521
}: ChallengeTitleProps): JSX.Element {
2622
return (
@@ -36,7 +32,6 @@ function ChallengeTitle({
3632
</Link>
3733
</>
3834
)}
39-
{showBreadCrumbs && <BreadCrumb block={block} superBlock={superBlock} />}
4035
<div className='challenge-title'>
4136
<div className='title-text'>
4237
<h1>{children}</h1>

client/src/templates/Challenges/components/tool-panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function ToolPanel({
7474

7575
const { t } = useTranslation();
7676

77-
const tryToSubmitChallenge = debounce(submitChallenge, 2000);
77+
const tryToSubmitChallenge = debounce(submitChallenge, 2000, {leading: true});
7878

7979
return (
8080
<div

client/src/templates/Challenges/projects/frontend/Show.tsx

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Grid, Col, Row } from '@freecodecamp/react-bootstrap';
1+
import { Button, Grid, Col, Row } from '@freecodecamp/react-bootstrap';
22
import { graphql } from 'gatsby';
33
import React, { Component } from 'react';
44
import Helmet from 'react-helmet';
@@ -14,18 +14,14 @@ import { ChallengeNode, ChallengeMeta } from '../../../../redux/prop-types';
1414
import ChallengeDescription from '../../components/Challenge-Description';
1515
import Hotkeys from '../../components/Hotkeys';
1616
import ChallengeTitle from '../../components/challenge-title';
17-
import CompletionModal from '../../components/completion-modal';
18-
import HelpModal from '../../components/help-modal';
1917
import {
2018
challengeMounted,
2119
isChallengeCompletedSelector,
20+
submitChallenge,
2221
updateChallengeMeta,
23-
openModal,
2422
updateSolutionFormValues
2523
} from '../../redux';
26-
import { getGuideUrl } from '../../utils';
2724
import SolutionForm from '../solution-form';
28-
import ProjectToolPanel from '../tool-panel';
2925

3026
// Redux Setup
3127
const mapStateToProps = createSelector(
@@ -38,10 +34,10 @@ const mapStateToProps = createSelector(
3834
const mapDispatchToProps = (dispatch: Dispatch) =>
3935
bindActionCreators(
4036
{
37+
submitChallenge,
4138
updateChallengeMeta,
4239
challengeMounted,
4340
updateSolutionFormValues,
44-
openCompletionModal: () => openModal('completion')
4541
},
4642
dispatch
4743
);
@@ -51,7 +47,7 @@ interface ProjectProps {
5147
challengeMounted: (arg0: string) => void;
5248
data: { challengeNode: ChallengeNode };
5349
isChallengeCompleted: boolean;
54-
openCompletionModal: () => void;
50+
submitChallenge: () => void;
5551
pageContext: {
5652
challengeMeta: ChallengeMeta;
5753
};
@@ -60,13 +56,24 @@ interface ProjectProps {
6056
updateSolutionFormValues: () => void;
6157
}
6258

59+
interface ProjectState {
60+
completed: boolean;
61+
hasErrors: boolean;
62+
}
63+
6364
// Component
64-
class Project extends Component<ProjectProps> {
65+
class Project extends Component<ProjectProps, ProjectState> {
6566
static displayName: string;
6667
private _container: HTMLElement | null = null;
6768

6869
constructor(props: ProjectProps) {
6970
super(props);
71+
72+
this.state = {
73+
completed: false,
74+
hasErrors: false,
75+
};
76+
7077
this.handleSubmit = this.handleSubmit.bind(this);
7178
}
7279
componentDidMount() {
@@ -120,12 +127,15 @@ class Project extends Component<ProjectProps> {
120127
}
121128

122129
handleSubmit({
123-
showCompletionModal
130+
completed
124131
}: {
125-
showCompletionModal: boolean;
132+
completed: boolean;
126133
}): void {
127-
if (showCompletionModal) {
128-
this.props.openCompletionModal();
134+
this.setState({completed, hasErrors: !completed});
135+
136+
const { submitChallenge } = this.props;
137+
if (completed) {
138+
submitChallenge();
129139
}
130140
}
131141

@@ -135,13 +145,10 @@ class Project extends Component<ProjectProps> {
135145
challengeNode: {
136146
challenge: {
137147
challengeType,
138-
fields: { blockName },
139-
forumTopicId,
140148
title,
141149
description,
142150
instructions,
143151
superBlock,
144-
certification,
145152
block,
146153
translationPending
147154
}
@@ -192,19 +199,8 @@ class Project extends Component<ProjectProps> {
192199
onSubmit={this.handleSubmit}
193200
updateSolutionForm={updateSolutionFormValues}
194201
/>
195-
<ProjectToolPanel
196-
guideUrl={getGuideUrl({ forumTopicId, title })}
197-
/>
198-
<br />
199202
<Spacer />
200203
</Col>
201-
<CompletionModal
202-
block={block}
203-
blockName={blockName}
204-
certification={certification}
205-
superBlock={superBlock}
206-
/>
207-
<HelpModal />
208204
</Row>
209205
</Grid>
210206
</LearnLayout>

client/src/templates/Challenges/projects/solution-form.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { Form, ValidatedValues } from '../../../components/formHelpers';
1313

1414
interface SubmitProps {
15-
showCompletionModal: boolean;
15+
completed: boolean;
1616
}
1717

1818
interface FormProps extends WithTranslation {
@@ -38,9 +38,9 @@ export class SolutionForm extends Component<FormProps> {
3838
// updates values on store
3939
this.props.updateSolutionForm(validatedValues.values);
4040
if (validatedValues.invalidValues.length === 0) {
41-
this.props.onSubmit({ showCompletionModal: true });
41+
this.props.onSubmit({ completed: true });
4242
} else {
43-
this.props.onSubmit({ showCompletionModal: false });
43+
this.props.onSubmit({ completed: false });
4444
}
4545
}
4646
};
@@ -57,7 +57,7 @@ export class SolutionForm extends Component<FormProps> {
5757
{ name: 'githubLink', label: t('learn.github-link') }
5858
];
5959

60-
const buttonCopy = t('learn.i-completed');
60+
const buttonCopy = t('learn.submit-and-go');
6161

6262
const options = {
6363
types: {

0 commit comments

Comments
 (0)