Repository URL to install this package:
|
Version:
8.0.0 ▾
|
/**
* The navigation header used for all landing pages.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { messages as commonMessages } from '@doodle/common-messages';
import { Button } from '../../controls/Button';
import Menu from '../../controls/Menu/Menu';
import { TrackingClientShape } from '../../propTypes';
import HeaderWidget from '../../user/HeaderWidget';
import pickDataAttributes from '../../utils/pickDataAttributes';
import { translateMenuItems } from '../../utils/translate';
import { userPropType, isLoggedIn as checkIfLoggedIn, isOrgAdmin as checkIfOrgAdmin } from '../../utils/user';
import Icon from '../../visuals/Icon';
import LogoLink from '../../visuals/LogoLink';
import ArrowDownIcon from '../../visuals/Icon/svg/ic_keyboard_arrow_down.svg';
import Header from '../Header';
import CreatePollMenu from './CreatePollMenu';
import HamburgerMenu from './HamburgerMenu';
import { submenuKey } from './constants';
export const getDefaultNavLinks = (page, intl) => {
const locale = intl ? intl.locale : 'en';
const contactLinkByLocale =
locale === 'de'
? 'https://go.doodle.com/WF-2021-01-Contact-Sales-DE_LP-02.html'
: 'https://landing.doodle.com/contact-sales';
return [
{
label: commonMessages.features,
to: `/${locale}/features`,
'data-track': JSON.stringify({
event: 'Click Product',
type: 'user Interaction',
properties: { label: page, category: 'Global Navigation' },
}),
},
{
label: commonMessages.solutions,
submenu: [
{
label: commonMessages.solutionsRecruiting,
to: `/${locale}/solutions/recruiting`,
},
{
label: commonMessages.solutionsBoardMeetings,
to: `/${locale}/solutions/board-meetings`,
},
{
label: commonMessages.solutionsSales,
to: `/${locale}/solutions/sales`,
},
{
label: commonMessages.solutionsEducation,
to: `/${locale}/solutions/education`,
},
{
label: commonMessages.solutionsNonProfit,
to: `/${locale}/solutions/non-profit`,
},
{
label: commonMessages.solutionsConsultants,
to: `/${locale}/solutions/consultants`,
},
{
label: commonMessages.solutionsEnterprise,
to: `/${locale}/solutions/enterprise`,
},
],
},
{
label: commonMessages.pricing,
to: '/premium',
'data-track': JSON.stringify({
event: 'Click Pricing',
type: 'user Interaction',
properties: { label: page, category: 'Global Navigation' },
}),
},
{
label: commonMessages.integrations,
to: `/${locale}/integrations`,
'data-track': JSON.stringify({
event: 'Click Integrations',
type: 'user Interaction',
properties: { label: page, category: 'Global Navigation' },
}),
},
{
label: commonMessages.resources,
submenu: [
{
label: commonMessages.resourceCenter,
to: `/${locale}/resources`,
'data-track': JSON.stringify({
event: 'Click Resources',
type: 'user Interaction',
properties: { label: page, category: 'Global Navigation' },
}),
},
{
label: commonMessages.blog,
to: 'https://blog.doodle.com/',
},
],
},
{
label: commonMessages.contact,
submenu: [
{
label: commonMessages.sales,
to: contactLinkByLocale,
'data-track': JSON.stringify({
event: 'Click Contact Sales',
type: 'user Interaction',
properties: {
label: page,
description: "user clicks on the 'Contact Sales' link placed in the header",
category: 'Global Navigation',
'Contact Sales': 'Header',
},
}),
},
{
label: commonMessages.helpAndSupport,
to: 'https://help.doodle.com',
},
],
},
];
};
const Navigation = ({
links,
user,
theme,
hideCreatePollMenu,
onClickLogin,
onClickLogout,
onClickSignup,
onClickCreatePoll,
onClickCreateOneOnOne,
onClickCreateBookingPage,
onClickCreateSurvey,
customUrl,
page,
currentPageType,
customLogo,
trackingClient,
intl,
showSignUp,
}) => {
let navLinks = links || getDefaultNavLinks(page, intl);
navLinks = translateMenuItems(navLinks, intl);
// Transform menu items to Menu and Link elements
const navElements = navLinks.map(itemOrElement => {
if (React.isValidElement(itemOrElement)) {
return itemOrElement;
}
if (submenuKey in itemOrElement) {
const { label: menuTitle, submenu } = itemOrElement;
// Only items as props objects supported here, not elements, due to Menu API
return (
<Menu items={submenu} horizontalAlign="left" dimension="compact" variant="linkDark" className={menuTitle}>
{menuTitle}
<Icon icon={ArrowDownIcon} />
</Menu>
);
}
const { label, to, ...rest } = itemOrElement;
return (
<Button href={to} variant="linkDark" dimension="compact" {...pickDataAttributes(rest)}>
{label}
</Button>
);
});
const isLoggedIn = checkIfLoggedIn(user);
const isOrgAdmin = checkIfOrgAdmin(user);
const headerLeft = [
<LogoLink user={user} currentPageType={currentPageType} customUrl={customUrl} logoUrl={customLogo} />,
...navElements,
];
const headerRight = [
<HeaderWidget
username={null} // hide username by design
userAvatar={isLoggedIn ? user.data.avatarSmallUrl : null}
isLoggedIn={isLoggedIn}
onClickLogin={onClickLogin}
onClickLogout={onClickLogout}
onClickSignup={onClickSignup}
isOrgAdmin={isOrgAdmin}
intl={intl}
showSignUp={showSignUp}
/>,
<CreatePollMenu
user={user}
page={page}
onClickCreatePoll={onClickCreatePoll}
onClickCreateOneOnOne={onClickCreateOneOnOne}
onClickCreateBookingPage={onClickCreateBookingPage}
onClickCreateSurvey={onClickCreateSurvey}
trackingClient={trackingClient}
intl={intl}
/>,
<HamburgerMenu
className="Navigation-hamburgerMenu"
items={navLinks}
user={user}
onClickLogin={onClickLogin}
onClickLogout={onClickLogout}
onClickSignup={onClickSignup}
isOrgAdmin={isOrgAdmin}
intl={intl}
/>,
];
if (hideCreatePollMenu) {
headerRight.splice(1, 1);
}
return <Header theme={theme} left={headerLeft} right={headerRight} />;
};
export const NavigationTypes = {
/** Custom array to override the default links of the header. If no links are needed, an empty array should be passed to this prop. */
links: PropTypes.array,
/** Defines the user and the shape of the data. */
user: userPropType,
/** The background colour for the header - defaults to transparent. */
theme: PropTypes.oneOf(['white', 'transparent']),
/** Hide or show the create poll menu (Create/Create a doodle). */
hideCreatePollMenu: PropTypes.bool,
/**
* Callback executed when the user clicks on the "Login" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickLogin by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickLogin: PropTypes.func,
/**
* Callback executed when the user clicks on the "Logout" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickLogout by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickLogout: PropTypes.func,
/**
* Callback executed when the user clicks on the "Signup" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickSignup by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickSignup: PropTypes.func,
/**
* Callback executed when the user clicks on the "Group Meeting" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickCreatePoll by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickCreatePoll: PropTypes.func,
/**
* Callback executed when the user clicks on the "1:1 Meeting" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickCreateOneOnOne by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickCreateOneOnOne: PropTypes.func,
/**
* Callback executed when the user clicks on the "Bookable Calendar" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickCreateBookingPage by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickCreateBookingPage: PropTypes.func,
/**
* Callback executed when the user clicks on the "Survey" button.
* It can be overridden to add custom functionality such as tracking.
* You can execute the default button behaviour within onClickCreateSurvey by running
* the function provided as first parameter. If your custom code is asynchronous,
* run the default behaviour as callback of your asynchronous action. This guarantees
* that your custom action completes before navigating to another page.
* @param {Function} defaultBehaviour - Function to execute the default click behaviour
*/
onClickCreateSurvey: PropTypes.func,
/** Page that the header will be added in - this prop is used for tracking purposes. */
page: PropTypes.string.isRequired,
/** CustomUrl prop that is passed into the LogoLink to redirect the user to a custom link */
customUrl: PropTypes.string,
/** Props to pass through to the LogoLink which will determine where to redirect the user */
currentPageType: PropTypes.string,
/** A prop for passing in a custom logo into LogoLink.
* If this prop is not used, Doodle's logo will be displayed */
customLogo: PropTypes.string,
/** An initialized instance of lib-tracking client */
trackingClient: TrackingClientShape,
/** An object used for internationalization. */
intl: PropTypes.object,
/** Show Sign Up Button - defaults to true */
showSignUp: PropTypes.bool,
};
Navigation.propTypes = NavigationTypes;
Navigation.defaultProps = {
links: null,
user: null,
theme: 'transparent',
hideCreatePollMenu: false,
onClickLogin: defaultBehaviour => defaultBehaviour(),
onClickLogout: defaultBehaviour => defaultBehaviour(),
onClickSignup: defaultBehaviour => defaultBehaviour(),
onClickCreatePoll: defaultBehaviour => defaultBehaviour(),
onClickCreateOneOnOne: defaultBehaviour => defaultBehaviour(),
onClickCreateBookingPage: defaultBehaviour => defaultBehaviour(),
onClickCreateSurvey: defaultBehaviour => defaultBehaviour(),
customUrl: '',
currentPageType: '',
customLogo: '',
trackingClient: null,
intl: null,
showSignUp: true,
};
Navigation.displayName = 'Navigation';
export default Navigation;