mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-06-22 21:08:12 +08:00
feat(client): full width component to carry key prop (#49082)
* feat(client): allow full width to carry key props * fix: setting can't render the element error * Remove the key prop from FullWidthRow Co-authored-by: Shaun Hamilton <shauhami020@gmail.com> * remove key form fullwidth * Remove undefined type from children Co-authored-by: Shaun Hamilton <shauhami020@gmail.com> * add key to renderProfile Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
parent
8d8a4d172e
commit
57317a4a32
@ -1,13 +1,12 @@
|
||||
import { Row, Col } from '@freecodecamp/react-bootstrap';
|
||||
import React from 'react';
|
||||
|
||||
function FullWidthRow({
|
||||
children,
|
||||
className
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
interface FullWidthRowProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}): JSX.Element {
|
||||
}
|
||||
|
||||
const FullWidthRow = ({ children, className }: FullWidthRowProps) => {
|
||||
return (
|
||||
<Row className={className}>
|
||||
<Col sm={8} smOffset={2} xs={12}>
|
||||
@ -15,7 +14,7 @@ function FullWidthRow({
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
FullWidthRow.displayName = 'FullWidthRow';
|
||||
|
||||
|
||||
@ -219,100 +219,96 @@ class PortfolioSettings extends Component<PortfolioProps, PortfolioState> {
|
||||
const { state: descriptionState, message: descriptionMessage } =
|
||||
this.getDescriptionValidation(description);
|
||||
return (
|
||||
<div key={id}>
|
||||
<FullWidthRow>
|
||||
<form onSubmit={e => this.handleSubmit(e, id)}>
|
||||
<FormGroup
|
||||
controlId={`${id}-title`}
|
||||
validationState={
|
||||
pristine || (!pristine && !title) ? null : titleState
|
||||
}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.title')}</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'title')}
|
||||
required={true}
|
||||
type='text'
|
||||
value={title}
|
||||
/>
|
||||
{titleMessage ? <HelpBlock>{titleMessage}</HelpBlock> : null}
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId={`${id}-url`}
|
||||
validationState={
|
||||
pristine || (!pristine && !url) ? null : urlState
|
||||
}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.url')}</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'url')}
|
||||
required={true}
|
||||
type='url'
|
||||
value={url}
|
||||
/>
|
||||
{urlMessage ? <HelpBlock>{urlMessage}</HelpBlock> : null}
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId={`${id}-image`}
|
||||
validationState={pristine ? null : imageState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.image')}</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'image')}
|
||||
type='url'
|
||||
value={image}
|
||||
/>
|
||||
{imageMessage ? <HelpBlock>{imageMessage}</HelpBlock> : null}
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId={`${id}-description`}
|
||||
validationState={pristine ? null : descriptionState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.description')}</ControlLabel>
|
||||
<FormControl
|
||||
componentClass='textarea'
|
||||
onChange={this.createOnChangeHandler(id, 'description')}
|
||||
value={description}
|
||||
/>
|
||||
{descriptionMessage ? (
|
||||
<HelpBlock>{descriptionMessage}</HelpBlock>
|
||||
) : null}
|
||||
</FormGroup>
|
||||
<BlockSaveButton
|
||||
disabled={
|
||||
pristine ||
|
||||
!title ||
|
||||
!isURL(url, {
|
||||
protocols: ['http', 'https'],
|
||||
/* eslint-disable camelcase, @typescript-eslint/naming-convention */
|
||||
require_tld: true,
|
||||
require_protocol: true
|
||||
/* eslint-enable camelcase, @typescript-eslint/naming-convention */
|
||||
})
|
||||
}
|
||||
>
|
||||
{t('buttons.save-portfolio')}
|
||||
</BlockSaveButton>
|
||||
<ButtonSpacer />
|
||||
<Button
|
||||
block={true}
|
||||
bsSize='lg'
|
||||
bsStyle='danger'
|
||||
onClick={() => this.handleRemoveItem(id)}
|
||||
type='button'
|
||||
>
|
||||
{t('buttons.remove-portfolio')}
|
||||
</Button>
|
||||
</form>
|
||||
{index + 1 !== arr.length && (
|
||||
<>
|
||||
<Spacer />
|
||||
<hr />
|
||||
<Spacer />
|
||||
</>
|
||||
)}
|
||||
</FullWidthRow>
|
||||
</div>
|
||||
<FullWidthRow key={id}>
|
||||
<form onSubmit={e => this.handleSubmit(e, id)}>
|
||||
<FormGroup
|
||||
controlId={`${id}-title`}
|
||||
validationState={
|
||||
pristine || (!pristine && !title) ? null : titleState
|
||||
}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.title')}</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'title')}
|
||||
required={true}
|
||||
type='text'
|
||||
value={title}
|
||||
/>
|
||||
{titleMessage ? <HelpBlock>{titleMessage}</HelpBlock> : null}
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId={`${id}-url`}
|
||||
validationState={pristine || (!pristine && !url) ? null : urlState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.url')}</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'url')}
|
||||
required={true}
|
||||
type='url'
|
||||
value={url}
|
||||
/>
|
||||
{urlMessage ? <HelpBlock>{urlMessage}</HelpBlock> : null}
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId={`${id}-image`}
|
||||
validationState={pristine ? null : imageState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.image')}</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'image')}
|
||||
type='url'
|
||||
value={image}
|
||||
/>
|
||||
{imageMessage ? <HelpBlock>{imageMessage}</HelpBlock> : null}
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId={`${id}-description`}
|
||||
validationState={pristine ? null : descriptionState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.description')}</ControlLabel>
|
||||
<FormControl
|
||||
componentClass='textarea'
|
||||
onChange={this.createOnChangeHandler(id, 'description')}
|
||||
value={description}
|
||||
/>
|
||||
{descriptionMessage ? (
|
||||
<HelpBlock>{descriptionMessage}</HelpBlock>
|
||||
) : null}
|
||||
</FormGroup>
|
||||
<BlockSaveButton
|
||||
disabled={
|
||||
pristine ||
|
||||
!title ||
|
||||
!isURL(url, {
|
||||
protocols: ['http', 'https'],
|
||||
/* eslint-disable camelcase, @typescript-eslint/naming-convention */
|
||||
require_tld: true,
|
||||
require_protocol: true
|
||||
/* eslint-enable camelcase, @typescript-eslint/naming-convention */
|
||||
})
|
||||
}
|
||||
>
|
||||
{t('buttons.save-portfolio')}
|
||||
</BlockSaveButton>
|
||||
<ButtonSpacer />
|
||||
<Button
|
||||
block={true}
|
||||
bsSize='lg'
|
||||
bsStyle='danger'
|
||||
onClick={() => this.handleRemoveItem(id)}
|
||||
type='button'
|
||||
>
|
||||
{t('buttons.remove-portfolio')}
|
||||
</Button>
|
||||
</form>
|
||||
{index + 1 !== arr.length && (
|
||||
<>
|
||||
<Spacer />
|
||||
<hr />
|
||||
<Spacer />
|
||||
</>
|
||||
)}
|
||||
</FullWidthRow>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user