feat: add recommendations modal

Description:
Add recommendations buttons and modal for painted door experiment
VAN-1601
This commit is contained in:
ahtesham-quraish
2023-08-16 12:23:07 +05:00
parent 86a4573405
commit 6cecc38e85
9 changed files with 183 additions and 35 deletions

View File

@@ -0,0 +1,60 @@
import React from 'react';
import PropTypes from 'prop-types';
import { ModalDialog, ActionRow, Button } from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
export const ModalView = ({
isOpen,
onClose,
}) => {
const { formatMessage } = useIntl();
const handleClose = () => {
onClose(false);
};
return (
<div className="containers">
<ModalDialog
title=""
isOpen={isOpen}
onClose={handleClose}
hasCloseButton={false}
isFullscreenScroll
>
<ModalDialog.Header>
<ModalDialog.Title>
<h3 className="mt-2">{formatMessage(messages.recommendationsModalHeading)}</h3>
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
<div className="modal-continer">
<p className="mt-2">{formatMessage(messages.recommendationsFeatureText)}</p>
<p>{formatMessage(messages.recommendationsAlertedText)}</p>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow>
<ModalDialog.CloseButton variant="tertiary">
{formatMessage(messages.modalSkipButton)}
</ModalDialog.CloseButton>
<Button variant="primary">{formatMessage(messages.modalCountMeButton)}</Button>
</ActionRow>
</ModalDialog.Footer>
</ModalDialog>
</div>
);
};
ModalView.defaultProps = {
isOpen: false,
onClose: () => {},
};
ModalView.propTypes = {
onClose: PropTypes.func,
isOpen: PropTypes.bool,
};
export default ModalView;

View File

@@ -0,0 +1,31 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
recommendationsFeatureText: {
id: 'RecommendationsPanel.recommendationsFeatureText',
defaultMessage: 'Personalized recommendations feature is not yet available. We are working hard on bringing it to your learner home in the near future.',
description: 'recommendations feature text',
},
recommendationsAlertedText: {
id: 'RecommendationsPanel.recommendationsAlertedText',
defaultMessage: 'Would you like to be alerted when it becomes available?',
description: 'recommendations alerted text',
},
recommendationsModalHeading: {
id: 'RecommendationsPanel.recommendationsModalHeading',
defaultMessage: 'Thank you for your interest!',
description: 'Heading of modal',
},
modalSkipButton: {
id: 'RecommendationsPanel.modalSkipButton',
defaultMessage: 'Skip for now',
description: 'button for Skip for now',
},
modalCountMeButton: {
id: 'RecommendationsPanel.modalCountMeButton',
defaultMessage: 'Count me in!',
description: 'button for Count me in!',
},
});
export default messages;

View File

