From 599cbfc649dbc3a8d33f59a96040aa5ec6f1e4f9 Mon Sep 17 00:00:00 2001
From: Adam Butterworth
Date: Fri, 5 Apr 2019 13:07:44 -0400
Subject: [PATCH] refactor: use raw html form elements (#123)
* refactor: use raw html for form elements
* test: update snapshot to reflect minor changes in html output
* refactor: replace all reactstrap with paragon or html
* test: update snapshot
* fix: add a noop to the button in async button if needed
This is a flaw in the Button component in Paragon. It calls props.onClick even if it doesn't exist.
* refactor: use classnames for toggling class names
* fix: remove unneeded ids. fix some form markup
* fix: update snapshot to reflect removed labels
---
.eslintrc | 7 +
package-lock.json | 40 ----
package.json | 3 +-
src/components/ErrorPage.jsx | 42 ++--
src/components/NotFoundPage.jsx | 8 +-
src/components/ProfilePage.jsx | 49 ++---
src/components/ProfilePage/AgeMessage.jsx | 51 +++--
src/components/ProfilePage/Bio.jsx | 23 +--
src/components/ProfilePage/Certificates.jsx | 33 +--
src/components/ProfilePage/Country.jsx | 23 +--
src/components/ProfilePage/Education.jsx | 24 +--
src/components/ProfilePage/Name.jsx | 30 ++-
src/components/ProfilePage/PageLoading.jsx | 3 +-
.../ProfilePage/PreferredLanguage.jsx | 24 +--
src/components/ProfilePage/ProfileAvatar.jsx | 97 ++++-----
src/components/ProfilePage/SocialLinks.jsx | 15 +-
.../elements/AsyncActionButton.jsx | 35 ++--
.../ProfilePage/elements/FormControls.jsx | 22 +-
.../ProfilePage/elements/Visibility.jsx | 5 +-
.../__snapshots__/ProfilePage.test.jsx.snap | 188 +++++++++++-------
src/index.scss | 12 ++
21 files changed, 372 insertions(+), 362 deletions(-)
diff --git a/.eslintrc b/.eslintrc
index a0125d9..ba8734a 100755
--- a/.eslintrc
+++ b/.eslintrc
@@ -16,6 +16,13 @@
"jsx-a11y/anchor-is-valid": [ "error", {
"components": [ "Link" ],
"specialLink": [ "to" ]
+ }],
+ "jsx-a11y/label-has-for": [ 2, {
+ "components": [ "label" ],
+ "required": {
+ "some": [ "nesting", "id" ]
+ },
+ "allowChildren": false
}]
},
"env": {
diff --git a/package-lock.json b/package-lock.json
index 89ada31..2243c3f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13933,16 +13933,6 @@
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
"dev": true
},
- "lodash.isfunction": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
- "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw=="
- },
- "lodash.isobject": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz",
- "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0="
- },
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -14009,11 +13999,6 @@
"integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
"dev": true
},
- "lodash.tonumber": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz",
- "integrity": "sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk="
- },
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@@ -18792,15 +18777,6 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
- "react-popper": {
- "version": "0.10.4",
- "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-0.10.4.tgz",
- "integrity": "sha1-rypBXqIike3VBGeNev2opu4ylao=",
- "requires": {
- "popper.js": "^1.14.1",
- "prop-types": "^15.6.1"
- }
- },
"react-proptype-conditional-require": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/react-proptype-conditional-require/-/react-proptype-conditional-require-1.0.4.tgz",
@@ -18912,22 +18888,6 @@
"integrity": "sha512-HH2N/b5tRxh7ypIgCRsiBl/CTxRkTEPf9DhIstaM6hne4WiwM5/bBbWuvVlRZc/i3FdqZED3pZ//6n4mtxma4w==",
"dev": true
},
- "reactstrap": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-7.1.0.tgz",
- "integrity": "sha512-wtc4RkgnGn1TsZ0AxOZ2OqT+b8YmCWZj/tErPujWLepxzlEEhveZGC+uDerdaHVSAzJUP2DTk605iper7hutQQ==",
- "requires": {
- "@babel/runtime": "^7.2.0",
- "classnames": "^2.2.3",
- "lodash.isfunction": "^3.0.9",
- "lodash.isobject": "^3.0.2",
- "lodash.tonumber": "^4.0.3",
- "prop-types": "^15.5.8",
- "react-lifecycles-compat": "^3.0.4",
- "react-popper": "^0.10.4",
- "react-transition-group": "^2.3.1"
- }
- },
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
diff --git a/package.json b/package.json
index 063ecda..481ef4c 100755
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
"@fortawesome/react-fontawesome": "^0.1.4",
"babel-polyfill": "^6.26.0",
"bootstrap": "^4.2.1",
- "classnames": "^2.2.5",
+ "classnames": "^2.2.6",
"connected-react-router": "^5.0.1",
"email-prop-type": "^1.1.5",
"font-awesome": "^4.7.0",
@@ -59,7 +59,6 @@
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-transition-group": "^2.5.3",
- "reactstrap": "^7.1.0",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.2",
"redux-logger": "^3.0.6",
diff --git a/src/components/ErrorPage.jsx b/src/components/ErrorPage.jsx
index a24a75b..7fc2e77 100644
--- a/src/components/ErrorPage.jsx
+++ b/src/components/ErrorPage.jsx
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import { Button, Col, Container, Row } from 'reactstrap';
+import { Button } from '@edx/paragon';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
@@ -12,12 +12,9 @@ export default class ErrorPage extends Component {
const { username } = apiClient.getAuthenticationState().authentication;
return (
-
-
-
+
+
+
+
-
-
-
+
+ }
+ />
-
-
-
+
+
+
);
}
}
diff --git a/src/components/NotFoundPage.jsx b/src/components/NotFoundPage.jsx
index 9e0077c..0a4807f 100644
--- a/src/components/NotFoundPage.jsx
+++ b/src/components/NotFoundPage.jsx
@@ -1,5 +1,4 @@
import React, { Component } from 'react';
-import { Container } from 'reactstrap';
import { FormattedMessage } from 'react-intl';
export default class NotFoundPage extends Component {
@@ -7,10 +6,7 @@ export default class NotFoundPage extends Component {
render() {
return (
-
+
);
}
}
diff --git a/src/components/ProfilePage.jsx b/src/components/ProfilePage.jsx
index 2bee9a4..c099cce 100644
--- a/src/components/ProfilePage.jsx
+++ b/src/components/ProfilePage.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Container, Row, Col, Alert, Button } from 'reactstrap';
+import { StatusAlert, Hyperlink } from '@edx/paragon';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from 'react-intl';
@@ -89,9 +89,12 @@ export class ProfilePage extends React.Component {
}
return (
-
- {this.props.intl.formatMessage(messages['profile.viewMyRecords'])}
-
+
);
}
@@ -116,11 +119,11 @@ export class ProfilePage extends React.Component {
}
return (
-
-
- {photoUploadError.userMessage}
-
-
+
);
}
@@ -160,9 +163,9 @@ export class ProfilePage extends React.Component {
return (
-
-
-
+
+
+
+
{this.renderHeadingLockup()}
{this.renderViewMyRecordsButton()}
-
-
+
+
{this.renderPhotoUploadErrorMessage()}
-
-
+
+
{this.renderHeadingLockup()}
@@ -224,8 +227,8 @@ export class ProfilePage extends React.Component {
formId="socialLinks"
{...commonFormProps}
/>
-
-
+
+
{shouldShowAgeMessage ?
: null}
-
-
-
+
+
+
);
}
diff --git a/src/components/ProfilePage/AgeMessage.jsx b/src/components/ProfilePage/AgeMessage.jsx
index d7da685..c0ff14c 100644
--- a/src/components/ProfilePage/AgeMessage.jsx
+++ b/src/components/ProfilePage/AgeMessage.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Alert } from 'reactstrap';
+import { StatusAlert } from '@edx/paragon';
import { FormattedMessage } from 'react-intl';
import { configuration } from '../../config/environment';
@@ -8,27 +8,34 @@ const { ACCOUNT_SETTINGS_URL } = configuration;
function AgeMessage() {
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ }
+ dismissible={false}
+ open
+ />
);
}
diff --git a/src/components/ProfilePage/Bio.jsx b/src/components/ProfilePage/Bio.jsx
index e3cc5e0..e64fbdc 100644
--- a/src/components/ProfilePage/Bio.jsx
+++ b/src/components/ProfilePage/Bio.jsx
@@ -1,8 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap';
import { connect } from 'react-redux';
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
+import classNames from 'classnames';
import messages from './Bio.messages';
@@ -55,22 +55,21 @@ class Bio extends React.Component {
cases={{
editing: (
),
editable: (
diff --git a/src/components/ProfilePage/Certificates.jsx b/src/components/ProfilePage/Certificates.jsx
index 558e6b7..6952373 100644
--- a/src/components/ProfilePage/Certificates.jsx
+++ b/src/components/ProfilePage/Certificates.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape, FormattedDate, FormattedMessage } from 'react-intl';
-import { Row, Col, Card, CardBody, CardTitle, Button, Form } from 'reactstrap';
+import { Hyperlink } from '@edx/paragon';
import { connect } from 'react-redux';
import get from 'lodash.get';
@@ -66,14 +66,14 @@ class Certificates extends React.Component {
})(certificateType);
return (
-
-
+
+
-
-
+
+
{intl.formatMessage(get(
messages,
@@ -82,7 +82,7 @@ class Certificates extends React.Component {
))}
{courseDisplayName}
-
+
-
- {intl.formatMessage(messages['profile.certificates.view.certificate'])}
-
+
-
-
-
+
+
+
);
}
@@ -121,7 +124,7 @@ class Certificates extends React.Component {
}
return (
- {this.props.certificates.map(certificate => this.renderCertificate(certificate))}
+ {this.props.certificates.map(certificate => this.renderCertificate(certificate))}
);
}
@@ -137,7 +140,7 @@ class Certificates extends React.Component {
cases={{
editing: (
-
+
-
+
),
editable: (
diff --git a/src/components/ProfilePage/Country.jsx b/src/components/ProfilePage/Country.jsx
index b9acebd..674fbe7 100644
--- a/src/components/ProfilePage/Country.jsx
+++ b/src/components/ProfilePage/Country.jsx
@@ -1,8 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from 'react-intl';
+import classNames from 'classnames';
import messages from './Country.messages';
@@ -66,27 +66,26 @@ class Country extends React.Component {
cases={{
editing: (
-
-
-
+
+
+
{intl.formatMessage(messages['profile.country.label'])}
-
-
+
{sortedCountries.map(({ code, name }) => (
{name}
))}
-
- {error}
-
+
+
{error}
+
-
+
),
editable: (
diff --git a/src/components/ProfilePage/Education.jsx b/src/components/ProfilePage/Education.jsx
index 1257e6c..e0621e2 100644
--- a/src/components/ProfilePage/Education.jsx
+++ b/src/components/ProfilePage/Education.jsx
@@ -1,9 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap';
import { connect } from 'react-redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import get from 'lodash.get';
+import classNames from 'classnames';
import messages from './Education.messages';
@@ -62,18 +62,16 @@ class Education extends React.Component {
cases={{
editing: (
-
-
-
+
+
+
{intl.formatMessage(messages['profile.education.education'])}
-
-
+
@@ -86,9 +84,9 @@ class Education extends React.Component {
))}
))}
-
- {error}
-
+
+
{error}
+
-
+
),
editable: (
diff --git a/src/components/ProfilePage/Name.jsx b/src/components/ProfilePage/Name.jsx
index 4b62989..710d34d 100644
--- a/src/components/ProfilePage/Name.jsx
+++ b/src/components/ProfilePage/Name.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Form, FormFeedback, FormGroup, FormText, Label } from 'reactstrap';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from 'react-intl';
@@ -48,7 +47,7 @@ class Name extends React.Component {
render() {
const {
- formId, name, visibilityName, editMode, saveState, error, intl,
+ formId, name, visibilityName, editMode, saveState, intl,
} = this.props;
return (
@@ -58,11 +57,9 @@ class Name extends React.Component {
cases={{
editing: (
-
-
-
- {intl.formatMessage(messages['profile.name.full.name'])}
-
+
+
+
{/*
This isn't a mistake - the name field should not be editable. But if it were,
you'd find the original code got deleted in the commit which added this comment.
@@ -72,11 +69,10 @@ class Name extends React.Component {
such to fully get rid of it.
*/}
{name}
-
+
{intl.formatMessage(messages['profile.name.details'])}
-
-
{error}
-
+
+
-
+
),
editable: (
@@ -97,9 +93,9 @@ class Name extends React.Component {
visibility={visibilityName}
/>
{name}
-
+
{intl.formatMessage(messages['profile.name.details'])}
-
+
),
empty: (
@@ -108,9 +104,9 @@ class Name extends React.Component {
{intl.formatMessage(messages['profile.name.empty'])}
-
+
{intl.formatMessage(messages['profile.name.details'])}
-
+
),
static: (
@@ -137,7 +133,6 @@ Name.propTypes = {
visibilityName: PropTypes.oneOf(['private', 'all_users']),
editMode: PropTypes.oneOf(['editing', 'editable', 'empty', 'static']),
saveState: PropTypes.string,
- error: PropTypes.string,
// Actions
changeHandler: PropTypes.func.isRequired,
@@ -154,7 +149,6 @@ Name.defaultProps = {
saveState: null,
name: null,
visibilityName: 'private',
- error: null,
};
export default connect(
diff --git a/src/components/ProfilePage/PageLoading.jsx b/src/components/ProfilePage/PageLoading.jsx
index 0be951d..5ebc98f 100644
--- a/src/components/ProfilePage/PageLoading.jsx
+++ b/src/components/ProfilePage/PageLoading.jsx
@@ -1,5 +1,4 @@
import React from 'react';
-import { Spinner } from 'reactstrap';
import Banner from './elements/Banner';
@@ -13,7 +12,7 @@ function PageLoading() {
height: '50vh',
}}
>
-
+
);
diff --git a/src/components/ProfilePage/PreferredLanguage.jsx b/src/components/ProfilePage/PreferredLanguage.jsx
index b9cebda..a4dfc32 100644
--- a/src/components/ProfilePage/PreferredLanguage.jsx
+++ b/src/components/ProfilePage/PreferredLanguage.jsx
@@ -1,8 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from 'react-intl';
+import classNames from 'classnames';
import messages from './PreferredLanguage.messages';
@@ -76,27 +76,25 @@ class PreferredLanguage extends React.Component {
cases={{
editing: (
-
-
-
+
+
+
{intl.formatMessage(messages['profile.preferredlanguage.label'])}
-
-
+
{sortedLanguages.map(({ code, name }) => (
{name}
))}
-
- {error}
-
+
+
{error}
+
-
+
),
editable: (
diff --git a/src/components/ProfilePage/ProfileAvatar.jsx b/src/components/ProfilePage/ProfileAvatar.jsx
index 91123ee..9121a2b 100644
--- a/src/components/ProfilePage/ProfileAvatar.jsx
+++ b/src/components/ProfilePage/ProfileAvatar.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Input, Spinner, Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Button } from 'reactstrap';
+import { Button, Dropdown } from '@edx/paragon';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { ReactComponent as DefaultAvatar } from '../../assets/avatar.svg';
@@ -11,10 +11,6 @@ class ProfileAvatar extends React.Component {
constructor(props) {
super(props);
- this.state = {
- dropdownOpen: false,
- };
-
this.fileInput = React.createRef();
this.form = React.createRef();
@@ -22,7 +18,6 @@ class ProfileAvatar extends React.Component {
this.onClickDelete = this.onClickDelete.bind(this);
this.onChangeInput = this.onChangeInput.bind(this);
this.onSubmit = this.onSubmit.bind(this);
- this.toggleDropdown = this.toggleDropdown.bind(this);
}
onClickUpload() {
@@ -43,19 +38,13 @@ class ProfileAvatar extends React.Component {
this.form.current.reset();
}
- toggleDropdown() {
- this.setState({
- dropdownOpen: !this.state.dropdownOpen,
- });
- }
-
renderPending() {
return (
);
}
@@ -64,49 +53,51 @@ class ProfileAvatar extends React.Component {
if (this.props.isDefault) {
return (
-
-
- );
- }
-
- return (
-
-
-
-
-
-
+ label={
-
-
-
-
-
-
+ }
+ />
+ );
+ }
+
+ return (
+
+ )}
+ menuItems={[
+ (
+
+
+
+ ),
+ (
+
+
+
+ ),
+ ]}
+ />
);
}
@@ -148,9 +139,9 @@ class ProfileAvatar extends React.Component {
encType="multipart/form-data"
>
{/* The name of this input must be 'file' */}
-
-
+
{/* TODO: Replace this alert with per-field errors. Needs API update. */}
- {error !== null ?
{error} : null}
+ {error !== null ?
: null}
{socialLinks.map(({ platform, socialLink }) => (
@@ -186,7 +187,7 @@ class SocialLinks extends React.Component {
cancelHandler={this.handleClose}
changeHandler={this.handleChange}
/>
-
+
),
}}
@@ -282,14 +283,14 @@ function EditingListItem({
}) {
return (
- {name}
- {name}
+
diff --git a/src/components/ProfilePage/elements/AsyncActionButton.jsx b/src/components/ProfilePage/elements/AsyncActionButton.jsx
index 2dd7e52..682ca56 100644
--- a/src/components/ProfilePage/elements/AsyncActionButton.jsx
+++ b/src/components/ProfilePage/elements/AsyncActionButton.jsx
@@ -1,8 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import { Icon } from '@edx/paragon';
-import { Button, Spinner } from 'reactstrap';
+import { Icon, Button } from '@edx/paragon';
function AsyncActionButton({
onClick,
@@ -16,7 +15,11 @@ function AsyncActionButton({
const renderIcon = () => {
if (variant === 'error') return ;
if (variant === 'complete') return ;
- if (variant === 'pending') return ;
+ if (variant === 'pending') {
+ return (
+
+ );
+ }
return null;
};
@@ -29,12 +32,14 @@ function AsyncActionButton({
return labels.default;
};
+ const isDisabled = variant === 'pending' || variant === 'complete' || variant === 'error';
+
return (
{})}
+ disabled={isDisabled}
className={classNames(
'btn-async-action',
'd-inline-flex align-items-center justify-content-center',
@@ -43,16 +48,20 @@ function AsyncActionButton({
'btn-state-pending': variant === 'pending',
'btn-state-complete': variant === 'complete',
'btn-state-error': variant === 'error',
+ [`btn-${color}`]: color != null,
+ disabled: isDisabled,
},
- )}
- color={color}
+ ).split(' ')}
style={style}
- >
-
- {renderIcon()}
-
- {renderLabel()}
-
+ label={(
+
+
+ {renderIcon()}
+
+ {renderLabel()}
+
+ )}
+ />
);
}
diff --git a/src/components/ProfilePage/elements/FormControls.jsx b/src/components/ProfilePage/elements/FormControls.jsx
index a333f40..8749ad7 100644
--- a/src/components/ProfilePage/elements/FormControls.jsx
+++ b/src/components/ProfilePage/elements/FormControls.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, Label, FormGroup } from 'reactstrap';
+import { Button } from '@edx/paragon';
import { injectIntl, intlShape } from 'react-intl';
import messages from './FormControls.messages';
@@ -16,10 +16,10 @@ function FormControls({
return (
-
-
+
+
{intl.formatMessage(messages['profile.formcontrols.who.can.see'])}
-
+
-
-
+
+
-
- {intl.formatMessage(messages['profile.formcontrols.button.cancel'])}
-
-
+
+
);
}
diff --git a/src/components/ProfilePage/elements/Visibility.jsx b/src/components/ProfilePage/elements/Visibility.jsx
index 10bedf6..b5dcf4c 100644
--- a/src/components/ProfilePage/elements/Visibility.jsx
+++ b/src/components/ProfilePage/elements/Visibility.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Input } from 'reactstrap';
import { injectIntl, intlShape } from 'react-intl';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEyeSlash, faEye } from '@fortawesome/free-regular-svg-icons';
@@ -41,14 +40,14 @@ function VisibilitySelect({ intl, className, ...props }) {
-
+
{intl.formatMessage(messages['profile.visibility.who.just.me'])}
{intl.formatMessage(messages['profile.visibility.who.everyone'])}
-
+
);
}
diff --git a/src/components/__snapshots__/ProfilePage.test.jsx.snap b/src/components/__snapshots__/ProfilePage.test.jsx.snap
index 19ad3e6..274d3cd 100644
--- a/src/components/__snapshots__/ProfilePage.test.jsx.snap
+++ b/src/components/__snapshots__/ProfilePage.test.jsx.snap
@@ -16,13 +16,7 @@ exports[` Renders correctly in various states app loading 1`] = `
-
- Loading...
-
-
+ />
`;
@@ -38,7 +32,7 @@ exports[` Renders correctly in various states viewing other profi
className="container-fluid"
>
Renders correctly in various states viewing other profi
Renders correctly in various states viewing own profile
className="container-fluid"
>
Renders correctly in various states viewing own profile
>
@@ -270,17 +264,21 @@ exports[` Renders correctly in various states viewing own profile
+ }
className="dropdown-menu"
role="menu"
- tabIndex="-1"
- x-placement={undefined}
>
Upload Photo
@@ -289,9 +287,7 @@ exports[` Renders correctly in various states viewing own profile
Remove
@@ -328,7 +324,7 @@ exports[` Renders correctly in various states viewing own profile
Renders correctly in various states viewing own profile
className="d-none d-md-block float-right"
>
View My Records
+
+
+
+
@@ -400,14 +403,21 @@ exports[` Renders correctly in various states viewing own profile
className="d-md-none mb-4"
>
View My Records
+
+
+
+
Renders correctly in various states viewing own profile
Renders correctly in various states viewing own profile
}
/>
Renders correctly in various states viewing own profile
@@ -1250,7 +1267,7 @@ exports[`
Renders correctly in various states while saving an edi
className="container-fluid"
>
Renders correctly in various states while saving an edi
>
@@ -1285,17 +1302,21 @@ exports[` Renders correctly in various states while saving an edi
+ }
className="dropdown-menu"
role="menu"
- tabIndex="-1"
- x-placement={undefined}
>
Upload Photo
@@ -1304,9 +1325,7 @@ exports[` Renders correctly in various states while saving an edi
Remove
@@ -1343,7 +1362,7 @@ exports[` Renders correctly in various states while saving an edi
Renders correctly in various states while saving an edi
className="d-none d-md-block float-right"
>
View My Records
+
+
+
+
@@ -1415,14 +1441,21 @@ exports[`
Renders correctly in various states while saving an edi
className="d-md-none mb-4"
>
View My Records
+
+
+
+
Renders correctly in various states while saving an edi
role="dialog"
>
About Me
@@ -2037,7 +2067,7 @@ exports[`
Renders correctly in various states while saving an edi
onChange={[Function]}
value="This is my bio"
/>
-
@@ -2085,6 +2115,7 @@ exports[`
Renders correctly in various states while saving an edi
id="visibilityBio"
name="visibilityBio"
onChange={[Function]}
+ type="select"
value="all_users"
>
Renders correctly in various states while saving an edi
className="form-group"
>
@@ -2119,20 +2151,15 @@ exports[` Renders correctly in various states while saving an edi
-
- Loading...
-
-
+ />
Saving
Cancel
@@ -2230,13 +2257,13 @@ exports[` Renders correctly in various states while saving an edi
Renders correctly in various states while saving an edi
}
/>
Renders correctly in various states while saving an edi
diff --git a/src/index.scss b/src/index.scss
index 59d16ee..3653c75 100755
--- a/src/index.scss
+++ b/src/index.scss
@@ -73,6 +73,18 @@ $fa-font-path: "~font-awesome/fonts";
margin-bottom: 1.2rem;
}
}
+
+ .dropdown {
+ @include media-breakpoint-up(md) {
+ margin-bottom: 1.2rem;
+ }
+ .btn {
+ color: $white;
+ background: transparent;
+ border-color: transparent;
+ margin: 0;
+ }
+ }
}
.profile-avatar {