-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: reskin of Profile MFE main page (#1114)
* feat: reskin of Profile MFE main page * feat: reskin of Profile MFE main page * test: updated tests according to the changes * fix: added missing name property * test: updated test snapshot * test: added tests for reducers * feat: moved reskin logic behind env variable * test: updated tests * refactor: refactored code according to requested changes * fix: fixed lint errors * refactor: refactored code according to requested changes * refactor: refactored code according to requested changes
- Loading branch information
1 parent
f3a328c
commit c025310
Showing
47 changed files
with
3,417 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,14 @@ | ||
import { combineReducers } from 'redux'; | ||
|
||
import { reducer as profilePage } from '../profile'; | ||
import { getConfig } from '@edx/frontend-platform'; | ||
|
||
import { reducer as profilePageReducer } from '../profile'; | ||
import { reducer as newProfilePageReducer } from '../profile-v2'; | ||
|
||
const isNewProfileEnabled = getConfig().ENABLE_NEW_PROFILE_VIEW; | ||
|
||
const createRootReducer = () => combineReducers({ | ||
profilePage, | ||
profilePage: isNewProfileEnabled ? newProfilePageReducer : profilePageReducer, | ||
}); | ||
|
||
export default createRootReducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
import { all } from 'redux-saga/effects'; | ||
|
||
import { getConfig } from '@edx/frontend-platform'; | ||
import { saga as profileSaga } from '../profile'; | ||
import { saga as newProfileSaga } from '../profile-v2'; | ||
|
||
const isNewProfileEnabled = getConfig().ENABLE_NEW_PROFILE_VIEW; | ||
|
||
export default function* rootSaga() { | ||
yield all([ | ||
profileSaga(), | ||
isNewProfileEnabled ? newProfileSaga() : profileSaga(), | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
@import "~@edx/brand/paragon/fonts"; | ||
@import "~@edx/brand/paragon/variables"; | ||
@import "~@openedx/paragon/scss/core/core"; | ||
@import "~@edx/brand/paragon/overrides"; | ||
@import "~@edx/frontend-component-header/dist/index"; | ||
@import "~@edx/frontend-component-footer/dist/footer"; | ||
|
||
@import './profile-v2/index'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { FormattedDate, FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; | ||
import { Hyperlink } from '@openedx/paragon'; | ||
import get from 'lodash.get'; | ||
|
||
import professionalCertificateSVG from './assets/professional-certificate.svg'; | ||
import verifiedCertificateSVG from './assets/verified-certificate.svg'; | ||
import messages from './Certificates.messages'; | ||
|
||
const CertificateCard = ({ | ||
certificateType, | ||
courseDisplayName, | ||
courseOrganization, | ||
modifiedDate, | ||
downloadUrl, | ||
courseId, | ||
uuid, | ||
}) => { | ||
const intl = useIntl(); | ||
|
||
const certificateIllustration = { | ||
professional: professionalCertificateSVG, | ||
'no-id-professional': professionalCertificateSVG, | ||
verified: verifiedCertificateSVG, | ||
honor: null, | ||
audit: null, | ||
}[certificateType] || null; | ||
|
||
return ( | ||
<div | ||
key={`${modifiedDate}-${courseId}`} | ||
className="col-auto d-flex align-items-center p-0" | ||
> | ||
<div className="col certificate p-4 border-light-400 bg-light-200 w-100 h-100"> | ||
<div | ||
className="certificate-type-illustration" | ||
style={{ backgroundImage: `url(${certificateIllustration})` }} | ||
/> | ||
<div className="d-flex flex-column position-relative p-0 width-19625rem"> | ||
<div className="w-100 color-black"> | ||
<p className="small mb-0 font-weight-normal"> | ||
{intl.formatMessage(get( | ||
messages, | ||
`profile.certificates.types.${certificateType}`, | ||
messages['profile.certificates.types.unknown'], | ||
))} | ||
</p> | ||
<h4 className="m-0 color-black">{courseDisplayName}</h4> | ||
<p className="small mb-0"> | ||
<FormattedMessage | ||
id="profile.certificate.organization.label" | ||
defaultMessage="From" | ||
/> | ||
</p> | ||
<h5 className="mb-0 color-black">{courseOrganization}</h5> | ||
<p className="small mb-0"> | ||
<FormattedMessage | ||
id="profile.certificate.completion.date.label" | ||
defaultMessage="Completed on {date}" | ||
values={{ | ||
date: <FormattedDate value={new Date(modifiedDate)} />, | ||
}} | ||
/> | ||
</p> | ||
</div> | ||
<div className="pt-3"> | ||
<Hyperlink | ||
destination={downloadUrl} | ||
target="_blank" | ||
showLaunchIcon={false} | ||
className="btn btn-primary btn-rounded font-weight-normal px-4 py-0625rem" | ||
> | ||
{intl.formatMessage(messages['profile.certificates.view.certificate'])} | ||
</Hyperlink> | ||
</div> | ||
<p className="small mb-0 pt-3"> | ||
<FormattedMessage | ||
id="profile.certificate.uuid" | ||
defaultMessage="Credential ID {certificate_uuid}" | ||
values={{ | ||
certificate_uuid: uuid, | ||
}} | ||
/> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
CertificateCard.propTypes = { | ||
certificateType: PropTypes.string, | ||
courseDisplayName: PropTypes.string, | ||
courseOrganization: PropTypes.string, | ||
modifiedDate: PropTypes.string, | ||
downloadUrl: PropTypes.string, | ||
courseId: PropTypes.string.isRequired, | ||
uuid: PropTypes.string, | ||
}; | ||
|
||
CertificateCard.defaultProps = { | ||
certificateType: 'unknown', | ||
courseDisplayName: '', | ||
courseOrganization: '', | ||
modifiedDate: '', | ||
downloadUrl: '', | ||
uuid: '', | ||
}; | ||
|
||
export default CertificateCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { FormattedMessage } from '@edx/frontend-platform/i18n'; | ||
import { connect } from 'react-redux'; | ||
import { getConfig } from '@edx/frontend-platform'; | ||
|
||
import CertificateCard from './CertificateCard'; | ||
import { certificatesSelector } from './data/selectors'; | ||
|
||
const Certificates = ({ certificates }) => ( | ||
<div> | ||
<div className="col justify-content-start align-items-start g-5rem p-0"> | ||
<div className="col align-self-stretch height-2625rem justify-content-start align-items-start p-0"> | ||
<h2 className="font-weight-bold text-primary-500 m-0"> | ||
<FormattedMessage | ||
id="profile.your.certificates" | ||
defaultMessage="Your certificates" | ||
description="heading for the certificates section" | ||
/> | ||
</h2> | ||
</div> | ||
<div className="col justify-content-start align-items-start pt-2 p-0"> | ||
<p className="font-weight-normal text-gray-800 m-0 p-0"> | ||
<FormattedMessage | ||
id="profile.certificates.description" | ||
defaultMessage="Your learner records information is only visible to you. Only your username is visible to others on {siteName}." | ||
description="description of the certificates section" | ||
values={{ | ||
siteName: getConfig().SITE_NAME, | ||
}} | ||
/> | ||
</p> | ||
</div> | ||
</div> | ||
{certificates?.length > 0 ? ( | ||
<div className="col"> | ||
<div className="row align-items-center pt-5 g-3rem"> | ||
{certificates.map(certificate => ( | ||
<CertificateCard key={certificate.courseId} {...certificate} /> | ||
))} | ||
</div> | ||
</div> | ||
) : ( | ||
<div className="pt-5"> | ||
<FormattedMessage | ||
id="profile.no.certificates" | ||
defaultMessage="You don't have any certificates yet." | ||
description="displays when user has no course completion certificates" | ||
/> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
|
||
Certificates.propTypes = { | ||
certificates: PropTypes.arrayOf(PropTypes.shape({ | ||
certificateType: PropTypes.string, | ||
courseDisplayName: PropTypes.string, | ||
courseOrganization: PropTypes.string, | ||
modifiedDate: PropTypes.string, | ||
downloadUrl: PropTypes.string, | ||
courseId: PropTypes.string.isRequired, | ||
uuid: PropTypes.string, | ||
})), | ||
}; | ||
|
||
Certificates.defaultProps = { | ||
certificates: [], | ||
}; | ||
|
||
export default connect( | ||
certificatesSelector, | ||
{}, | ||
)(Certificates); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { defineMessages } from '@edx/frontend-platform/i18n'; | ||
|
||
const messages = defineMessages({ | ||
'profile.certificates.my.certificates': { | ||
id: 'profile.certificates.my.certificates', | ||
defaultMessage: 'My Certificates', | ||
description: 'A section of a user profile', | ||
}, | ||
'profile.certificates.view.certificate': { | ||
id: 'profile.certificates.view.certificate', | ||
defaultMessage: 'View Certificate', | ||
description: 'A call to action to view a certificate', | ||
}, | ||
'profile.certificates.types.verified': { | ||
id: 'profile.certificates.types.verified', | ||
defaultMessage: 'Verified Certificate', | ||
description: 'A type of certificate a user may have earned', | ||
}, | ||
'profile.certificates.types.professional': { | ||
id: 'profile.certificates.types.professional', | ||
defaultMessage: 'Professional Certificate', | ||
description: 'A type of certificate a user may have earned', | ||
}, | ||
'profile.certificates.types.unknown': { | ||
id: 'profile.certificates.types.unknown', | ||
defaultMessage: 'Certificate', | ||
description: 'The string to display when a certificate is of an unknown type', | ||
}, | ||
}); | ||
|
||
export default messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React, { memo } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { FormattedMessage, FormattedDate } from '@edx/frontend-platform/i18n'; | ||
|
||
const DateJoined = ({ date }) => { | ||
if (!date) { return null; } | ||
|
||
return ( | ||
<span className="small mb-0 text-gray-800"> | ||
<FormattedMessage | ||
id="profile.datejoined.member.since" | ||
defaultMessage="Member since {year}" | ||
description="A label for how long the user has been a member" | ||
values={{ | ||
year: <span className="font-weight-bold"> <FormattedDate value={new Date(date)} year="numeric" /> </span>, | ||
}} | ||
/> | ||
</span> | ||
); | ||
}; | ||
|
||
DateJoined.propTypes = { | ||
date: PropTypes.string, | ||
}; | ||
DateJoined.defaultProps = { | ||
date: null, | ||
}; | ||
|
||
export default memo(DateJoined); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react'; | ||
import { FormattedMessage } from '@edx/frontend-platform/i18n'; | ||
|
||
const NotFoundPage = () => ( | ||
<div className="container-fluid d-flex py-5 justify-content-center align-items-start text-center"> | ||
<p className="my-0 py-5 text-muted max-width-32em"> | ||
<FormattedMessage | ||
id="profile.notfound.message" | ||
defaultMessage="The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again." | ||
description="error message when a page does not exist" | ||
/> | ||
</p> | ||
</div> | ||
); | ||
|
||
export default NotFoundPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const PageLoading = ({ srMessage }) => ( | ||
<div> | ||
<div className="d-flex justify-content-center align-items-center flex-column height-50vh"> | ||
<div className="spinner-border text-primary" role="status"> | ||
{srMessage && <span className="sr-only">{srMessage}</span>} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
|
||
PageLoading.propTypes = { | ||
srMessage: PropTypes.string.isRequired, | ||
}; | ||
|
||
export default PageLoading; |
Oops, something went wrong.