@@ -12,9 +12,10 @@ import { reduxHooks } from 'hooks';
import { findCoursesNavDropdownClicked } from '../hooks';
import ModalView from '../../../components/ModalView';
import messages from '../messages';
export const CollapseMenuBody = ({ isOpen }) => {
export const CollapseMenuBody = ({ isOpen, isRecommendationModalOpen, setRecommendationModal }) => {
const { formatMessage } = useIntl();
const { authenticatedUser } = React.useContext(AppContext);
@@ -40,6 +41,12 @@ export const CollapseMenuBody = ({ isOpen }) => {
>
{formatMessage(messages.discoverNew)}
</Button>
<Button
variant="inverse-primary"
onClick={() => setRecommendationModal(true)}
>
{formatMessage(messages.recommendedForYou)}
</Button>
<Button as="a" href={getConfig().SUPPORT_URL} variant="inverse-primary">
{formatMessage(messages.help)}
</Button>
@@ -92,6 +99,7 @@ export const CollapseMenuBody = ({ isOpen }) => {
</Button>
</>
)}
<ModalView isOpen={isRecommendationModalOpen} onClose={setRecommendationModal} />
</div>
)
);
@@ -99,6 +107,13 @@ export const CollapseMenuBody = ({ isOpen }) => {
CollapseMenuBody.propTypes = {
isOpen: PropTypes.bool.isRequired,
isRecommendationModalOpen: PropTypes.bool,
setRecommendationModal: PropTypes.func,
};
CollapseMenuBody.defaultProps = {
isRecommendationModalOpen: false,
setRecommendationModal: () => {},
};
export default CollapseMenuBody;

View File

@@ -26,6 +26,12 @@ exports[`CollapseMenuBody render 1`] = `
>
Discover New
</Button>
<Button
onClick={[Function]}
variant="inverse-primary"
>
Recommended for you
</Button>
<Button
as="a"
href="http://localhost:18000/support"
@@ -61,6 +67,10 @@ exports[`CollapseMenuBody render 1`] = `
>
Sign Out
</Button>
<ModalView
isOpen={false}
onClose={[Function]}
/>
</div>
`;
@@ -92,6 +102,12 @@ exports[`CollapseMenuBody render unauthenticated 1`] = `
>
Discover New
</Button>
<Button
onClick={[Function]}
variant="inverse-primary"
>
Recommended for you
</Button>
<Button
as="a"
href="http://localhost:18000/support"
@@ -99,5 +115,9 @@ exports[`CollapseMenuBody render unauthenticated 1`] = `
>
Help
</Button>
<ModalView
isOpen={false}
onClose={[Function]}
/>
</div>
`;

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Menu, Close } from '@edx/paragon/icons';
@@ -15,6 +15,7 @@ export const CollapsedHeader = () => {
const { formatMessage } = useIntl();
const isCollapsed = useIsCollapsed();
const { isOpen, toggleIsOpen } = useLearnerDashboardHeaderData();
const [isRecommendationModalOpen, setRecommendationModal] = useState(false);
return (
isCollapsed && (
@@ -36,7 +37,11 @@ export const CollapsedHeader = () => {
/>
<BrandLogo />
</header>
<CollapseMenuBody isOpen={isOpen} />
<CollapseMenuBody
isOpen={isOpen}
setRecommendationModal={setRecommendationModal}
isRecommendationModalOpen={isRecommendationModalOpen}
/>
</>
)
);

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
@@ -11,12 +11,14 @@ import AuthenticatedUserDropdown from './AuthenticatedUserDropdown';
import { useIsCollapsed, findCoursesNavClicked } from '../hooks';
import messages from '../messages';
import ModalView from '../../../components/ModalView';
import BrandLogo from '../BrandLogo';
export const ExpandedHeader = () => {
const { formatMessage } = useIntl();
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
const isCollapsed = useIsCollapsed();
const [isRecommendationModalOpen, setRecommendationModal] = useState(false);
const exploreCoursesClick = findCoursesNavClicked(urls.baseAppUrl(courseSearchUrl));
@@ -51,6 +53,13 @@ export const ExpandedHeader = () => {
>
{formatMessage(messages.discoverNew)}
</Button>
<Button
variant="inverse-primary"
className="p-4"
onClick={() => setRecommendationModal(true)}
>
{formatMessage(messages.recommendedForYou)}
</Button>
<span className="flex-grow-1" />
<Button
as="a"
@@ -63,6 +72,7 @@ export const ExpandedHeader = () => {
</div>
<AuthenticatedUserDropdown />
<ModalView isOpen={isRecommendationModalOpen} onClose={setRecommendationModal} />
</header>
)
);

View File

@@ -51,6 +51,11 @@ const messages = defineMessages({
defaultMessage: 'Discover New',
description: 'Header link for switching to discover page.',
},
recommendedForYou: {
id: 'learnerVariantDashboard.recommendedForYou',
defaultMessage: 'Recommended for you',
description: 'Header link for recommended page.',
},
logoAltText: {
id: 'learnerVariantDashboard.logoAltText',
defaultMessage: 'edX, Inc. Dashboard',

View File

@@ -1,15 +1,12 @@
import React from 'react';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button } from '@edx/paragon';
import { Search } from '@edx/paragon/icons';
import { baseAppUrl } from 'data/services/lms/urls';
import { useIntl } from '@edx/frontend-platform/i18n';
import { reduxHooks } from 'hooks';
import track from './track';
import CourseCard from './components/CourseCard';
import messages from './messages';
import ModalView from '../../components/ModalView';
import './index.scss';
@@ -18,34 +15,34 @@ export const LoadedView = ({
isControl,
}) => {
const { formatMessage } = useIntl();
const { courseSearchUrl } = reduxHooks.usePlatformSettingsData();
const [isOpen, setOpen] = useState(false);
return (
<div className="p-4 w-100 panel-background">
<h3 className="pb-2">{isControl === false
? formatMessage(messages.recommendationsHeading) : formatMessage(messages.popularCoursesHeading)}
</h3>
<div>
{courses.map((course) => (
<CourseCard
key={course.courseKey}
course={course}
isControl={isControl}
/>
))}
<>
<div className="p-4 w-100 panel-background">
<h3 className="pb-2">{isControl === false
? formatMessage(messages.recommendationsHeading) : formatMessage(messages.popularCoursesHeading)}
</h3>
<div>
{courses.map((course) => (
<CourseCard
key={course.courseKey}
course={course}
isControl={isControl}
/>
))}
</div>
<div className="text-center explore-courses-btn">
<Button
variant="brand"
onClick={() => setOpen(true)}
>
{formatMessage(messages.seeAllRecommendationsButton)}
</Button>
</div>
</div>
<div className="text-center explore-courses-btn">
<Button
variant="tertiary"
iconBefore={Search}
as="a"
href={baseAppUrl(courseSearchUrl)}
onClick={track.findCoursesWidgetClicked(baseAppUrl(courseSearchUrl))}
>
{formatMessage(messages.exploreCoursesButton)}
</Button>
</div>
</div>
<ModalView isOpen={isOpen} onClose={setOpen} />
</>
);
};

View File

@@ -16,6 +16,11 @@ const messages = defineMessages({
defaultMessage: 'Explore courses',
description: 'Button to explore more courses on recommendations panel',
},
seeAllRecommendationsButton: {
id: 'RecommendationsPanel.seeAllRecommendationsButton',
defaultMessage: 'See All Recommendations',
description: 'Button to see all recommendations',
},
});
export default messages;