diff --git a/frontend/src/components/EditAndReviewTable.jsx b/frontend/src/components/EditAndReviewTable.jsx
index a62498e..a5a354d 100644
--- a/frontend/src/components/EditAndReviewTable.jsx
+++ b/frontend/src/components/EditAndReviewTable.jsx
@@ -1,3 +1,4 @@
+import { useMemo } from "react";
import PropTypes from "prop-types";
import { Link, useNavigate } from "react-router-dom";
import classNames from "classnames";
@@ -8,19 +9,17 @@ import {
faChevronRight,
} from "@fa-kit/icons/classic/solid";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import paths from "@/router/paths";
import StatusBadge from "@/components/StatusBadge";
import NotReadyFlag from "@/components/NotReadyFlag";
function TableRow(park) {
const navigate = useNavigate();
-
- function getParkLink() {
- return `/park/${park.orcs}`;
- }
+ const parkLink = useMemo(() => paths.park(park.orcs), [park.orcs]);
// navigate to park details page
function navigateToPark() {
- navigate(getParkLink());
+ navigate(parkLink);
}
return (
@@ -31,7 +30,7 @@ function TableRow(park) {
-
+
,
},
// edit/submit dates for a season
{
- path: "/park/:parkId/edit/:seasonId",
+ path: paths.seasonEdit(":parkId", ":seasonId"),
element: ,
},
// review changes
{
- path: "/park/:parkId/edit/:seasonId/preview",
+ path: paths.seasonPreview(":parkId", ":seasonId"),
element: ,
},
// edit/submit winter fees dates
{
- path: "/park/:parkId/winter-fees/:seasonId/edit",
+ path: paths.winterFeesEdit(":parkId", ":seasonId"),
element: ,
},
// review winter fees dates
{
- path: "/park/:parkId/winter-fees/:seasonId/preview",
+ path: paths.winterFeesPreview(":parkId", ":seasonId"),
element: ,
},
],
diff --git a/frontend/src/router/pages/ParkDetails.jsx b/frontend/src/router/pages/ParkDetails.jsx
index 8226381..0e8d693 100644
--- a/frontend/src/router/pages/ParkDetails.jsx
+++ b/frontend/src/router/pages/ParkDetails.jsx
@@ -1,5 +1,6 @@
import { useEffect } from "react";
import { useParams, useSearchParams } from "react-router-dom";
+import paths from "@/router/paths";
import { useApiGet } from "@/hooks/useApi";
import { useFlashMessage } from "@/hooks/useFlashMessage";
import NavBack from "@/components/NavBack";
@@ -45,7 +46,7 @@ function ParkDetails() {
// Remove the query string so the flash message won't show again
searchParams.delete("approved");
searchParams.delete("saved");
- setSearchParams(searchParams);
+ setSearchParams(searchParams, { replace: true });
// Find the season in the park data by its ID
const allSeasons = [
@@ -100,9 +101,8 @@ function ParkDetails() {
seasons={seasons}
seasonProps={{
getDataEndpoint: (seasonId) => `/seasons/${seasonId}`,
- getEditRoutePath: (seasonId) => `/park/${parkId}/edit/${seasonId}`,
- getPreviewRoutePath: (seasonId) =>
- `/park/${parkId}/edit/${seasonId}/preview`,
+ getEditRoutePath: paths.seasonEdit,
+ getPreviewRoutePath: paths.seasonPreview,
getTitle: (season) => `${season.operatingYear} season`,
DetailsComponent: SeasonDates,
}}
@@ -117,10 +117,8 @@ function ParkDetails() {
seasons={park.winterFees}
seasonProps={{
getDataEndpoint: (seasonId) => `/winter-fees/${seasonId}`,
- getEditRoutePath: (seasonId) =>
- `/park/${parkId}/winter-fees/${seasonId}/edit`,
- getPreviewRoutePath: (seasonId) =>
- `/park/${parkId}/winter-fees/${seasonId}/preview`,
+ getEditRoutePath: paths.winterFeesEdit,
+ getPreviewRoutePath: paths.winterFeesPreview,
getTitle: (season) =>
`${season.operatingYear} – ${season.operatingYear + 1}`,
DetailsComponent: WinterFeesDates,
diff --git a/frontend/src/router/pages/PreviewChanges.jsx b/frontend/src/router/pages/PreviewChanges.jsx
index cc63cd9..85f23fe 100644
--- a/frontend/src/router/pages/PreviewChanges.jsx
+++ b/frontend/src/router/pages/PreviewChanges.jsx
@@ -1,11 +1,12 @@
import PropTypes from "prop-types";
-import { useNavigate, useParams } from "react-router-dom";
+import { useNavigate, useParams, Link } from "react-router-dom";
import { useEffect, useState } from "react";
import { useApiGet, useApiPost } from "@/hooks/useApi";
import { useNavigationGuard } from "@/hooks/useNavigationGuard";
import { useConfirmation } from "@/hooks/useConfirmation";
import { useMissingDatesConfirmation } from "@/hooks/useMissingDatesConfirmation";
import { useFlashMessage } from "@/hooks/useFlashMessage";
+import paths from "@/router/paths";
import { faPen } from "@fa-kit/icons/classic/solid";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -21,8 +22,6 @@ import ConfirmationDialog from "@/components/ConfirmationDialog";
import MissingDatesConfirmationDialog from "@/components/MissingDatesConfirmationDialog";
import FlashMessage from "@/components/FlashMessage";
-import { Link } from "react-router-dom";
-
import "./PreviewChanges.scss";
function PreviewChanges() {
@@ -65,7 +64,7 @@ function PreviewChanges() {
useNavigationGuard(hasChanges, openConfirmation);
function navigateToEdit() {
- navigate(`/park/${parkId}/edit/${seasonId}`);
+ navigate(paths.seasonEdit(parkId, seasonId));
}
function getPrevSeasonDates(feature, dateType) {
@@ -114,7 +113,7 @@ function PreviewChanges() {
readyToPublish,
});
- navigate(`/park/${parkId}?saved=${data.id}`);
+ navigate(`${paths.park(parkId)}?saved=${data.id}`);
} catch (err) {
console.error("Error saving preview", err);
@@ -215,7 +214,7 @@ function PreviewChanges() {
missingDatesConfirmation.setInputMessage("");
// Redirect back to the Park Details page on success.
// Use the "approved" query param to show a flash message.
- navigate(`/park/${parkId}?approved=${data.id}`);
+ navigate(`${paths.park(parkId)}?approved=${data.id}`);
}
} else {
await approveData({
@@ -224,7 +223,7 @@ function PreviewChanges() {
});
// Redirect back to the Park Details page on success.
// Use the "approved" query param to show a flash message.
- navigate(`/park/${parkId}?approved=${data.id}`);
+ navigate(`${paths.park(parkId)}?approved=${data.id}`);
}
} catch (err) {
console.error("Error approving preview", err);
@@ -368,7 +367,7 @@ function PreviewChanges() {
onCancel={missingDatesConfirmation.handleCancel}
onConfirm={missingDatesConfirmation.handleConfirm}
/>
-
+
Back to {data?.park.name} dates
@@ -424,7 +423,7 @@ function PreviewChanges() {
diff --git a/frontend/src/router/pages/PreviewWinterFeesChanges.jsx b/frontend/src/router/pages/PreviewWinterFeesChanges.jsx
index 60fc7e8..731be14 100644
--- a/frontend/src/router/pages/PreviewWinterFeesChanges.jsx
+++ b/frontend/src/router/pages/PreviewWinterFeesChanges.jsx
@@ -1,11 +1,12 @@
import PropTypes from "prop-types";
-import { useNavigate, useParams } from "react-router-dom";
+import { useNavigate, useParams, Link } from "react-router-dom";
import { useEffect, useState } from "react";
import { useApiGet, useApiPost } from "@/hooks/useApi";
import { useNavigationGuard } from "@/hooks/useNavigationGuard";
import { useConfirmation } from "@/hooks/useConfirmation";
import { useMissingDatesConfirmation } from "@/hooks/useMissingDatesConfirmation";
import { useFlashMessage } from "@/hooks/useFlashMessage";
+import paths from "@/router/paths";
import { faPen } from "@fa-kit/icons/classic/solid";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -21,8 +22,6 @@ import ConfirmationDialog from "@/components/ConfirmationDialog";
import MissingDatesConfirmationDialog from "@/components/MissingDatesConfirmationDialog";
import FlashMessage from "@/components/FlashMessage";
-import { Link } from "react-router-dom";
-
import "./PreviewChanges.scss";
function PreviewChanges() {
@@ -65,7 +64,7 @@ function PreviewChanges() {
useNavigationGuard(hasChanges, openConfirmation);
function navigateToEdit() {
- navigate(`/park/${parkId}/winter-fees/${seasonId}/edit`);
+ navigate(paths.winterFeesEdit(parkId, seasonId));
}
function getDates(dates) {
@@ -97,7 +96,7 @@ function PreviewChanges() {
readyToPublish,
});
- navigate(`/park/${parkId}?saved=${data.id}`);
+ navigate(`${paths.park(parkId)}?saved=${data.id}`);
} catch (err) {
console.error("Error saving preview", err);
@@ -134,7 +133,7 @@ function PreviewChanges() {
missingDatesConfirmation.setInputMessage("");
// Redirect back to the Park Details page on success.
// Use the "approved" query param to show a flash message.
- navigate(`/park/${parkId}?approved=${data.id}`);
+ navigate(`${paths.park(parkId)}?approved=${data.id}`);
}
} else {
await approveData({
@@ -143,7 +142,7 @@ function PreviewChanges() {
});
// Redirect back to the Park Details page on success.
// Use the "approved" query param to show a flash message.
- navigate(`/park/${parkId}?approved=${data.id}`);
+ navigate(`${paths.park(parkId)}?approved=${data.id}`);
}
} catch (err) {
console.error("Error approving preview", err);
@@ -257,7 +256,7 @@ function PreviewChanges() {
onConfirm={missingDatesConfirmation.handleConfirm}
/>
-
+
Back to {data?.park.name} dates
@@ -313,7 +312,7 @@ function PreviewChanges() {
diff --git a/frontend/src/router/pages/SubmitDates.jsx b/frontend/src/router/pages/SubmitDates.jsx
index ef5a8f8..0c0a5e4 100644
--- a/frontend/src/router/pages/SubmitDates.jsx
+++ b/frontend/src/router/pages/SubmitDates.jsx
@@ -32,6 +32,7 @@ import {
normalizeToUTCDate,
normalizeToLocalDate,
} from "@/lib/utils";
+import paths from "@/router/paths";
import "./SubmitDates.scss";
@@ -125,7 +126,7 @@ function SubmitDates() {
const response = await sendData(payload);
if (savingDraft) {
- navigate(`/park/${parkId}?saved=${data.id}`);
+ navigate(`${paths.park(parkId)}?saved=${data.id}`);
}
return response;
@@ -165,7 +166,7 @@ function SubmitDates() {
const submitOk = await submitChanges();
if (submitOk) {
- navigate(`/park/${parkId}/edit/${seasonId}/preview`);
+ navigate(paths.seasonPreview(parkId, seasonId));
}
} catch (err) {
console.error(err);
@@ -725,7 +726,7 @@ function SubmitDates() {
variant="error"
/>
-
+
Back to {season?.park.name} season dates
@@ -807,7 +808,7 @@ function SubmitDates() {
diff --git a/frontend/src/router/pages/SubmitWinterFeesDates.jsx b/frontend/src/router/pages/SubmitWinterFeesDates.jsx
index caa16e1..f3badb3 100644
--- a/frontend/src/router/pages/SubmitWinterFeesDates.jsx
+++ b/frontend/src/router/pages/SubmitWinterFeesDates.jsx
@@ -32,6 +32,7 @@ import {
normalizeToUTCDate,
normalizeToLocalDate,
} from "@/lib/utils";
+import paths from "@/router/paths";
import "./SubmitWinterFeesDates.scss";
@@ -455,7 +456,7 @@ export default function SubmitWinterFeesDates() {
const response = await sendData(payload);
if (savingDraft) {
- navigate(`/park/${parkId}?saved=${data.id}`);
+ navigate(`${paths.park(parkId)}?saved=${data.id}`);
}
return response;
@@ -511,7 +512,7 @@ export default function SubmitWinterFeesDates() {
const submitOk = await submitChanges();
if (submitOk) {
- navigate(`/park/${parkId}/winter-fees/${seasonId}/preview`);
+ navigate(paths.winterFeesPreview(parkId, seasonId));
}
} catch (err) {
console.error(err);
@@ -575,7 +576,7 @@ export default function SubmitWinterFeesDates() {
isOpen={isConfirmationOpen}
/>
-
+
Back to {season.park.name} season dates
@@ -649,7 +650,7 @@ export default function SubmitWinterFeesDates() {
diff --git a/frontend/src/router/paths.js b/frontend/src/router/paths.js
new file mode 100644
index 0000000..da25200
--- /dev/null
+++ b/frontend/src/router/paths.js
@@ -0,0 +1,25 @@
+// Router path resolvers for resource IDs
+
+function park(id) {
+ return `/parks/${id}`;
+}
+
+export default {
+ park,
+
+ seasonEdit(parkId, seasonId) {
+ return `${park(parkId)}/seasons/${seasonId}/edit`;
+ },
+
+ seasonPreview(parkId, seasonId) {
+ return `${park(parkId)}/seasons/${seasonId}/preview`;
+ },
+
+ winterFeesEdit(parkId, seasonId) {
+ return `${park(parkId)}/winter-fees/${seasonId}/edit`;
+ },
+
+ winterFeesPreview(parkId, seasonId) {
+ return `${park(parkId)}/winter-fees/${seasonId}/preview`;
+ },
+};
|