diff --git a/mailpoet/assets/js/src/common/scroll-to-top.jsx b/mailpoet/assets/js/src/common/scroll-to-top.jsx
index 8d6fd6ae81..a146e4c3ca 100644
--- a/mailpoet/assets/js/src/common/scroll-to-top.jsx
+++ b/mailpoet/assets/js/src/common/scroll-to-top.jsx
@@ -1,22 +1,20 @@
import PropTypes from 'prop-types';
import { useEffect } from 'react';
-import { withRouter } from 'react-router-dom';
+import { useLocation } from 'react-router-dom';
import { withBoundary } from './error-boundary';
-function ScrollToTopComponent({ children, location: { pathname } }) {
+export function ScrollToTopComponent({ children }) {
+ const location = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
- }, [pathname]);
+ }, [location.pathname]);
return children || null;
}
ScrollToTopComponent.propTypes = {
- location: PropTypes.shape({
- pathname: PropTypes.string.isRequired,
- }).isRequired,
children: PropTypes.node.isRequired,
};
ScrollToTopComponent.displayName = 'ScrollToTopComponent';
-export const ScrollToTop = withRouter(withBoundary(ScrollToTopComponent));
+export const ScrollToTop = withBoundary(ScrollToTopComponent);
diff --git a/mailpoet/assets/js/src/form/form.jsx b/mailpoet/assets/js/src/form/form.jsx
index 0e15a719ad..416ed5f2a6 100644
--- a/mailpoet/assets/js/src/form/form.jsx
+++ b/mailpoet/assets/js/src/form/form.jsx
@@ -1,8 +1,8 @@
import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
import { Component, createRef } from 'react';
-import { withRouter } from 'react-router-dom';
import jQuery from 'jquery';
+import { useNavigate } from 'react-router-dom';
import PropTypes from 'prop-types';
import { MailPoet } from 'mailpoet';
@@ -56,7 +56,7 @@ class FormComponent extends Component {
if (
params.id === undefined &&
- prevProps.location.pathname !== location.pathname
+ prevProps.location?.pathname !== location.pathname
) {
setImmediate(() => {
this.setState({
@@ -76,7 +76,7 @@ class FormComponent extends Component {
loadItem = (id) => {
const {
- history,
+ navigate,
endpoint = undefined,
onItemLoad = undefined,
} = this.props;
@@ -107,7 +107,7 @@ class FormComponent extends Component {
item: {},
},
() => {
- history.push('/lists');
+ navigate('/lists');
},
);
});
@@ -117,7 +117,7 @@ class FormComponent extends Component {
e.preventDefault();
const {
- history,
+ navigate,
endpoint = undefined,
fields = [],
isValid = undefined,
@@ -169,7 +169,7 @@ class FormComponent extends Component {
if (typeof onSuccess === 'function') {
onSuccess();
} else {
- history.push('/');
+ navigate('/');
}
if (params.id !== undefined) {
@@ -330,9 +330,10 @@ FormComponent.propTypes = {
onChange: PropTypes.func,
onSubmit: PropTypes.func,
onSuccess: PropTypes.func,
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
+ navigate: PropTypes.func.isRequired,
};
-export const Form = withRouter(FormComponent);
+export function Form(props) {
+ const navigate = useNavigate();
+ return ;
+}
diff --git a/mailpoet/assets/js/src/listing/listing.jsx b/mailpoet/assets/js/src/listing/listing.jsx
index 3e219bdf47..12d22588b3 100644
--- a/mailpoet/assets/js/src/listing/listing.jsx
+++ b/mailpoet/assets/js/src/listing/listing.jsx
@@ -12,7 +12,7 @@ import { ListingSearch } from 'listing/search.jsx';
import { ListingFilters } from 'listing/filters.jsx';
import { ListingItems } from 'listing/listing-items.jsx';
import { MailerError } from 'notices/mailer-error';
-import { withRouter } from 'react-router-dom';
+import { useLocation, useNavigate } from 'react-router-dom';
import { GlobalContext } from 'context';
import { withBoundary } from '../common';
@@ -67,7 +67,7 @@ class ListingComponent extends Component {
});
setParams = () => {
- const { history, location = undefined } = this.props;
+ const { navigate, location = undefined } = this.props;
if (location) {
const params = Object.keys(this.state)
.filter(
@@ -101,7 +101,7 @@ class ListingComponent extends Component {
const url = this.getUrlWithParams(params);
if (location.pathname !== url) {
- history.push(`${url}`);
+ navigate(`${url}`);
}
}
};
@@ -747,14 +747,19 @@ ListingComponent.propTypes = {
renderExtraActions: PropTypes.func,
onBeforeSelectFilter: PropTypes.func,
getListingItemKey: PropTypes.func,
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
+ navigate: PropTypes.func.isRequired,
isItemDeletable: PropTypes.func,
isItemToggleable: PropTypes.func,
className: PropTypes.string,
};
ListingComponent.displayName = 'Listing';
+const ListingWithBoundary = withBoundary(ListingComponent);
-export const Listing = withRouter(withBoundary(ListingComponent));
+export function Listing(props) {
+ const navigate = useNavigate();
+ const location = useLocation();
+ return (
+
+ );
+}
diff --git a/mailpoet/assets/js/src/newsletters/automatic-emails/events-conditions.jsx b/mailpoet/assets/js/src/newsletters/automatic-emails/events-conditions.jsx
index 836b72b3ef..2ca549ddc4 100644
--- a/mailpoet/assets/js/src/newsletters/automatic-emails/events-conditions.jsx
+++ b/mailpoet/assets/js/src/newsletters/automatic-emails/events-conditions.jsx
@@ -9,7 +9,7 @@ import { Button } from 'common/button/button';
import { Heading } from 'common/typography/heading/heading';
import { GlobalContext } from 'context';
import { Grid } from 'common/grid';
-import { ListingHeadingStepsRoute } from 'newsletters/listings/heading-steps-route';
+import { ListingHeadingSteps } from 'newsletters/listings/heading-steps';
import { EventScheduling } from 'newsletters/automatic-emails/events/event-scheduling.jsx';
import { EventOptions } from 'newsletters/automatic-emails/events/event-options';
import { MailPoet } from 'mailpoet';
@@ -261,7 +261,7 @@ class EventsConditions extends Component {
-
diff --git a/mailpoet/assets/js/src/newsletters/campaign-stats/page.tsx b/mailpoet/assets/js/src/newsletters/campaign-stats/page.tsx
index 31b9fc2e9c..e12066978c 100644
--- a/mailpoet/assets/js/src/newsletters/campaign-stats/page.tsx
+++ b/mailpoet/assets/js/src/newsletters/campaign-stats/page.tsx
@@ -2,7 +2,7 @@ import { useState, useEffect, useCallback } from 'react';
import { __, _x } from '@wordpress/i18n';
import { Hooks } from 'wp-js-hooks';
import { MailPoet } from 'mailpoet';
-import { withRouter } from 'react-router-dom';
+import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { TopBarWithBeamer } from 'common/top-bar/top-bar';
import { HideScreenOptions } from 'common/hide-screen-options/hide-screen-options';
import { RemoveWrapMargin } from 'common/remove-wrap-margin/remove-wrap-margin';
@@ -14,30 +14,21 @@ import { NewsletterType } from './newsletter-type';
import { NewsletterStatsInfo } from './newsletter-stats-info';
import { PremiumBanner } from './premium-banner';
-type Props = {
- match: {
- params: {
- id: string;
- };
- };
- history: {
- push: (string) => void;
- };
- // eslint-disable-next-line @typescript-eslint/ban-types -- we need to match `withRouter`
- location: object;
-};
-
type State = {
item?: NewsletterType;
loading: boolean;
};
-function CampaignStatsPageComponent({ match, history, location }: Props) {
+export function CampaignStatsPage() {
const [state, setState] = useState
({
item: undefined,
loading: true,
});
+ const location = useLocation();
+ const navigate = useNavigate();
+ const params = useParams();
+
const loadItem = useCallback(
(id) => {
setState({ loading: true, item: state.item });
@@ -68,20 +59,20 @@ function CampaignStatsPageComponent({ match, history, location }: Props) {
setState({
loading: false,
});
- history.push('/');
+ navigate('/');
});
},
- [history, state.item],
+ [navigate, state.item],
);
useEffect(() => {
// Scroll to top in case we're coming
// from the middle of a long newsletter listing
window.scrollTo(0, 0);
- if (state.item?.id !== match.params.id) {
- loadItem(match.params.id);
+ if (state.item?.id !== params.id) {
+ loadItem(params.id);
}
- }, [match.params.id, loadItem, state.item]);
+ }, [params.id, loadItem, state.item]);
const { item, loading } = state;
const newsletter = item;
@@ -142,7 +133,7 @@ function CampaignStatsPageComponent({ match, history, location }: Props) {
'mailpoet_newsletters_subscriber_engagement',
,
location,
- match.params,
+ params,
newsletter,
)}
@@ -160,7 +151,7 @@ function CampaignStatsPageComponent({ match, history, location }: Props) {
'mailpoet_newsletters_bounces',
,
location,
- match.params,
+ params,
)}
@@ -169,5 +160,4 @@ function CampaignStatsPageComponent({ match, history, location }: Props) {
);
}
-CampaignStatsPageComponent.displayName = 'CampaignStatsPage';
-export const CampaignStatsPage = withRouter(CampaignStatsPageComponent);
+CampaignStatsPage.displayName = 'CampaignStatsPage';
diff --git a/mailpoet/assets/js/src/newsletters/listings/heading-display.jsx b/mailpoet/assets/js/src/newsletters/listings/heading-display.jsx
index 16e10b6f16..3f6982fbdb 100644
--- a/mailpoet/assets/js/src/newsletters/listings/heading-display.jsx
+++ b/mailpoet/assets/js/src/newsletters/listings/heading-display.jsx
@@ -1,11 +1,12 @@
import PropTypes from 'prop-types';
-import { withRouter } from 'react-router-dom';
+import { useLocation } from 'react-router-dom';
import { mapPathToSteps } from './heading-steps.tsx';
const isHeaderHidden = (location) =>
location.hash.match(/^#\/new/) || location.pathname.match(/^\/new/);
-function ListingHeadingDisplayComponent({ children, location }) {
+export function ListingHeadingDisplay({ children }) {
+ const location = useLocation();
const stepNumber = mapPathToSteps(location);
if (stepNumber === null && !isHeaderHidden(location)) {
return children;
@@ -13,9 +14,6 @@ function ListingHeadingDisplayComponent({ children, location }) {
return null;
}
-ListingHeadingDisplayComponent.propTypes = {
- location: PropTypes.string.isRequired,
+ListingHeadingDisplay.propTypes = {
children: PropTypes.node.isRequired,
};
-
-export const ListingHeadingDisplay = withRouter(ListingHeadingDisplayComponent);
diff --git a/mailpoet/assets/js/src/newsletters/listings/heading-steps-route.tsx b/mailpoet/assets/js/src/newsletters/listings/heading-steps-route.tsx
index d534315ba6..a9d29dad70 100644
--- a/mailpoet/assets/js/src/newsletters/listings/heading-steps-route.tsx
+++ b/mailpoet/assets/js/src/newsletters/listings/heading-steps-route.tsx
@@ -1,8 +1,7 @@
-import { RouteComponentProps, withRouter } from 'react-router-dom';
-import { ListingHeadingSteps, Props } from './heading-steps';
+import { useLocation } from 'react-router-dom';
+import { ListingHeadingSteps } from './heading-steps';
-interface PropsWithRouter extends RouteComponentProps, Props {}
-
-export const ListingHeadingStepsRoute = withRouter((props: PropsWithRouter) => (
-
-));
+export function ListingHeadingStepsRoute(props) {
+ const location = useLocation();
+ return ;
+}
diff --git a/mailpoet/assets/js/src/newsletters/listings/heading-steps.tsx b/mailpoet/assets/js/src/newsletters/listings/heading-steps.tsx
index 003a572ffe..1ebc88b801 100644
--- a/mailpoet/assets/js/src/newsletters/listings/heading-steps.tsx
+++ b/mailpoet/assets/js/src/newsletters/listings/heading-steps.tsx
@@ -1,6 +1,6 @@
import { ReactNode } from 'react';
-import { Location } from 'history';
import { Icon, video } from '@wordpress/icons';
+import { Location } from 'react-router-dom';
import { __ } from '@wordpress/i18n';
import { HideScreenOptions } from '../../common/hide-screen-options/hide-screen-options';
import { MailPoetLogoResponsive } from '../../common/top-bar/mailpoet-logo-responsive';
@@ -129,7 +129,7 @@ export interface Props {
step?: number;
emailType?: string;
automationId?: string;
- location: Location;
+ location?: Location;
onLogoClick?: () => void;
buttons?: ReactNode;
}
@@ -137,8 +137,8 @@ export interface Props {
function ListingHeadingSteps({
step,
emailType,
- location,
automationId,
+ location,
buttons,
onLogoClick,
}: Props): JSX.Element {
diff --git a/mailpoet/assets/js/src/newsletters/listings/notification-history.jsx b/mailpoet/assets/js/src/newsletters/listings/notification-history.jsx
index 8e703a1ca7..ed77e0e20e 100644
--- a/mailpoet/assets/js/src/newsletters/listings/notification-history.jsx
+++ b/mailpoet/assets/js/src/newsletters/listings/notification-history.jsx
@@ -1,6 +1,6 @@
import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
-import { Link, withRouter } from 'react-router-dom';
+import { Link, useParams, useLocation } from 'react-router-dom';
import PropTypes from 'prop-types';
import { Listing } from 'listing/listing.jsx';
@@ -182,6 +182,9 @@ const renderItem = (newsletter, actions, meta) => {
};
function NewsletterListNotificationHistoryComponent(props) {
+ const params = useParams();
+ const location = useLocation();
+
return (
<>
;
+}
diff --git a/mailpoet/assets/js/src/newsletters/listings/re-engagement.jsx b/mailpoet/assets/js/src/newsletters/listings/re-engagement.jsx
index 935c0029ef..6c5d20693d 100644
--- a/mailpoet/assets/js/src/newsletters/listings/re-engagement.jsx
+++ b/mailpoet/assets/js/src/newsletters/listings/re-engagement.jsx
@@ -3,7 +3,7 @@ import { __, _x } from '@wordpress/i18n';
import { escapeHTML } from '@wordpress/escape-html';
import { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
-import { Link, withRouter } from 'react-router-dom';
+import { Link, useLocation, useParams } from 'react-router-dom';
import ReactStringReplace from 'react-string-replace';
import { Toggle } from 'common/form/toggle/toggle';
@@ -379,7 +379,7 @@ class NewsletterListReEngagementComponent extends Component {
;
+}
diff --git a/mailpoet/assets/js/src/newsletters/listings/standard.jsx b/mailpoet/assets/js/src/newsletters/listings/standard.jsx
index 45286e7578..7c08d7f68c 100644
--- a/mailpoet/assets/js/src/newsletters/listings/standard.jsx
+++ b/mailpoet/assets/js/src/newsletters/listings/standard.jsx
@@ -4,7 +4,7 @@ import { escapeHTML } from '@wordpress/escape-html';
import { Component } from 'react';
import { MailPoet } from 'mailpoet';
import PropTypes from 'prop-types';
-import { withRouter } from 'react-router-dom';
+import { useLocation, useParams } from 'react-router-dom';
import { confirmAlert } from 'common/confirm-alert.jsx';
import { FilterSegmentTag, SegmentTags } from 'common/tag/tags';
@@ -294,7 +294,7 @@ class NewsletterListStandardComponent extends Component {
;
+}
diff --git a/mailpoet/assets/js/src/newsletters/send.tsx b/mailpoet/assets/js/src/newsletters/send.tsx
index bfbea42289..07dbb5cd45 100644
--- a/mailpoet/assets/js/src/newsletters/send.tsx
+++ b/mailpoet/assets/js/src/newsletters/send.tsx
@@ -2,10 +2,16 @@ import _ from 'lodash';
import { ChangeEvent, Component, ContextType } from 'react';
import jQuery from 'jquery';
import { __, _x } from '@wordpress/i18n';
-import { History, Location } from 'history';
import ReactStringReplace from 'react-string-replace';
import slugify from 'slugify';
-import { match as RouterMatch, withRouter } from 'react-router-dom';
+import {
+ useNavigate,
+ useLocation,
+ NavigateFunction,
+ Location,
+ useParams,
+ Params,
+} from 'react-router-dom';
import { Background } from 'common/background/background';
import { Button, ErrorBoundary } from 'common';
@@ -40,11 +46,9 @@ const generateGaTrackingCampaignName = (
};
type NewsletterSendComponentProps = {
- match: RouterMatch<{
- id: string;
- }>;
- history: History;
+ navigate: NavigateFunction;
location: Location;
+ params: Params;
};
type NewsletterSendComponentState = {
@@ -184,7 +188,7 @@ class NewsletterSendComponent extends Component<
componentDidMount() {
// safe to ignore since even on rejection the state is updated
- void this.loadItem(this.props.match.params.id).always(() => {
+ void this.loadItem(this.props.params.id).always(() => {
this.setState({ loading: false });
});
jQuery('#mailpoet_newsletter').parsley({
@@ -193,9 +197,9 @@ class NewsletterSendComponent extends Component<
}
componentDidUpdate(prevProps) {
- if (this.props.match.params.id !== prevProps.match.params.id) {
+ if (this.props.params.id !== prevProps.match.params.id) {
// safe to ignore since even on rejection the state is updated
- void this.loadItem(this.props.match.params.id).always(() => {
+ void this.loadItem(this.props.params.id).always(() => {
this.setState({ loading: false });
});
}
@@ -295,7 +299,7 @@ class NewsletterSendComponent extends Component<
item: {} as NewsLetter,
},
() => {
- this.props.history.push(goToUrl);
+ this.props.navigate(goToUrl);
},
);
}
@@ -326,7 +330,7 @@ class NewsletterSendComponent extends Component<
item: {} as NewsLetter,
},
() => {
- this.props.history.push('/new');
+ this.props.navigate('/new');
},
);
});
@@ -443,7 +447,7 @@ class NewsletterSendComponent extends Component<
this.saveTemplate(saveResponse, () => {
if (window.mailpoet_show_congratulate_after_first_newsletter) {
MailPoet.Modal.loading(false);
- this.props.history.push(`/send/congratulate/${this.state.item.id}`);
+ this.props.navigate(`/send/congratulate/${this.state.item.id}`);
return;
}
this.redirectToListing('activated');
@@ -493,7 +497,7 @@ class NewsletterSendComponent extends Component<
endpoint: 'newsletters',
action: 'setStatus',
data: {
- id: this.props.match.params.id,
+ id: this.props.params.id,
status: 'active',
},
})
@@ -502,7 +506,7 @@ class NewsletterSendComponent extends Component<
this.saveTemplate(saveResponse, () => {
if (window.mailpoet_show_congratulate_after_first_newsletter) {
MailPoet.Modal.loading(false);
- this.props.history.push(`/send/congratulate/${this.state.item.id}`);
+ this.props.navigate(`/send/congratulate/${this.state.item.id}`);
return;
}
this.redirectToListing('activated');
@@ -612,7 +616,7 @@ class NewsletterSendComponent extends Component<
if (['automatic', 'welcome'].includes(this.state.item.type)) {
window.location.href = `admin.php?page=mailpoet-automation¬ice=${action}`;
} else {
- this.props.history.push(`/${this.state.item.type}`);
+ this.props.navigate(`/${this.state.item.type}`);
}
};
@@ -874,7 +878,7 @@ class NewsletterSendComponent extends Component<
wpPostId,
)}`
: `?page=mailpoet-newsletter-editor&id=${Number(
- this.props.match.params.id,
+ this.props.params.id,
)}`
}
onClick={this.handleRedirectToDesign}
@@ -905,4 +909,17 @@ class NewsletterSendComponent extends Component<
}
NewsletterSendComponent.contextType = GlobalContext;
-export const NewsletterSend = withRouter(NewsletterSendComponent);
+
+export function NewsletterSend(props) {
+ const location = useLocation();
+ const navigate = useNavigate();
+ const params = useParams();
+ return (
+
+ );
+}
diff --git a/mailpoet/assets/js/src/newsletters/types.tsx b/mailpoet/assets/js/src/newsletters/types.tsx
index 86f5cfcec6..3ec823605a 100644
--- a/mailpoet/assets/js/src/newsletters/types.tsx
+++ b/mailpoet/assets/js/src/newsletters/types.tsx
@@ -4,13 +4,13 @@ import {
Dropdown,
MenuItem as WpMenuItem,
} from '@wordpress/components';
-import { ComponentType, useState } from 'react';
+import { useState } from 'react';
import { __ } from '@wordpress/i18n';
import { chevronDown, Icon } from '@wordpress/icons';
import { MailPoet } from 'mailpoet';
import { Hooks } from 'wp-js-hooks';
import _ from 'underscore';
-import { RouteComponentProps, withRouter } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { Heading } from 'common/typography/heading/heading';
import { EditorSelectModal } from 'newsletters/editor-select-modal';
import { HideScreenOptions } from 'common/hide-screen-options/hide-screen-options';
@@ -19,7 +19,6 @@ import { Info } from './types/info';
interface Props {
filter?: () => void;
- history: RouteComponentProps['history'];
hideScreenOptions?: boolean;
}
@@ -28,11 +27,12 @@ const MenuItem = WpMenuItem as React.FC<
React.ComponentProps & { variant: string }
>;
-function NewsletterTypesComponent({
- history,
+export function NewsletterTypes({
filter = null,
hideScreenOptions = true,
}: Props): JSX.Element {
+ const navigate = useNavigate();
+
const [isCreating, setIsCreating] = useState(false);
const [isSelectEditorModalOpen, setIsSelectEditorModalOpen] = useState(false);
@@ -42,7 +42,7 @@ function NewsletterTypesComponent({
const setupNewsletter = (type): void => {
if (type !== undefined) {
- history.push(`/new/${type}`);
+ navigate(`/new/${type}`);
MailPoet.trackEvent('Emails > Type selected', {
'Email type': type,
});
@@ -105,7 +105,7 @@ function NewsletterTypesComponent({
},
})
.done((response) => {
- history.push(`/template/${response.data.id}`);
+ navigate(`/template/${response.data.id}`);
})
.fail((response) => {
setIsCreating(false);
@@ -290,7 +290,3 @@ function NewsletterTypesComponent({
>
);
}
-
-export const NewsletterTypes = withRouter(
- NewsletterTypesComponent as ComponentType,
-);
diff --git a/mailpoet/assets/js/src/newsletters/types/notification/notification.jsx b/mailpoet/assets/js/src/newsletters/types/notification/notification.jsx
index 30d739af42..bc21431ba8 100644
--- a/mailpoet/assets/js/src/newsletters/types/notification/notification.jsx
+++ b/mailpoet/assets/js/src/newsletters/types/notification/notification.jsx
@@ -10,7 +10,7 @@ import { Background } from 'common/background/background';
import { Button } from 'common/button/button';
import { Heading } from 'common/typography/heading/heading';
import { Grid } from 'common/grid';
-import { withRouter } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { GlobalContext } from 'context';
const field = {
@@ -76,7 +76,7 @@ class NewsletterNotificationComponent extends Component {
};
showTemplateSelection = (newsletterId) => {
- this.props.history.push(`/template/${newsletterId}`);
+ this.props.navigate(`/template/${newsletterId}`);
};
render() {
@@ -112,13 +112,12 @@ class NewsletterNotificationComponent extends Component {
NewsletterNotificationComponent.contextType = GlobalContext;
NewsletterNotificationComponent.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
+ navigate: PropTypes.func.isRequired,
};
NewsletterNotificationComponent.displayName = 'NewsletterNotification';
-export const NewsletterNotification = withRouter(
- NewsletterNotificationComponent,
-);
+export function NewsletterNotification(props) {
+ const navigate = useNavigate();
+ return ;
+}
diff --git a/mailpoet/assets/js/src/newsletters/types/standard.jsx b/mailpoet/assets/js/src/newsletters/types/standard.jsx
index 572a46512a..8cb51b2279 100644
--- a/mailpoet/assets/js/src/newsletters/types/standard.jsx
+++ b/mailpoet/assets/js/src/newsletters/types/standard.jsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { ListingHeadingStepsRoute } from 'newsletters/listings/heading-steps-route';
import { MailPoet } from 'mailpoet';
-import { withRouter } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { GlobalContext } from 'context';
import { __ } from '@wordpress/i18n';
@@ -42,7 +42,7 @@ class NewsletterStandardComponent extends Component {
}
showTemplateSelection = (newsletterId) => {
- this.props.history.push(`/template/${newsletterId}`);
+ this.props.navigate(`/template/${newsletterId}`);
};
render() {
@@ -60,11 +60,12 @@ class NewsletterStandardComponent extends Component {
NewsletterStandardComponent.contextType = GlobalContext;
NewsletterStandardComponent.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
+ navigate: PropTypes.func.isRequired,
};
NewsletterStandardComponent.displayName = 'NewsletterStandard';
-export const NewsletterTypeStandard = withRouter(NewsletterStandardComponent);
+export function NewsletterTypeStandard(props) {
+ const navigate = useNavigate();
+ return ;
+}
diff --git a/mailpoet/assets/js/src/newsletters/types/welcome/scheduling.jsx b/mailpoet/assets/js/src/newsletters/types/welcome/scheduling.jsx
index 19a63ef749..665e20fe64 100644
--- a/mailpoet/assets/js/src/newsletters/types/welcome/scheduling.jsx
+++ b/mailpoet/assets/js/src/newsletters/types/welcome/scheduling.jsx
@@ -6,7 +6,6 @@ import { Selection } from 'form/fields/selection.jsx';
import { FormFieldText } from 'form/fields/text.jsx';
import { timeDelayValues } from 'newsletters/scheduling/common.jsx';
import PropTypes from 'prop-types';
-import { withRouter } from 'react-router-dom';
const availableRoles = window.mailpoet_roles || {};
const availableSegments = _.filter(
@@ -55,7 +54,7 @@ const afterTimeTypeField = {
values: timeDelayValues,
};
-class WelcomeSchedulingComponent extends Component {
+export class WelcomeScheduling extends Component {
getCurrentValue = () => this.props.item[this.props.field.name] || {};
handleValueChange = (name, value) => {
@@ -151,15 +150,11 @@ class WelcomeSchedulingComponent extends Component {
}
}
-WelcomeSchedulingComponent.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
+WelcomeScheduling.propTypes = {
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
field: PropTypes.shape({
name: PropTypes.string,
}).isRequired,
onValueChange: PropTypes.func.isRequired,
};
-WelcomeSchedulingComponent.displayName = 'WelcomeScheduling';
-export const WelcomeScheduling = withRouter(WelcomeSchedulingComponent);
+WelcomeScheduling.displayName = 'WelcomeScheduling';
diff --git a/mailpoet/assets/js/src/segments/static/list.tsx b/mailpoet/assets/js/src/segments/static/list.tsx
index 355838ed2f..9d82c61613 100644
--- a/mailpoet/assets/js/src/segments/static/list.tsx
+++ b/mailpoet/assets/js/src/segments/static/list.tsx
@@ -1,5 +1,11 @@
import { Component, ReactNode } from 'react';
-import { Link, withRouter, RouteComponentProps } from 'react-router-dom';
+import {
+ Link,
+ useLocation,
+ useParams,
+ Location,
+ Params,
+} from 'react-router-dom';
import { MailPoet } from 'mailpoet';
import classnames from 'classnames';
import { escapeHTML, escapeAttribute } from '@wordpress/escape-html';
@@ -258,7 +264,12 @@ const itemActions = [
},
];
-class SegmentListComponent extends Component {
+type SegmentListComponentProps = {
+ params: Params;
+ location: Location;
+};
+
+class SegmentListComponent extends Component {
renderItem = (segment: Segment, actions: ReactNode) => {
const rowClasses = classnames(
'manage-column',
@@ -363,7 +374,7 @@ class SegmentListComponent extends Component {
{
}
}
-export const SegmentList = withRouter(SegmentListComponent);
+export function SegmentList(props) {
+ const params = useParams();
+ const location = useLocation();
+ return (
+
+ );
+}
diff --git a/mailpoet/assets/js/src/subscribers/heading.jsx b/mailpoet/assets/js/src/subscribers/heading.jsx
index 98ff0d5677..722501ae5c 100644
--- a/mailpoet/assets/js/src/subscribers/heading.jsx
+++ b/mailpoet/assets/js/src/subscribers/heading.jsx
@@ -1,10 +1,11 @@
-import PropTypes from 'prop-types';
-import { Link, withRouter } from 'react-router-dom';
+import { Link, useLocation } from 'react-router-dom';
import { MailPoet } from 'mailpoet';
import { TopBarWithBeamer } from 'common/top-bar/top-bar';
import { plusIcon } from 'common/button/icon/plus';
-function SubscribersHeadingComponent({ location }) {
+export function SubscribersHeading() {
+ const location = useLocation();
+
return (
);
}
-
-SubscribersHeadingComponent.propTypes = {
- location: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
-};
-
-export const SubscribersHeading = withRouter(SubscribersHeadingComponent);
diff --git a/mailpoet/assets/js/src/subscribers/import-export/import/step-data-manipulation.jsx b/mailpoet/assets/js/src/subscribers/import-export/import/step-data-manipulation.jsx
index acef9c32b9..9434fcbc86 100644
--- a/mailpoet/assets/js/src/subscribers/import-export/import/step-data-manipulation.jsx
+++ b/mailpoet/assets/js/src/subscribers/import-export/import/step-data-manipulation.jsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
-import { withRouter } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { PreviousNextStepButtons } from './previous-next-step-buttons.jsx';
import { Warnings } from './step-data-manipulation/warnings.jsx';
import { MatchTable } from './step-data-manipulation/match-table.jsx';
@@ -24,12 +24,12 @@ function getPreviousStepLink(importData, subscribersLimitForValidation) {
return 'step_input_validation';
}
-function StepDataManipulationComponent({
- history,
+export function StepDataManipulation({
subscribersLimitForValidation,
setStepDataManipulationData,
stepMethodSelectionData = undefined,
}) {
+ const navigate = useNavigate();
const [selectedSegments, setSelectedSegments] = useState([]);
const [updateExistingSubscribers, setUpdateExistingSubscribers] =
useState(true);
@@ -40,9 +40,9 @@ function StepDataManipulationComponent({
const [selectedTags, setSelectedTags] = useState([]);
useEffect(() => {
if (typeof stepMethodSelectionData === 'undefined') {
- history.replace('step_method_selection');
+ navigate('step_method_selection', { replace: true });
}
- }, [stepMethodSelectionData, history]);
+ }, [stepMethodSelectionData, navigate]);
const importSubscribers = () => {
doImport(
@@ -54,7 +54,7 @@ function StepDataManipulationComponent({
selectedTags,
(importResults) => {
setStepDataManipulationData(importResults);
- history.push('step_results');
+ navigate('step_results');
},
);
};
@@ -91,7 +91,7 @@ function StepDataManipulationComponent({
0}
onPreviousAction={() =>
- history.push(
+ navigate(
getPreviousStepLink(
stepMethodSelectionData,
subscribersLimitForValidation,
@@ -106,11 +106,7 @@ function StepDataManipulationComponent({
);
}
-StepDataManipulationComponent.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- replace: PropTypes.func.isRequired,
- }).isRequired,
+StepDataManipulation.propTypes = {
stepMethodSelectionData: PropTypes.shape({
duplicate: PropTypes.arrayOf(PropTypes.string),
header: PropTypes.arrayOf(PropTypes.string),
@@ -131,5 +127,3 @@ StepDataManipulationComponent.propTypes = {
subscribersLimitForValidation: PropTypes.number.isRequired,
setStepDataManipulationData: PropTypes.func.isRequired,
};
-
-export const StepDataManipulation = withRouter(StepDataManipulationComponent);
diff --git a/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation.tsx b/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation.tsx
index 38851bbb46..b937e218d7 100644
--- a/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation.tsx
+++ b/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation.tsx
@@ -1,5 +1,5 @@
-import { ComponentType, useCallback, useEffect, useState } from 'react';
-import { withRouter, RouteComponentProps } from 'react-router-dom';
+import { useCallback, useEffect, useState } from 'react';
+import { useNavigate } from 'react-router-dom';
import { CleanList } from 'subscribers/import-export/import/clean-list';
import { ErrorBoundary } from 'common';
@@ -17,38 +17,37 @@ type StepMethodSelectionData = {
};
type Props = {
- history: RouteComponentProps['history'];
stepMethodSelectionData?: StepMethodSelectionData;
};
-function StepInputValidationComponent({
- history,
+export function StepInputValidation({
stepMethodSelectionData = undefined,
}: Props): JSX.Element {
+ const navigate = useNavigate();
const [importSource, setImportSource] = useState(undefined);
const [lastSent, setLastSent] = useState(undefined);
useEffect(() => {
if (stepMethodSelectionData === undefined) {
- history.replace('step_method_selection');
+ navigate('step_method_selection', { replace: true });
}
- }, [stepMethodSelectionData, history]);
+ }, [stepMethodSelectionData, navigate]);
const lastSentSubmit = useCallback(
(when) => {
setLastSent(when);
if (when === 'recently') {
- history.push('step_data_manipulation');
+ navigate('step_data_manipulation');
}
},
- [history, setLastSent],
+ [navigate, setLastSent],
);
return (
<>
{importSource === undefined && (
-
+
)}
@@ -69,8 +68,4 @@ function StepInputValidationComponent({
);
}
-StepInputValidationComponent.displayName = 'StepInputValidationComponent';
-
-export const StepInputValidation = withRouter(
- StepInputValidationComponent as ComponentType,
-);
+StepInputValidation.displayName = 'StepInputValidation';
diff --git a/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation/initial-question.jsx b/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation/initial-question.jsx
index ecc52f8602..df97fba18f 100644
--- a/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation/initial-question.jsx
+++ b/mailpoet/assets/js/src/subscribers/import-export/import/step-input-validation/initial-question.jsx
@@ -1,10 +1,12 @@
import { useState } from 'react';
import PropTypes from 'prop-types';
import { MailPoet } from 'mailpoet';
+import { useNavigate } from 'react-router-dom';
import { Radio } from 'common/form/radio/radio';
import { PreviousNextStepButtons } from '../previous-next-step-buttons.jsx';
-function InitialQuestion({ onSubmit, history }) {
+function InitialQuestion({ onSubmit }) {
+ const navigate = useNavigate();
const [importSource, setImportSource] = useState(undefined);
function isFormValid() {
@@ -44,7 +46,7 @@ function InitialQuestion({ onSubmit, history }) {
history.push('step_method_selection')}
+ onPreviousAction={() => navigate('step_method_selection')}
onNextAction={() => onSubmit(importSource)}
/>
@@ -52,9 +54,6 @@ function InitialQuestion({ onSubmit, history }) {
}
InitialQuestion.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
onSubmit: PropTypes.func.isRequired,
};
InitialQuestion.displayName = 'InitialQuestion';
diff --git a/mailpoet/assets/js/src/subscribers/import-export/import/step-method-selection.jsx b/mailpoet/assets/js/src/subscribers/import-export/import/step-method-selection.jsx
index e0e48ab78c..fbb717d8cf 100644
--- a/mailpoet/assets/js/src/subscribers/import-export/import/step-method-selection.jsx
+++ b/mailpoet/assets/js/src/subscribers/import-export/import/step-method-selection.jsx
@@ -1,5 +1,5 @@
import { useState } from 'react';
-import { withRouter } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import PropTypes from 'prop-types';
import { MailPoet } from 'mailpoet';
import { ErrorBoundary } from 'common';
@@ -26,24 +26,24 @@ const getNextStepLink = (importData, subscribersLimitForValidation, method) => {
return 'step_input_validation';
};
-function StepMethodSelectionComponent({
- history,
+export function StepMethodSelection({
setStepMethodSelectionData,
subscribersLimitForValidation,
}) {
+ const navigate = useNavigate();
const [method, setMethod] = useState(undefined);
const [pastedCsvData, setPastedCsvData] = useState('');
const [file, setFile] = useState(undefined);
const finish = (parsedData) => {
setStepMethodSelectionData(parsedData);
- history.push(
+ navigate(
getNextStepLink(parsedData, subscribersLimitForValidation, method),
);
};
const previousStep = () => {
- history.push('/step_clean_list');
+ navigate('/step_clean_list');
};
const processLocal = () => {
@@ -108,12 +108,8 @@ function StepMethodSelectionComponent({
);
}
-StepMethodSelectionComponent.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- }).isRequired,
+StepMethodSelection.propTypes = {
setStepMethodSelectionData: PropTypes.func.isRequired,
subscribersLimitForValidation: PropTypes.number.isRequired,
};
-StepMethodSelectionComponent.diplayName = 'StepMethodSelection';
-export const StepMethodSelection = withRouter(StepMethodSelectionComponent);
+StepMethodSelection.diplayName = 'StepMethodSelection';
diff --git a/mailpoet/assets/js/src/subscribers/import-export/import/step-results.jsx b/mailpoet/assets/js/src/subscribers/import-export/import/step-results.jsx
index b6a676d63d..58cc1a9ff4 100644
--- a/mailpoet/assets/js/src/subscribers/import-export/import/step-results.jsx
+++ b/mailpoet/assets/js/src/subscribers/import-export/import/step-results.jsx
@@ -2,7 +2,7 @@ import { useEffect } from 'react';
import PropTypes from 'prop-types';
import { MailPoet } from 'mailpoet';
import _ from 'underscore';
-import { withRouter } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import ReactStringReplace from 'react-string-replace';
import { Button } from 'common/button/button';
@@ -102,14 +102,14 @@ NoWelcomeEmail.propTypes = {
NoWelcomeEmail.diplayName = 'NoWelcomeEmail';
-function StepResultsComponent({
- history,
+export function StepResults({
errors = [],
createdSubscribers = undefined,
updatedSubscribers = undefined,
segments = undefined,
addedToSegmentWithWelcomeNotification = undefined,
}) {
+ const navigate = useNavigate();
useEffect(() => {
if (
typeof segments === 'undefined' &&
@@ -117,13 +117,13 @@ function StepResultsComponent({
typeof createdSubscribers === 'undefined' &&
typeof updatedSubscribers === 'undefined'
) {
- history.replace('step_method_selection');
+ navigate('step_method_selection', { replace: true });
}
}, [
segments,
createdSubscribers,
errors.length,
- history,
+ navigate,
updatedSubscribers,
]);
if (errors.length) {
@@ -165,7 +165,7 @@ function StepResultsComponent({
@@ -183,11 +183,7 @@ function StepResultsComponent({
);
}
-StepResultsComponent.propTypes = {
- history: PropTypes.shape({
- push: PropTypes.func.isRequired,
- replace: PropTypes.func.isRequired,
- }).isRequired,
+StepResults.propTypes = {
errors: PropTypes.arrayOf(PropTypes.string.isRequired),
segments: PropTypes.arrayOf(PropTypes.string.isRequired),
createdSubscribers: PropTypes.number,
@@ -195,5 +191,4 @@ StepResultsComponent.propTypes = {
addedToSegmentWithWelcomeNotification: PropTypes.bool,
};
-StepResultsComponent.displayName = 'StepResultsComponent';
-export const StepResults = withRouter(StepResultsComponent);
+StepResults.displayName = 'StepResults';